Index: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -127,7 +127,8 @@ 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: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h =================================================================== --- llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h +++ llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h @@ -191,7 +191,8 @@ } /// 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: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2635,7 +2635,7 @@ const GlobalValue *FinalGV = dyn_cast(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: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1108,8 +1108,8 @@ } 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 @@ 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(Sym), - !IsIndirectLocal); - } + !GV->hasLocalLinkage()); const MCExpr *BSymExpr = MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); Index: llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h +++ llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h @@ -35,7 +35,8 @@ 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: llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp @@ -59,8 +59,8 @@ } 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: llvm/trunk/lib/Target/X86/X86TargetObjectFile.h =================================================================== --- llvm/trunk/lib/Target/X86/X86TargetObjectFile.h +++ llvm/trunk/lib/Target/X86/X86TargetObjectFile.h @@ -30,7 +30,8 @@ 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: llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp +++ llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp @@ -47,8 +47,8 @@ } 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+. 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 @@ -73,7 +73,7 @@ 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 @@ 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