From 3e85a683888ef55d611353c2349e489ab7864dd2 Mon Sep 17 00:00:00 2001 From: Francis Visoiu Mistrih Date: Thu, 22 Aug 2019 16:59:00 +0000 Subject: [PATCH] [MachO][TLOF] Use hasLocalLinkage to determine if indirect symbol is local 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 --- .../CodeGen/TargetLoweringObjectFileImpl.h | 3 +- .../llvm/Target/TargetLoweringObjectFile.h | 3 +- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +- lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 12 +++--- .../AArch64/AArch64TargetObjectFile.cpp | 4 +- lib/Target/AArch64/AArch64TargetObjectFile.h | 3 +- lib/Target/X86/X86TargetObjectFile.cpp | 4 +- lib/Target/X86/X86TargetObjectFile.h | 3 +- test/MC/MachO/cstexpr-gotpcrel-32.ll | 37 ++++++++++++++++--- 9 files changed, 50 insertions(+), 21 deletions(-) diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 93f5baaac66..59f5ddbd9da 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -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; diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 3a2497bff11..d74341b23fb 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -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, diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index a3035d1e4ce..be2d72a5071 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2635,7 +2635,7 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, 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; diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index ae323606f8a..1505c9d5e15 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -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(Sym), - !IsIndirectLocal); - } + !GV->hasLocalLinkage()); const MCExpr *BSymExpr = MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); diff --git a/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/lib/Target/AArch64/AArch64TargetObjectFile.cpp index 1c3d5d0743a..54562094fcf 100644 --- a/lib/Target/AArch64/AArch64TargetObjectFile.cpp +++ b/lib/Target/AArch64/AArch64TargetObjectFile.cpp @@ -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 diff --git a/lib/Target/AArch64/AArch64TargetObjectFile.h b/lib/Target/AArch64/AArch64TargetObjectFile.h index 7ead363d42f..1cb4c028c80 100644 --- a/lib/Target/AArch64/AArch64TargetObjectFile.h +++ b/lib/Target/AArch64/AArch64TargetObjectFile.h @@ -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; diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp index 92e0779c2e7..44185957686 100644 --- a/lib/Target/X86/X86TargetObjectFile.cpp +++ b/lib/Target/X86/X86TargetObjectFile.cpp @@ -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+. diff --git a/lib/Target/X86/X86TargetObjectFile.h b/lib/Target/X86/X86TargetObjectFile.h index 13d7b4ad70d..1fd0bbf56b1 100644 --- a/lib/Target/X86/X86TargetObjectFile.h +++ b/lib/Target/X86/X86TargetObjectFile.h @@ -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; diff --git a/test/MC/MachO/cstexpr-gotpcrel-32.ll b/test/MC/MachO/cstexpr-gotpcrel-32.ll index 9b08ee7b867..3d06301b99b 100644 --- a/test/MC/MachO/cstexpr-gotpcrel-32.ll +++ b/test/MC/MachO/cstexpr-gotpcrel-32.ll @@ -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 -- 2.40.0