Skip to content

ELF: Introduce R_AARCH64_FUNCINIT64 relocation type. #133531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: users/pcc/spr/main.elf-do-not-rewrite-ifunc-relocations-to-point-to-plt-if-no-gotplt-needed
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lld/ELF/Arch/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,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;
Expand All @@ -136,6 +137,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:
Expand Down Expand Up @@ -260,7 +262,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;
}
Expand Down
23 changes: 21 additions & 2 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -992,8 +992,9 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
if (e == R_GOT || e == R_PLT)
return ctx.target->usesOnlyLowPageBits(type) || !ctx.arg.isPic;

// R_AARCH64_AUTH_ABS64 requires a dynamic relocation.
if (sym.isPreemptible || e == RE_AARCH64_AUTH)
// R_AARCH64_AUTH_ABS64 and iRelSymbolicRel require a dynamic relocation.
if (sym.isPreemptible || e == RE_AARCH64_AUTH ||
type == ctx.target->iRelSymbolicRel)
return false;
if (!ctx.arg.isPic)
return true;
Expand Down Expand Up @@ -1171,6 +1172,24 @@ 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,
DynamicReloc::AddendOnlyWithTargetVA, 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.
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class TargetInfo {
RelType relativeRel = 0;
RelType iRelativeRel = 0;
RelType symbolicRel = 0;
RelType iRelSymbolicRel = 0;
RelType tlsDescRel = 0;
RelType tlsGotRel = 0;
RelType tlsModuleIndexRel = 0;
Expand Down
18 changes: 18 additions & 0 deletions lld/test/ELF/aarch64-funcinit64-invalid.s
Original file line number Diff line number Diff line change
@@ -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: relocation R_AARCH64_FUNCINIT64 cannot be used against symbol 'func'
.8byte func@FUNCINIT

.data
# ERR: relocation R_AARCH64_FUNCINIT64 cannot be used against ifunc symbol 'ifunc'
.8byte ifunc@FUNCINIT

.text
func:
.type ifunc, @gnu_indirect_function
ifunc:
ret
19 changes: 19 additions & 0 deletions lld/test/ELF/aarch64-funcinit64.s
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ ELF_RELOC(R_AARCH64_TLS_DTPREL64, 0x405)
ELF_RELOC(R_AARCH64_TLS_TPREL64, 0x406)
ELF_RELOC(R_AARCH64_TLSDESC, 0x407)
ELF_RELOC(R_AARCH64_IRELATIVE, 0x408)
ELF_RELOC(R_AARCH64_FUNCINIT64, 0x409)
// PAuthABI static and dynamic relocations: defined in pauthabielf64,
// https://github.com/ARM-software/abi-aa
ELF_RELOC(R_AARCH64_AUTH_ABS64, 0x244)
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8203,6 +8203,8 @@ bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) {
Spec = AArch64MCExpr::VK_GOTPCREL;
else if (Identifier == "plt")
Spec = AArch64MCExpr::VK_PLT;
else if (Identifier == "funcinit")
Spec = AArch64MCExpr::VK_FUNCINIT;
}
if (Spec == AArch64MCExpr::None)
return Error(Loc, "invalid relocation specifier");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
if (RefKind == AArch64MCExpr::VK_AUTH ||
RefKind == AArch64MCExpr::VK_AUTHADDR)
return ELF::R_AARCH64_AUTH_ABS64;
if (RefKind == AArch64MCExpr::VK_FUNCINIT)
return ELF::R_AARCH64_FUNCINIT64;
return ELF::R_AARCH64_ABS64;
}
case AArch64::fixup_aarch64_add_imm12:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const MCAsmInfo::AtSpecifier ELFAtSpecifiers[] = {
{AArch64MCExpr::VK_GOT, "GOT"},
{AArch64MCExpr::VK_GOTPCREL, "GOTPCREL"},
{AArch64MCExpr::VK_PLT, "PLT"},
{AArch64MCExpr::VK_FUNCINIT, "FUNCINIT"},
};

const MCAsmInfo::AtSpecifier MachOAtSpecifiers[] = {
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class AArch64MCExpr : public MCTargetExpr {
VK_AUTHADDR = 0x00b,
VK_GOT_AUTH = 0x00c,
VK_TLSDESC_AUTH = 0x00d,
VK_FUNCINIT = 0x00e,
VK_SymLocBits = 0x00f,

// Variants specifying which part of the final address calculation is
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/AArch64/data-directive-specifier.s
Original file line number Diff line number Diff line change
Expand Up @@ -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 l 0x0
# CHECK-NEXT: }
.data
.word l@plt - .
Expand All @@ -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
Expand Down
Loading