diff --git a/llvm/include/llvm/MC/MCELFObjectWriter.h b/llvm/include/llvm/MC/MCELFObjectWriter.h --- a/llvm/include/llvm/MC/MCELFObjectWriter.h +++ b/llvm/include/llvm/MC/MCELFObjectWriter.h @@ -88,7 +88,7 @@ virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const = 0; - virtual bool needsRelocateWithSymbol(const MCSymbol &Sym, + virtual bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const; virtual void sortRelocs(const MCAssembler &Asm, diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -227,8 +227,7 @@ bool hasRelocationAddend() const; - bool shouldRelocateWithSymbol(const MCAssembler &Asm, - const MCSymbolRefExpr *RefA, + bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCValue &Val, const MCSymbolELF *Sym, uint64_t C, unsigned Type) const; @@ -1297,10 +1296,11 @@ // to use a relocation with a section if that is possible. Using the section // allows us to omit some local symbols from the symbol table. bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, - const MCSymbolRefExpr *RefA, + const MCValue &Val, const MCSymbolELF *Sym, uint64_t C, unsigned Type) const { + const MCSymbolRefExpr *RefA = Val.getSymA(); // A PCRel relocation to an absolute value has no symbol (or section). We // represent that with a relocation to a null section. if (!RefA) @@ -1419,7 +1419,7 @@ if (Asm.isThumbFunc(Sym)) return true; - if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type)) + if (TargetObjectWriter->needsRelocateWithSymbol(Val, *Sym, Type)) return true; return false; } @@ -1484,7 +1484,7 @@ const auto *Parent = cast(Fragment->getParent()); // Emiting relocation with sybmol for CG Profile to help with --cg-profile. bool RelocateWithSymbol = - shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type) || + shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) || (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE); uint64_t Addend = 0; diff --git a/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/llvm/lib/MC/MCELFObjectTargetWriter.cpp --- a/llvm/lib/MC/MCELFObjectTargetWriter.cpp +++ b/llvm/lib/MC/MCELFObjectTargetWriter.cpp @@ -17,7 +17,8 @@ : OSABI(OSABI_), ABIVersion(ABIVersion_), EMachine(EMachine_), HasRelocationAddend(HasRelocationAddend_), Is64Bit(Is64Bit_) {} -bool MCELFObjectTargetWriter::needsRelocateWithSymbol(const MCSymbol &Sym, +bool MCELFObjectTargetWriter::needsRelocateWithSymbol(const MCValue &, + const MCSymbol &, unsigned Type) const { return false; } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -39,6 +39,8 @@ protected: unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, + unsigned Type) const override; bool IsILP32; }; @@ -459,6 +461,12 @@ llvm_unreachable("Unimplemented fixup -> relocation"); } +bool AArch64ELFObjectWriter::needsRelocateWithSymbol(const MCValue &Val, + const MCSymbol &, + unsigned) const { + return (Val.getRefKind() & AArch64MCExpr::VK_GOT) == AArch64MCExpr::VK_GOT; +} + MCSectionELF * AArch64ELFObjectWriter::getMemtagRelocsSection(MCContext &Ctx) const { return Ctx.getELFSection(".memtag.globals.static", diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -38,7 +38,7 @@ unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(const MCSymbol &Sym, + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const override; void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override; @@ -51,7 +51,8 @@ ELF::EM_ARM, /*HasRelocationAddend*/ false) {} -bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, +bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCValue &, + const MCSymbol &, unsigned Type) const { // FIXME: This is extremely conservative. This really needs to use an // explicit list with a clear explanation for why each realocation needs to diff --git a/llvm/lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp b/llvm/lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp --- a/llvm/lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp +++ b/llvm/lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp @@ -26,7 +26,7 @@ protected: unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(const MCSymbol &SD, + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const override; }; @@ -72,7 +72,8 @@ return Type; } -bool LanaiELFObjectWriter::needsRelocateWithSymbol(const MCSymbol & /*SD*/, +bool LanaiELFObjectWriter::needsRelocateWithSymbol(const MCValue &, + const MCSymbol &, unsigned Type) const { switch (Type) { case ELF::R_LANAI_21: diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -62,7 +62,7 @@ unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(const MCSymbol &Sym, + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const override; void sortRelocs(const MCAssembler &Asm, std::vector &Relocs) override; @@ -505,14 +505,15 @@ Relocs[CopyTo++] = R.R; } -bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, +bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCValue &Val, + const MCSymbol &Sym, unsigned Type) const { // If it's a compound relocation for N64 then we need the relocation if any // sub-relocation needs it. if (!isUInt<8>(Type)) - return needsRelocateWithSymbol(Sym, Type & 0xff) || - needsRelocateWithSymbol(Sym, (Type >> 8) & 0xff) || - needsRelocateWithSymbol(Sym, (Type >> 16) & 0xff); + return needsRelocateWithSymbol(Val, Sym, Type & 0xff) || + needsRelocateWithSymbol(Val, Sym, (Type >> 8) & 0xff) || + needsRelocateWithSymbol(Val, Sym, (Type >> 16) & 0xff); switch (Type) { default: diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -28,7 +28,7 @@ unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(const MCSymbol &Sym, + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const override; }; } @@ -472,7 +472,8 @@ return Type; } -bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, +bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCValue &, + const MCSymbol &Sym, unsigned Type) const { switch (Type) { default: diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -27,7 +27,7 @@ // Return true if the given relocation must be with a symbol rather than // section plus offset. - bool needsRelocateWithSymbol(const MCSymbol &Sym, + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const override { // TODO: this is very conservative, update once RISC-V psABI requirements // are clarified. diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -32,9 +32,8 @@ unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(const MCSymbol &Sym, + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const override; - }; } @@ -124,8 +123,9 @@ return ELF::R_SPARC_NONE; } -bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, - unsigned Type) const { +bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCValue &, + const MCSymbol &, + unsigned Type) const { switch (Type) { default: return false; diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp --- a/llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp +++ b/llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp @@ -31,7 +31,7 @@ unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(const MCSymbol &Sym, + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const override; }; } // namespace @@ -134,7 +134,8 @@ return ELF::R_VE_NONE; } -bool VEELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, +bool VEELFObjectWriter::needsRelocateWithSymbol(const MCValue &, + const MCSymbol &, unsigned Type) const { switch (Type) { default: diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaELFObjectWriter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaELFObjectWriter.cpp --- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaELFObjectWriter.cpp +++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaELFObjectWriter.cpp @@ -32,7 +32,7 @@ protected: unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(const MCSymbol &Sym, + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, unsigned Type) const override; }; } // namespace @@ -60,7 +60,8 @@ return std::make_unique(OSABI); } -bool XtensaObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, +bool XtensaObjectWriter::needsRelocateWithSymbol(const MCValue &, + const MCSymbol &, unsigned Type) const { return false; } diff --git a/llvm/test/MC/AArch64/arm64-elf-relocs.s b/llvm/test/MC/AArch64/arm64-elf-relocs.s --- a/llvm/test/MC/AArch64/arm64-elf-relocs.s +++ b/llvm/test/MC/AArch64/arm64-elf-relocs.s @@ -316,3 +316,24 @@ // CHECK: ldr d22, :got:sym // CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym // CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym + +// GOT relocations referencing local symbols are not converted to reference +// STT_SECTION symbols. https://github.com/llvm/llvm-project/issues/63418 + ldr x0, [x0, :got_lo12:local0] + ldr x1, [x1, :got_lo12:local1] + ldr x2, [x2, :gotpage_lo15:local2] + adrp x3, :got:local3 +// CHECK: ldr x0, [x0, :got_lo12:local0] +// CHECK-NEXT: ldr x1, [x1, :got_lo12:local1] +// CHECK-NEXT: ldr x2, [x2, :gotpage_lo15:local2] +// CHECK-NEXT: adrp x3, :got:local3 +// CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC local0{{$}} +// CHECK-OBJ-LP64-NEXT: R_AARCH64_LD64_GOT_LO12_NC local1{{$}} +// CHECK-OBJ-LP64-NEXT: R_AARCH64_LD64_GOTPAGE_LO15 local2{{$}} +// CHECK-OBJ-LP64-NEXT: R_AARCH64_ADR_GOT_PAGE local3{{$}} + +.data +local0: .long 0 +local1: .long 0 +local2: .long 0 +local3: .long 0