From bed89970c3df5e755820708580e405f65ddaa1ba Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 27 Feb 2026 21:37:59 -0800 Subject: [PATCH] AArch64: Replace @plt/%gotpcrel in data directives with %pltpcrel %gotpcrel (#155776) Similar to #132569 for RISC-V, replace the unofficial `@plt` and `@gotpcrel` relocation specifiers, currently only used by clang -fexperimental-relative-c++-abi-vtables, with %pltpcrel %gotpcrel. The syntax is not used in humand-written assembly code, and is not supported by GNU assembler. Also replace the recent `@funcinit` with `%funcinit(x)`. --- ...ip-non-vfuncptr-reloc-in-relative-vtable.s | 2 +- lld/test/ELF/aarch64-branch-to-branch.s | 6 +- lld/test/ELF/aarch64-feature-bti.s | 2 +- lld/test/ELF/aarch64-funcinit64-invalid.s | 4 +- lld/test/ELF/aarch64-funcinit64.s | 2 +- .../ELF/aarch64-range-thunk-extension-plt32.s | 2 +- lld/test/ELF/aarch64-reloc-gotpcrel32.s | 10 +-- lld/test/ELF/aarch64-reloc-plt32.s | 6 +- lld/test/ELF/aarch64-undefined-weak.s | 2 +- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 5 +- .../AArch64/AsmParser/AArch64AsmParser.cpp | 32 ++++++-- .../MCTargetDesc/AArch64ELFObjectWriter.cpp | 27 +++++-- .../AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp | 19 ++++- .../AArch64/MCTargetDesc/AArch64MCAsmInfo.h | 2 + .../test/CodeGen/AArch64/ptrauth-irelative.ll | 18 ++--- .../MC/AArch64/data-directive-specifier.s | 80 ++++++++++--------- llvm/test/MC/AArch64/elf-reloc-ptrauth.s | 2 +- 17 files changed, 141 insertions(+), 80 deletions(-) diff --git a/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.s b/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.s index 41a00313427d..6f293025d0f8 100644 --- a/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.s +++ b/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.s @@ -31,5 +31,5 @@ _fake_rtti_data: _ZTV3gooE: .word 0 .word _fake_rtti_data-_ZTV3gooE-8 - .word foo@PLT-_ZTV3gooE-8 + .word %pltpcrel(foo) .size _ZTV3gooE, 12 diff --git a/lld/test/ELF/aarch64-branch-to-branch.s b/lld/test/ELF/aarch64-branch-to-branch.s index c970fe308579..f6c96b2e10e5 100644 --- a/lld/test/ELF/aarch64-branch-to-branch.s +++ b/lld/test/ELF/aarch64-branch-to-branch.s @@ -35,14 +35,14 @@ vtable: # B2B-NEXT: [[VF:[0-9a-f]{8}]] # B2B-RELOC-NEXT: R_AARCH64_PLT32 f3 # NOB2B-RELOC-NEXT: R_AARCH64_PLT32 f1 -.4byte f1@PLT - vtable +.4byte %pltpcrel(f1) # B2B-SAME: [[VF]] # B2B-RELOC-NEXT: R_AARCH64_PLT32 f3+0x4 # NOB2B-RELOC-NEXT: R_AARCH64_PLT32 f2+0x4 -.4byte f2@PLT - vtable +.4byte %pltpcrel(f2+4) # B2B-SAME: [[VF]] # RELOC-NEXT: R_AARCH64_PLT32 f3+0x8 -.4byte f3@PLT - vtable +.4byte %pltpcrel(f3+8) .section .text._start,"ax" .globl _start diff --git a/lld/test/ELF/aarch64-feature-bti.s b/lld/test/ELF/aarch64-feature-bti.s index 8d7c1f2826c1..a1f46da156dc 100644 --- a/lld/test/ELF/aarch64-feature-bti.s +++ b/lld/test/ELF/aarch64-feature-bti.s @@ -290,5 +290,5 @@ func1: .ifdef RELVTABLE_PLT // R_AARCH64_PLT32 -.word funcRelVtable@PLT - . +.word %pltpcrel(funcRelVtable) .endif diff --git a/lld/test/ELF/aarch64-funcinit64-invalid.s b/lld/test/ELF/aarch64-funcinit64-invalid.s index 4577db742977..c0fc398cb85a 100644 --- a/lld/test/ELF/aarch64-funcinit64-invalid.s +++ b/lld/test/ELF/aarch64-funcinit64-invalid.s @@ -5,11 +5,11 @@ .rodata # ERR: error: relocation R_AARCH64_FUNCINIT64 cannot be used against local symbol -.8byte func@FUNCINIT +.8byte %funcinit(func) .data # ERR: error: relocation R_AARCH64_FUNCINIT64 cannot be used against ifunc symbol 'ifunc' -.8byte ifunc@FUNCINIT +.8byte %funcinit(ifunc) .text func: diff --git a/lld/test/ELF/aarch64-funcinit64.s b/lld/test/ELF/aarch64-funcinit64.s index 5f2b863ee884..1be30e2de3d5 100644 --- a/lld/test/ELF/aarch64-funcinit64.s +++ b/lld/test/ELF/aarch64-funcinit64.s @@ -10,7 +10,7 @@ .data # CHECK: R_AARCH64_IRELATIVE [[FOO:[0-9a-f]*]] # ERR: relocation R_AARCH64_FUNCINIT64 cannot be used against preemptible symbol 'foo' -.8byte foo@FUNCINIT +.8byte %funcinit(foo) .text # CHECK: {{0*}}[[FOO]] {{.*}} foo diff --git a/lld/test/ELF/aarch64-range-thunk-extension-plt32.s b/lld/test/ELF/aarch64-range-thunk-extension-plt32.s index 9ebf7f5c6952..86b6154d9af2 100644 --- a/lld/test/ELF/aarch64-range-thunk-extension-plt32.s +++ b/lld/test/ELF/aarch64-range-thunk-extension-plt32.s @@ -25,7 +25,7 @@ .global _start .type _start, %function _start: - .word callee@PLT - . + .word %pltpcrel(callee) .section .text.2, "ax", %progbits .global callee diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s index 4d007776a86a..35dfe756f4b2 100644 --- a/lld/test/ELF/aarch64-reloc-gotpcrel32.s +++ b/lld/test/ELF/aarch64-reloc-gotpcrel32.s @@ -17,11 +17,11 @@ _start: // PC = 0x303a0 // bar@GOTPCREL-4 = 0x20390 (got entry for `bar`) - 0x303a8 (.) - 4 = 0xe4fffeff // CHECK: Contents of section .data: // CHECK-NEXT: {{.*}} f0fffeff f0fffeff e4fffeff - .word bar@GOTPCREL - .word bar@GOTPCREL+4 - .word bar@GOTPCREL-4 + .word %gotpcrel(bar) + .word %gotpcrel(bar+4) + .word %gotpcrel(bar-4) // WARN: relocation R_AARCH64_GOTPCREL32 out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz' // WARN: relocation R_AARCH64_GOTPCREL32 out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz' - .word baz@GOTPCREL+0xffffffff - .word baz@GOTPCREL-0xffffffff + .word %gotpcrel(baz+0xffffffff) + .word %gotpcrel(baz-0xffffffff) diff --git a/lld/test/ELF/aarch64-reloc-plt32.s b/lld/test/ELF/aarch64-reloc-plt32.s index 8a3b989a909b..cd442e76fcf3 100644 --- a/lld/test/ELF/aarch64-reloc-plt32.s +++ b/lld/test/ELF/aarch64-reloc-plt32.s @@ -32,6 +32,6 @@ .globl _start _start: .data - .word foo@PLT - . + 2149589079 - .word foo@PLT - . - 2145378212 - .word foo@PLT - . + .word %pltpcrel(foo + 2149589079) + .word %pltpcrel(foo - 2145378212) + .word %pltpcrel(foo) diff --git a/lld/test/ELF/aarch64-undefined-weak.s b/lld/test/ELF/aarch64-undefined-weak.s index 52edc8776773..b7d98c0fde46 100644 --- a/lld/test/ELF/aarch64-undefined-weak.s +++ b/lld/test/ELF/aarch64-undefined-weak.s @@ -37,7 +37,7 @@ _start: // R_AARCH64_PREL16 .hword target - . // R_AARCH64_PLT32 - .word target@PLT - . + .word %pltpcrel(target) bl_undefweak2: bl undefweak2 diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 2b8db27599d3..87fbe9be14a2 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -2671,8 +2671,9 @@ const MCExpr *AArch64AsmPrinter::emitPAuthRelocationAsIRelative( MCInstBuilder(AArch64::RET).addReg(AArch64::LR), *STI); OutStreamer->popSection(); - return MCSymbolRefExpr::create(IRelativeSym, AArch64::S_FUNCINIT, - OutStreamer->getContext()); + return MCSpecifierExpr::create( + MCSymbolRefExpr::create(IRelativeSym, OutStreamer->getContext()), + AArch64::S_FUNCINIT, OutStreamer->getContext()); } const MCExpr * diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 85778c1f1bee..590da8f93873 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -182,6 +182,7 @@ private: bool showMatchError(SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo, OperandVector &Operands); + bool parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E); bool parseDataExpr(const MCExpr *&Res) override; bool parseAuthExpr(const MCExpr *&Res, SMLoc &EndLoc); @@ -8452,8 +8453,31 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) { return false; } +bool AArch64AsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) { + SMLoc Loc = getLoc(); + if (getLexer().getKind() != AsmToken::Identifier) + return TokError("expected '%' relocation specifier"); + StringRef Identifier = getParser().getTok().getIdentifier(); + auto Spec = AArch64::parsePercentSpecifierName(Identifier); + if (!Spec) + return TokError("invalid relocation specifier"); + + getParser().Lex(); // Eat the identifier + if (parseToken(AsmToken::LParen, "expected '('")) + return true; + + const MCExpr *SubExpr; + if (getParser().parseParenExpression(SubExpr, E)) + return true; + + Res = MCSpecifierExpr::create(SubExpr, Spec, getContext(), Loc); + return false; +} + bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) { SMLoc EndLoc; + if (parseOptionalToken(AsmToken::Percent)) + return parseExprWithSpecifier(Res, EndLoc); if (getParser().parseExpression(Res)) return true; @@ -8473,14 +8497,6 @@ bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) { if (STI->getTargetTriple().isOSBinFormatMachO()) { if (Identifier == "got") Spec = AArch64::S_MACHO_GOT; - } else { - // Unofficial, experimental syntax that will be changed. - if (Identifier == "gotpcrel") - 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 892b8da37eb6..e33196d4c014 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -104,6 +104,20 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup, break; } + switch (RefKind) { + case AArch64::S_GOTPCREL: + case AArch64::S_PLT: + if (Kind == FK_Data_4) + break; + // Only R_AARCH64_PLT32/R_AARCH64_GOTPCREL32 defined at present, but can + // be extended to other sizes if additional relocations are defined. + reportError(Fixup.getLoc(), AArch64::getSpecifierName(RefKind) + + " can only be used in a .word directive"); + return ELF::R_AARCH64_NONE; + default: + break; + } + // Extract the relocation type from the fixup kind, after applying STT_TLS as // needed. if (mc::isRelocation(Fixup.getKind())) @@ -117,8 +131,7 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup, case FK_Data_2: return R_CLS(PREL16); case FK_Data_4: { - return Target.getSpecifier() == AArch64::S_PLT ? R_CLS(PLT32) - : R_CLS(PREL32); + return R_CLS(PREL32); } case FK_Data_8: if (IsILP32) { @@ -220,9 +233,13 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup, case FK_Data_2: return R_CLS(ABS16); case FK_Data_4: - return (!IsILP32 && Target.getSpecifier() == AArch64::S_GOTPCREL) - ? ELF::R_AARCH64_GOTPCREL32 - : R_CLS(ABS32); + if (!IsILP32) { + if (Target.getSpecifier() == AArch64::S_GOTPCREL) + return ELF::R_AARCH64_GOTPCREL32; + if (Target.getSpecifier() == AArch64::S_PLT) + return ELF::R_AARCH64_PLT32; + } + return R_CLS(ABS32); case FK_Data_8: { if (IsILP32) { reportError( diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp index c6a4723e00b7..9c043655ab1a 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp @@ -114,12 +114,24 @@ StringRef AArch64::getSpecifierName(AArch64::Specifier S) { case AArch64::S_GOT_AUTH: return ":got_auth:"; case AArch64::S_GOT_AUTH_PAGE: return ":got_auth:"; case AArch64::S_GOT_AUTH_LO12: return ":got_auth_lo12:"; + + case AArch64::S_GOTPCREL: return "%gotpcrel"; + case AArch64::S_PLT: return "%pltpcrel"; + case AArch64::S_FUNCINIT: return "%funcinit"; default: llvm_unreachable("Invalid relocation specifier"); } // clang-format on } +AArch64::Specifier AArch64::parsePercentSpecifierName(StringRef name) { + return StringSwitch(name) + .Case("pltpcrel", AArch64::S_PLT) + .Case("gotpcrel", AArch64::S_GOTPCREL) + .Case("funcinit", AArch64::S_FUNCINIT) + .Default(0); +} + static bool evaluate(const MCSpecifierExpr &Expr, MCValue &Res, const MCAssembler *Asm) { if (!Expr.getSubExpr()->evaluateAsRelocatable(Res, Asm)) @@ -232,8 +244,13 @@ void AArch64MCAsmInfoELF::printSpecifierExpr( raw_ostream &OS, const MCSpecifierExpr &Expr) const { if (auto *AE = dyn_cast(&Expr)) return AE->print(OS, this); - OS << AArch64::getSpecifierName(Expr.getSpecifier()); + auto Str = AArch64::getSpecifierName(Expr.getSpecifier()); + OS << Str; + if (!Str.empty() && Str[0] == '%') + OS << '('; printExpr(OS, *Expr.getSubExpr()); + if (!Str.empty() && Str[0] == '%') + OS << ')'; } bool AArch64MCAsmInfoELF::evaluateAsRelocatableImpl( diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h index f2acff54f166..5bb8ff8599b2 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h @@ -184,6 +184,8 @@ enum { /// (e.g. ":got:", ":lo12:"). StringRef getSpecifierName(Specifier S); +Specifier parsePercentSpecifierName(StringRef); + inline Specifier getSymbolLoc(Specifier S) { return static_cast(S & AArch64::S_SymLocBits); } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-irelative.ll b/llvm/test/CodeGen/AArch64/ptrauth-irelative.ll index 1e0af68dd7ab..f0ac7a821094 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-irelative.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-irelative.ll @@ -8,7 +8,7 @@ ; CHECK-NEXT: mov x1, #1 ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .rodata -; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT +; CHECK-NEXT: .xword %funcinit([[FUNC]]) @nullref = constant ptr ptrauth (ptr null, i32 2, i64 1, ptr null), align 8 @dsolocal = external dso_local global i8 @@ -22,7 +22,7 @@ ; CHECK-NEXT: mov x1, #2 ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .data.rel.ro -; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT +; CHECK-NEXT: .xword %funcinit([[FUNC]]) @dsolocalref = constant ptr ptrauth (ptr @dsolocal, i32 2, i64 2, ptr null), align 8 @ds = external global i8 @@ -39,7 +39,7 @@ ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: ret ; CHECK-NEXT: .section .data.rel.ro -; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT +; CHECK-NEXT: .xword %funcinit([[FUNC]]) @dsolocalrefds = constant ptr ptrauth (ptr @dsolocal, i32 2, i64 2, ptr null, ptr @ds), align 8 ; CHECK: dsolocalref8: @@ -51,7 +51,7 @@ ; CHECK-NEXT: mov x1, #3 ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .data.rel.ro -; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT +; CHECK-NEXT: .xword %funcinit([[FUNC]]) @dsolocalref8 = constant ptr ptrauth (ptr getelementptr (i8, ptr @dsolocal, i64 8), i32 2, i64 3, ptr null), align 8 ; CHECK: disc: @@ -64,7 +64,7 @@ ; CHECK-NEXT: add x1, x1, :lo12:[[PLACE]] ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .data.rel.ro -; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT +; CHECK-NEXT: .xword %funcinit([[FUNC]]) @disc = constant ptr ptrauth (ptr @dsolocal, i32 2, i64 0, ptr @disc), align 8 ; CHECK: disc65536: @@ -77,7 +77,7 @@ ; CHECK-NEXT: add x1, x1, :lo12:[[PLACE]]+65536 ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .data.rel.ro -; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT +; CHECK-NEXT: .xword %funcinit([[FUNC]]) @disc65536 = constant ptr ptrauth (ptr @dsolocal, i32 2, i64 65536, ptr @disc), align 8 @global = external global i8 @@ -91,7 +91,7 @@ ; CHECK-NEXT: mov x1, #4 ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .data.rel.ro -; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT +; CHECK-NEXT: .xword %funcinit([[FUNC]]) @globalref = constant ptr ptrauth (ptr @global, i32 2, i64 4, ptr null), align 8 ; CHECK: globalref8: @@ -104,7 +104,7 @@ ; CHECK-NEXT: mov x1, #5 ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .data.rel.ro -; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT +; CHECK-NEXT: .xword %funcinit([[FUNC]]) @globalref8 = constant ptr ptrauth (ptr getelementptr (i8, ptr @global, i64 8), i32 2, i64 5, ptr null), align 8 ; CHECK: globalref16777216: @@ -119,7 +119,7 @@ ; CHECK-NEXT: mov x1, #5 ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .data.rel.ro -; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT +; CHECK-NEXT: .xword %funcinit([[FUNC]]) @globalref16777216 = constant ptr ptrauth (ptr getelementptr (i8, ptr @global, i64 16777216), i32 2, i64 5, ptr null), align 8 $comdat = comdat any diff --git a/llvm/test/MC/AArch64/data-directive-specifier.s b/llvm/test/MC/AArch64/data-directive-specifier.s index 2d1ec4feddfa..f964b3cf92ec 100644 --- a/llvm/test/MC/AArch64/data-directive-specifier.s +++ b/llvm/test/MC/AArch64/data-directive-specifier.s @@ -1,57 +1,65 @@ +# RUN: llvm-mc -triple=aarch64 %s | FileCheck %s --check-prefix=ASM # RUN: llvm-mc -triple=aarch64 -filetype=obj %s | llvm-readobj -r - | FileCheck %s -# RUN: not llvm-mc -triple=aarch64 %s --defsym ERR=1 -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error: -# RUN: not llvm-mc -triple=aarch64 -filetype=obj %s --defsym OBJERR=1 -o /dev/null 2>&1 | FileCheck %s --check-prefix=OBJERR --implicit-check-not=error: + +# RUN: not llvm-mc -triple=aarch64 %s --defsym ERR0=1 2>&1 | FileCheck %s --check-prefix=ERR0 --implicit-check-not=error: +# RUN: not llvm-mc -triple=aarch64 -filetype=obj %s --defsym ERR=1 -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error: .globl g g: l: +# ASM: .word %pltpcrel(l) # CHECK: Section ({{.*}}) .rela.data { # CHECK-NEXT: 0x0 R_AARCH64_PLT32 l 0x0 -# CHECK-NEXT: 0x4 R_AARCH64_PLT32 l 0x4 -# 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: 0x4 R_AARCH64_PLT32 extern 0x4 +# CHECK-NEXT: 0x8 R_AARCH64_PLT32 g 0x8 # CHECK-NEXT: } .data -.word l@plt - . -.word l@plt - .data - -.word extern@plt - . + 4 -.word g@plt - . + 8 -.word g@plt - .data + 8 - -.quad l@funcinit +.word %pltpcrel(l) +.word %pltpcrel(extern + 4), %pltpcrel(g + 8) +# ASM: .word %gotpcrel(data1) # CHECK: Section ({{.*}}) .rela.data1 { # CHECK-NEXT: 0x0 R_AARCH64_GOTPCREL32 data1 0x0 # CHECK-NEXT: 0x4 R_AARCH64_GOTPCREL32 extern 0x4 -# CHECK-NEXT: 0x8 R_AARCH64_GOTPCREL32 extern 0xFFFFFFFFFFFFFFFB +# CHECK-NEXT: 0x8 R_AARCH64_GOTPCREL32 extern 0xFFFFFFFFFFFFFFFB +# CHECK-NEXT: 0xC R_AARCH64_FUNCINIT64 .text 0 # CHECK-NEXT: } .section .data1,"aw" data1: -.word data1@GOTPCREL -.word extern@gotpcrel+4 -.word extern@GOTPCREL-5 +.word %gotpcrel(data1) +.word %gotpcrel(extern+4), %gotpcrel(extern-5) + +.quad %funcinit(l) + +.ifdef ERR0 +# ERR0: [[#@LINE+1]]:8: error: invalid relocation specifier +.word %xxx(l) + +# ERR0: [[#@LINE+1]]:17: error: expected '(' +.word %pltpcrel l + +# ERR0: [[#@LINE+2]]:14: error: unknown token in expression +# ERR0: [[#@LINE+1]]:14: error: invalid operand +ldr w0, [x1, %pltpcrel(g)] +.endif -## Test parse-time errors .ifdef ERR -# ERR: [[#@LINE+1]]:9: error: @ specifier only allowed after a symbol -.quad 3@plt - . +# ERR: [[#@LINE+1]]:8: error: %pltpcrel can only be used in a .word directive +.quad %pltpcrel(g) -# ERR: [[#@LINE+1]]:9: error: expected ')' -.quad (l@plt - .) -.endif - -.ifdef OBJERR -.quad g@plt - . - -.word extern@gotpcrel - . - -# OBJERR: [[#@LINE+1]]:7: error: symbol 'und' can not be undefined in a subtraction expression -.word extern@plt - und - -# OBJERR: [[#@LINE+1]]:7: error: symbol 'und' can not be undefined in a subtraction expression -.word extern@gotpcrel - und +# ERR: [[#@LINE+1]]:8: error: expected relocatable expression +.word %pltpcrel(g-.) + +# ERR: [[#@LINE+1]]:8: error: expected relocatable expression +.word %pltpcrel(extern - und) + +# ERR: [[#@LINE+1]]:8: error: %gotpcrel can only be used in a .word directive +.quad %gotpcrel(g) + +# ERR: [[#@LINE+1]]:8: error: expected relocatable expression +.word %gotpcrel(extern - .) + +# ERR: [[#@LINE+1]]:8: error: expected relocatable expression +.word %gotpcrel(extern - und) .endif diff --git a/llvm/test/MC/AArch64/elf-reloc-ptrauth.s b/llvm/test/MC/AArch64/elf-reloc-ptrauth.s index 53e0107c5cca..06031383fe35 100644 --- a/llvm/test/MC/AArch64/elf-reloc-ptrauth.s +++ b/llvm/test/MC/AArch64/elf-reloc-ptrauth.s @@ -125,7 +125,7 @@ _g9: // ERR: :[[#@LINE+1]]:21: error: expected ')' .quad sym@AUTH(ia,42( -// ERR: :[[#@LINE+1]]:14: error: unexpected token +// ERR: :[[#@LINE+1]]:11: error: invalid relocation specifier .quad sym@PLT@AUTH(ia,42) // ERR: :[[#@LINE+1]]:15: error: expected '('