]> granicus.if.org Git - llvm/commitdiff
[MachO][TLOF] Use hasLocalLinkage to determine if indirect symbol is local
authorFrancis Visoiu Mistrih <francisvm@yahoo.com>
Thu, 22 Aug 2019 16:59:00 +0000 (16:59 +0000)
committerFrancis Visoiu Mistrih <francisvm@yahoo.com>
Thu, 22 Aug 2019 16:59:00 +0000 (16:59 +0000)
Local symbols in the indirect symbol table contain the value
`INDIRECT_SYMBOL_LOCAL` and the corresponding __pointers entry must
contain the address of the target.

In r349060, I added support for local symbols in the indirect symbol
table, which was checking if the symbol `isDefined` && `!isExternal` to
determine if the symbol is local or not.

It turns out that `isDefined` will return false if the user of the
symbol comes before its definition, and we'll again generate .long 0
which will be the symbol at the adress 0x0.

Instead of doing that, use GlobalValue::hasLocalLinkage() to check if
the symbol is local.

Differential Revision: https://reviews.llvm.org/D66563

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369671 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
include/llvm/Target/TargetLoweringObjectFile.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/TargetLoweringObjectFileImpl.cpp
lib/Target/AArch64/AArch64TargetObjectFile.cpp
lib/Target/AArch64/AArch64TargetObjectFile.h
lib/Target/X86/X86TargetObjectFile.cpp
lib/Target/X86/X86TargetObjectFile.h
test/MC/MachO/cstexpr-gotpcrel-32.ll

index 93f5baaac66059fdf57a09917db2758c62af100f..59f5ddbd9dac338a422b5f1dc022cbae6751ac13 100644 (file)
@@ -127,7 +127,8 @@ public:
                                     MachineModuleInfo *MMI) const override;
 
   /// Get MachO PC relative GOT entry relocation
-  const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym,
+  const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
+                                          const MCSymbol *Sym,
                                           const MCValue &MV, int64_t Offset,
                                           MachineModuleInfo *MMI,
                                           MCStreamer &Streamer) const override;
index 3a2497bff11e84708684047f5fa03abf88f4bbee..d74341b23fb196c83cfb959f21dc324ab5a992be 100644 (file)
@@ -191,7 +191,8 @@ public:
   }
 
   /// Get the target specific PC relative GOT entry relocation
-  virtual const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym,
+  virtual const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
+                                                  const MCSymbol *Sym,
                                                   const MCValue &MV,
                                                   int64_t Offset,
                                                   MachineModuleInfo *MMI,
index a3035d1e4cea4cc8e51723d26ccf4c316c2b2a95..be2d72a50712b8fd89afd52ce9b5fd2154db65b1 100644 (file)
@@ -2635,7 +2635,7 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME,
   const GlobalValue *FinalGV = dyn_cast<GlobalValue>(GV->getOperand(0));
   const MCSymbol *FinalSym = AP.getSymbol(FinalGV);
   *ME = AP.getObjFileLowering().getIndirectSymViaGOTPCRel(
-      FinalSym, MV, Offset, AP.MMI, *AP.OutStreamer);
+      FinalGV, FinalSym, MV, Offset, AP.MMI, *AP.OutStreamer);
 
   // Update GOT equivalent usage information
   --NumUses;
index ae323606f8a4287d573923b892a87a80862aa126..1505c9d5e15baa6bda265c3476a3859c4524d4ce 100644 (file)
@@ -1108,8 +1108,8 @@ MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol(
 }
 
 const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel(
-    const MCSymbol *Sym, const MCValue &MV, int64_t Offset,
-    MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+    const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
+    int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
   // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation
   // as 64-bit do, we replace the GOT equivalent by accessing the final symbol
   // through a non_lazy_ptr stub instead. One advantage is that it allows the
@@ -1166,12 +1166,10 @@ const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel(
   MCSymbol *Stub = Ctx.getOrCreateSymbol(Name);
 
   MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub);
-  if (!StubSym.getPointer()) {
-    bool IsIndirectLocal = Sym->isDefined() && !Sym->isExternal();
-    // With the assumption that IsIndirectLocal == GV->hasLocalLinkage().
+
+  if (!StubSym.getPointer())
     StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym),
-                                                 !IsIndirectLocal);
-  }
+                                                 !GV->hasLocalLinkage());
 
   const MCExpr *BSymExpr =
     MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx);
