[MachO][TLOF] Add support for local symbols in the indirect symbol table
authorFrancis Visoiu Mistrih <francisvm@yahoo.com>
Thu, 13 Dec 2018 17:23:30 +0000 (17:23 +0000)
committerFrancis Visoiu Mistrih <francisvm@yahoo.com>
Thu, 13 Dec 2018 17:23:30 +0000 (17:23 +0000)
On 32-bit archs, before, we would assume that an indirect symbol will
never have local linkage. This can lead to miscompiles where the
symbol's value would be 0 and the linker would use that value, because
the indirect symbol table would contain the value
`INDIRECT_SYMBOL_LOCAL` for that specific symbol.

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

llvm-svn: 349060

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/test/MC/MachO/cstexpr-gotpcrel-32.ll

index 5f4421f..394281e 100644 (file)
@@ -1100,6 +1100,22 @@ const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel(
   //       .indirect_symbol        _extfoo
   //       .long   0
   //
+  // The indirect symbol table (and sections of non_lazy_symbol_pointers type)
+  // may point to both local (same translation unit) and global (other
+  // translation units) symbols. Example:
+  //
+  // .section __DATA,__pointers,non_lazy_symbol_pointers
+  // L1:
+  //    .indirect_symbol _myGlobal
+  //    .long 0
+  // L2:
+  //    .indirect_symbol _myLocal
+  //    .long _myLocal
+  //
+  // If the symbol is local, instead of the symbol's index, the assembler
+  // places the constant INDIRECT_SYMBOL_LOCAL into the indirect symbol table.
+  // Then the linker will notice the constant in the table and will look at the
+  // content of the symbol.
   MachineModuleInfoMachO &MachOMMI =
     MMI->getObjFileInfo<MachineModuleInfoMachO>();
   MCContext &Ctx = getContext();
@@ -1119,9 +1135,12 @@ const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel(
   MCSymbol *Stub = Ctx.getOrCreateSymbol(Name);
 
   MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub);
-  if (!StubSym.getPointer())
-    StubSym = MachineModuleInfoImpl::
-      StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */);
+  if (!StubSym.getPointer()) {
+    bool IsIndirectLocal = Sym->isDefined() && !Sym->isExternal();
+    // With the assumption that IsIndirectLocal == GV->hasLocalLinkage().
+    StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym),
+                                                 !IsIndirectLocal);
+  }
 
   const MCExpr *BSymExpr =
     MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx);
index 8e00b4a..9b08ee7 100644 (file)
@@ -72,3 +72,24 @@ define i32 @t0(i32 %a) {
                     i32 ptrtoint (i32 (i32)* @t0 to i32)), %a
   ret i32 %x
 }
+
+; Text indirect local symbols.
+; CHECK-LABEL: _localindirect
+; CHECK: .long 65603
+@localindirect = internal constant i32  65603
+@got.localindirect = private unnamed_addr constant i32* @localindirect
+
+; CHECK-LABEL: _localindirectuser:
+; CHECK: .long   L_localindirect$non_lazy_ptr-_localindirectuser
+@localindirectuser = internal constant
+  i32 sub (i32 ptrtoint (i32** @got.localindirect to i32),
+           i32 ptrtoint (i32* @localindirectuser to i32))
+
+; 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
+}