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
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;
}
/// 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,
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;
}
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
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);
}
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
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;
}
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>.
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;
ret i32 %x
}
-; Text indirect local symbols.
+; Test indirect local symbols.
; CHECK-LABEL: _localindirect
; CHECK: .long 65603
@localindirect = internal constant i32 65603
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