index 1c3d5d0743ad0de34099dedb0a60cab59d56a78c..54562094fcf56b038c24149e3b65c7ac49df93fd 100644 (file)
@@ -59,8 +59,8 @@ MCSymbol *AArch64_MachoTargetObjectFile::getCFIPersonalitySymbol(
 }
 
 const MCExpr *AArch64_MachoTargetObjectFile::getIndirectSymViaGOTPCRel(
-    const MCSymbol *Sym, const MCValue &MV, int64_t Offset,
-    MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+    const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
+    int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
   assert((Offset+MV.getConstant() == 0) &&
          "Arch64 does not support GOT PC rel with extra offset");
   // On ARM64 Darwin, we can reference symbols with foo@GOT-., which
index 7ead363d42fe72c618517a33f87d355e4171d7cf..1cb4c028c80d234a7be16d31d4937912d3223b7c 100644 (file)
@@ -35,7 +35,8 @@ public:
                                     const TargetMachine &TM,
                                     MachineModuleInfo *MMI) const override;
 
-  const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym,
+  const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
+                                          const MCSymbol *Sym,
                                           const MCValue &MV, int64_t Offset,
                                           MachineModuleInfo *MMI,
                                           MCStreamer &Streamer) const override;
index 92e0779c2e74ad7bb049e7b336830473ecef9d6b..44185957686b6c70338dbc3da0ff20d003ea8668 100644 (file)
@@ -47,8 +47,8 @@ MCSymbol *X86_64MachoTargetObjectFile::getCFIPersonalitySymbol(
 }
 
 const MCExpr *X86_64MachoTargetObjectFile::getIndirectSymViaGOTPCRel(
-    const MCSymbol *Sym, const MCValue &MV, int64_t Offset,
-    MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+    const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
+    int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
   // On Darwin/X86-64, we need to use foo@GOTPCREL+4 to access the got entry
   // from a data section. In case there's an additional offset, then use
   // foo@GOTPCREL+4+<offset>.
index 13d7b4ad70d64baf408637a9d892db1f75ac3207..1fd0bbf56b19ab1f41a4d6ff78286ccdd8cfb0f0 100644 (file)
@@ -30,7 +30,8 @@ namespace llvm {
                                       const TargetMachine &TM,
                                       MachineModuleInfo *MMI) const override;
 
-    const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym,
+    const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
+                                            const MCSymbol *Sym,
                                             const MCValue &MV, int64_t Offset,
                                             MachineModuleInfo *MMI,
                                             MCStreamer &Streamer) const override;
index 9b08ee7b867768bc9d4863404d5be5d1ff3a221c..3d06301b99b1de011c35280f719d4d706b225c56 100644 (file)
@@ -73,7 +73,7 @@ define i32 @t0(i32 %a) {
   ret i32 %x
 }
 
-; Text indirect local symbols.
+; Test indirect local symbols.
 ; CHECK-LABEL: _localindirect
 ; CHECK: .long 65603
 @localindirect = internal constant i32  65603
@@ -85,11 +85,38 @@ define i32 @t0(i32 %a) {
   i32 sub (i32 ptrtoint (i32** @got.localindirect to i32),
            i32 ptrtoint (i32* @localindirectuser to i32))
 
+; Test internal indirect local symbols where the user doesn't see the
+; definition of the other symbols yet.
+
+; We used to check if the symbol is defined and not external to guess if it has
+; local linkage, but that doesn't work if the symbol is defined after. The code
+; should check if the GlobalValue itself has local linkage.
+
+; CHECK-LABEL: _undeflocalindirectuser:
+; CHECK: .long L_undeflocalindirect$non_lazy_ptr-_undeflocalindirectuser
+@undeflocalindirectuser = internal constant
+  i32 sub (i32 ptrtoint (i32** @got.undeflocalindirect to i32),
+           i32 ptrtoint (i32* @undeflocalindirectuser to i32)),
+  section "__TEXT,__const"
+
+; CHECK-LABEL: _undeflocalindirect:
+; CHECK: .long 65603
+@undeflocalindirect = internal constant i32  65603
+@got.undeflocalindirect = private unnamed_addr constant i32* @undeflocalindirect
+
+; CHECK-LABEL: .section __IMPORT,__pointers
+
+; CHECK-LABEL: L_localfoo$non_lazy_ptr:
+; CHECK: .indirect_symbol _localfoo
+; CHECK-NOT: .long _localfoo
+; CHECK-NEXT: .long 0
+
 ; CHECK-LABEL: L_localindirect$non_lazy_ptr:
 ; CHECK: .indirect_symbol _localindirect
 ; CHECK-NOT: .long 0
 ; CHECK-NEXT: .long _localindirect
-define i8* @testRelativeIndirectSymbol() {
-  %1 = bitcast i32* @localindirectuser to i8*
-  ret i8* %1
-}
+
+; CHECK-LABEL: L_undeflocalindirect$non_lazy_ptr:
+; CHECK: .indirect_symbol _undeflocalindirect
+; CHECK-NOT: .long 0
+; CHECK-NEXT: .long _undeflocalindirect