diff options
| author | Peter Collingbourne <pcc@google.com> | 2025-09-02 18:42:22 -0700 |
|---|---|---|
| committer | Peter Collingbourne <peter@pcc.me.uk> | 2025-09-02 18:42:22 -0700 |
| commit | bfde4eff48081b63f0c907a0c853a48234281292 (patch) | |
| tree | be72da489eb8c33d970cf9ab0e68678a0f4604af | |
| parent | 8e7385a8ea91d96f24af903d91ca7f7dd1daa24d (diff) | |
| parent | 2504d844b13403389c4c14324862f67edabca3a4 (diff) | |
[𝘀𝗽𝗿] initial versionusers/pcc/spr/elf-add-support-for-relocating-r_aarch64_funcinit64-1
Created using spr 1.3.6-beta.1
| -rw-r--r-- | lld/ELF/Arch/AArch64.cpp | 5 | ||||
| -rw-r--r-- | lld/ELF/Relocations.cpp | 21 | ||||
| -rw-r--r-- | lld/ELF/Target.h | 1 | ||||
| -rw-r--r-- | lld/test/ELF/aarch64-funcinit64-invalid.s | 18 | ||||
| -rw-r--r-- | lld/test/ELF/aarch64-funcinit64.s | 19 | ||||
| -rw-r--r-- | llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h | 1 | ||||
| -rw-r--r-- | llvm/test/MC/AArch64/data-directive-specifier.s | 3 |
11 files changed, 71 insertions, 3 deletions
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 27e77e943c19..ff13773aee5d 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -114,6 +114,7 @@ AArch64::AArch64(Ctx &ctx) : TargetInfo(ctx) { copyRel = R_AARCH64_COPY; relativeRel = R_AARCH64_RELATIVE; iRelativeRel = R_AARCH64_IRELATIVE; + iRelSymbolicRel = R_AARCH64_FUNCINIT64; gotRel = R_AARCH64_GLOB_DAT; pltRel = R_AARCH64_JUMP_SLOT; symbolicRel = R_AARCH64_ABS64; @@ -137,6 +138,7 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s, case R_AARCH64_ABS16: case R_AARCH64_ABS32: case R_AARCH64_ABS64: + case R_AARCH64_FUNCINIT64: case R_AARCH64_ADD_ABS_LO12_NC: case R_AARCH64_LDST128_ABS_LO12_NC: case R_AARCH64_LDST16_ABS_LO12_NC: @@ -267,7 +269,8 @@ bool AArch64::usesOnlyLowPageBits(RelType type) const { } RelType AArch64::getDynRel(RelType type) const { - if (type == R_AARCH64_ABS64 || type == R_AARCH64_AUTH_ABS64) + if (type == R_AARCH64_ABS64 || type == R_AARCH64_AUTH_ABS64 || + type == R_AARCH64_FUNCINIT64) return type; return R_AARCH64_NONE; } diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 6f55bac2ecf1..bf7c2fd6ce8e 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -989,8 +989,8 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type, // only the low bits are used. if (e == R_GOT || e == R_PLT) return ctx.target->usesOnlyLowPageBits(type) || !ctx.arg.isPic; - // R_AARCH64_AUTH_ABS64 requires a dynamic relocation. - if (e == RE_AARCH64_AUTH) + // R_AARCH64_AUTH_ABS64 and iRelSymbolicRel require a dynamic relocation. + if (e == RE_AARCH64_AUTH || type == ctx.target->iRelSymbolicRel) return false; // The behavior of an undefined weak reference is implementation defined. @@ -1163,6 +1163,23 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset, } return; } + if (LLVM_UNLIKELY(type == ctx.target->iRelSymbolicRel)) { + if (sym.isPreemptible) { + auto diag = Err(ctx); + diag << "relocation " << type + << " cannot be used against preemptible symbol '" << &sym << "'"; + printLocation(diag, *sec, sym, offset); + } else if (isIfunc) { + auto diag = Err(ctx); + diag << "relocation " << type + << " cannot be used against ifunc symbol '" << &sym << "'"; + printLocation(diag, *sec, sym, offset); + } else { + part.relaDyn->addReloc({ctx.target->iRelativeRel, sec, offset, false, + sym, addend, R_ABS}); + return; + } + } part.relaDyn->addSymbolReloc(rel, *sec, offset, sym, addend, type); // MIPS ABI turns using of GOT and dynamic relocations inside out. diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index e121fa1183e9..58393e7afa20 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -134,6 +134,7 @@ public: RelType relativeRel = 0; RelType iRelativeRel = 0; RelType symbolicRel = 0; + RelType iRelSymbolicRel = 0; RelType tlsDescRel = 0; RelType tlsGotRel = 0; RelType tlsModuleIndexRel = 0; diff --git a/lld/test/ELF/aarch64-funcinit64-invalid.s b/lld/test/ELF/aarch64-funcinit64-invalid.s new file mode 100644 index 000000000000..4577db742977 --- /dev/null +++ b/lld/test/ELF/aarch64-funcinit64-invalid.s @@ -0,0 +1,18 @@ +# REQUIRES: aarch64 + +# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o +# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck --check-prefix=ERR %s + +.rodata +# ERR: error: relocation R_AARCH64_FUNCINIT64 cannot be used against local symbol +.8byte func@FUNCINIT + +.data +# ERR: error: relocation R_AARCH64_FUNCINIT64 cannot be used against ifunc symbol 'ifunc' +.8byte ifunc@FUNCINIT + +.text +func: +.type ifunc, @gnu_indirect_function +ifunc: +ret diff --git a/lld/test/ELF/aarch64-funcinit64.s b/lld/test/ELF/aarch64-funcinit64.s new file mode 100644 index 000000000000..5f2b863ee884 --- /dev/null +++ b/lld/test/ELF/aarch64-funcinit64.s @@ -0,0 +1,19 @@ +# REQUIRES: aarch64 + +# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-readelf -s -r %t | FileCheck %s +# RUN: ld.lld %t.o -o %t -pie +# RUN: llvm-readelf -s -r %t | FileCheck %s +# RUN: not ld.lld %t.o -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s + +.data +# CHECK: R_AARCH64_IRELATIVE [[FOO:[0-9a-f]*]] +# ERR: relocation R_AARCH64_FUNCINIT64 cannot be used against preemptible symbol 'foo' +.8byte foo@FUNCINIT + +.text +# CHECK: {{0*}}[[FOO]] {{.*}} foo +.globl foo +foo: +ret diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def index 8dcc2926e1b5..1cfcdbf67dac 100644 --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def @@ -62,6 +62,7 @@ ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 0x139) ELF_RELOC(R_AARCH64_PLT32, 0x13a) ELF_RELOC(R_AARCH64_GOTPCREL32, 0x13b) ELF_RELOC(R_AARCH64_PATCHINST, 0x13c) +ELF_RELOC(R_AARCH64_FUNCINIT64, 0x13d) // General dynamic TLS relocations ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 0x200) ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 0x201) diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 3641e22e6f76..e40da69410ab 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -8217,6 +8217,8 @@ bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) { Spec = AArch64::S_GOTPCREL; else if (Identifier == "plt") Spec = AArch64::S_PLT; + else if (Identifier == "funcinit") + Spec = AArch64::S_FUNCINIT; } if (Spec == AArch64::S_None) return Error(Loc, "invalid relocation specifier"); diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp index a388216a9509..892b8da37eb6 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -232,6 +232,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup, } if (RefKind == AArch64::S_AUTH || RefKind == AArch64::S_AUTHADDR) return ELF::R_AARCH64_AUTH_ABS64; + if (RefKind == AArch64::S_FUNCINIT) + return ELF::R_AARCH64_FUNCINIT64; return ELF::R_AARCH64_ABS64; } case AArch64::fixup_aarch64_add_imm12: diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp index 828c5c546240..423856180443 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp @@ -40,6 +40,7 @@ const MCAsmInfo::AtSpecifier ELFAtSpecifiers[] = { {AArch64::S_GOT, "GOT"}, {AArch64::S_GOTPCREL, "GOTPCREL"}, {AArch64::S_PLT, "PLT"}, + {AArch64::S_FUNCINIT, "FUNCINIT"}, }; const MCAsmInfo::AtSpecifier MachOAtSpecifiers[] = { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h index c28e925d77e2..a6fe7367605d 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h @@ -164,6 +164,7 @@ enum { // ELF relocation specifiers in data directives: S_PLT = 0x400, S_GOTPCREL, + S_FUNCINIT, // Mach-O @ relocation specifiers: S_MACHO_GOT, diff --git a/llvm/test/MC/AArch64/data-directive-specifier.s b/llvm/test/MC/AArch64/data-directive-specifier.s index 2cb7eb3a3ca8..2d1ec4feddfa 100644 --- a/llvm/test/MC/AArch64/data-directive-specifier.s +++ b/llvm/test/MC/AArch64/data-directive-specifier.s @@ -12,6 +12,7 @@ l: # CHECK-NEXT: 0x8 R_AARCH64_PLT32 extern 0x4 # CHECK-NEXT: 0xC R_AARCH64_PLT32 g 0x8 # CHECK-NEXT: 0x10 R_AARCH64_PLT32 g 0x18 +# CHECK-NEXT: 0x14 R_AARCH64_FUNCINIT64 .text 0x0 # CHECK-NEXT: } .data .word l@plt - . @@ -21,6 +22,8 @@ l: .word g@plt - . + 8 .word g@plt - .data + 8 +.quad l@funcinit + # CHECK: Section ({{.*}}) .rela.data1 { # CHECK-NEXT: 0x0 R_AARCH64_GOTPCREL32 data1 0x0 # CHECK-NEXT: 0x4 R_AARCH64_GOTPCREL32 extern 0x4 |
