Index: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1100,6 +1100,22 @@ // .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(); MCContext &Ctx = getContext(); @@ -1119,9 +1135,12 @@ MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); - if (!StubSym.getPointer()) - StubSym = MachineModuleInfoImpl:: - StubValueTy(const_cast(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(Sym), + !IsIndirectLocal); + } const MCExpr *BSymExpr = MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); Index: llvm/trunk/test/MC/MachO/cstexpr-gotpcrel-32.ll =================================================================== --- llvm/trunk/test/MC/MachO/cstexpr-gotpcrel-32.ll +++ llvm/trunk/test/MC/MachO/cstexpr-gotpcrel-32.ll @@ -72,3 +72,24 @@ 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 +}