-
Notifications
You must be signed in to change notification settings - Fork 15k
AArch64: Replace @plt/%gotpcrel in data directives with %pltpcrel %gotpcrel #155774
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
AArch64: Replace @plt/%gotpcrel in data directives with %pltpcrel %gotpcrel #155774
Conversation
Created using spr 1.3.5-bogner
@llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-lld-elf Author: Fangrui Song (MaskRay) ChangesSimilar to #132569 for RISC-V, replace the unofficial Full diff: https://github.com/llvm/llvm-project/pull/155774.diff 7 Files Affected:
diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
index 4d007776a86a7..35dfe756f4b24 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 8a3b989a909b8..cd442e76fcf3d 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/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 3641e22e6f76a..88ccc043d8b89 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -181,6 +181,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
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);
@@ -8190,8 +8191,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;
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index a388216a95098..5add98dcab931 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -104,6 +104,18 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup,
break;
}
+ switch (RefKind) {
+ case AArch64::S_GOTPCREL:
+ case AArch64::S_PLT:
+ if (Kind == FK_Data_4)
+ break;
+ reportError(Fixup.getLoc(), AArch64::getSpecifierName(RefKind) +
+ " can only be used in a .word directive");
+ return ELF::R_RISCV_NONE;
+ default:
+ break;
+ }
+
// Extract the relocation type from the fixup kind, after applying STT_TLS as
// needed.
if (mc::isRelocation(Fixup.getKind()))
@@ -117,8 +129,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 +231,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 2b5cf3484ffc1..a06ae8eb8c3cb 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
@@ -113,12 +113,22 @@ 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";
default:
llvm_unreachable("Invalid relocation specifier");
}
// clang-format on
}
+AArch64::Specifier AArch64::parsePercentSpecifierName(StringRef name) {
+ return StringSwitch<AArch64::Specifier>(name)
+ .Case("pltpcrel", AArch64::S_PLT)
+ .Case("gotpcrel", AArch64::S_GOTPCREL)
+ .Default(0);
+}
+
static bool evaluate(const MCSpecifierExpr &Expr, MCValue &Res,
const MCAssembler *Asm) {
if (!Expr.getSubExpr()->evaluateAsRelocatable(Res, Asm))
@@ -232,8 +242,13 @@ void AArch64MCAsmInfoELF::printSpecifierExpr(
raw_ostream &OS, const MCSpecifierExpr &Expr) const {
if (auto *AE = dyn_cast<AArch64AuthMCExpr>(&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 0dfa61b1dc60e..971ba58497f96 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h
@@ -183,6 +183,8 @@ enum {
/// (e.g. ":got:", ":lo12:").
StringRef getSpecifierName(Specifier S);
+Specifier parsePercentSpecifierName(StringRef);
+
inline Specifier getSymbolLoc(Specifier S) {
return static_cast<Specifier>(S & AArch64::S_SymLocBits);
}
diff --git a/llvm/test/MC/AArch64/data-directive-specifier.s b/llvm/test/MC/AArch64/data-directive-specifier.s
index 2cb7eb3a3ca81..a790bb57b9bd5 100644
--- a/llvm/test/MC/AArch64/data-directive-specifier.s
+++ b/llvm/test/MC/AArch64/data-directive-specifier.s
@@ -1,6 +1,6 @@
# 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 -o /dev/null 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:
@@ -8,47 +8,51 @@ 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: 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
+.word %pltpcrel(l)
+.word %pltpcrel(extern + 4), %pltpcrel(g + 8)
# 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: }
.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)
-## Test parse-time errors
-.ifdef ERR
-# ERR: [[#@LINE+1]]:9: error: @ specifier only allowed after a symbol
-.quad 3@plt - .
+.ifdef ERR0
+# ERR0: [[#@LINE+1]]:8: error: invalid relocation specifier
+.word %xxx(l)
+
+# ERR0: [[#@LINE+1]]:17: error: expected '('
+.word %pltpcrel l
-# ERR: [[#@LINE+1]]:9: error: expected ')'
-.quad (l@plt - .)
+# ERR0: [[#@LINE+2]]:14: error: unknown token in expression
+# ERR0: [[#@LINE+1]]:14: error: invalid operand
+ldr w0, [x1, %pltpcrel(g)]
.endif
-.ifdef OBJERR
-.quad g@plt - .
+.ifdef ERR
+# ERR: [[#@LINE+1]]:8: error: %pltpcrel can only be used in a .word directive
+.quad %pltpcrel(g)
+
+# ERR: [[#@LINE+1]]:8: error: expected relocatable expression
+.word %pltpcrel(g-.)
+
+# ERR: [[#@LINE+1]]:8: error: expected relocatable expression
+.word %pltpcrel(extern - und)
-.word extern@gotpcrel - .
+# ERR: [[#@LINE+1]]:8: error: %gotpcrel can only be used in a .word directive
+.quad %gotpcrel(g)
-# OBJERR: [[#@LINE+1]]:7: error: symbol 'und' can not be undefined in a subtraction expression
-.word extern@plt - und
+# ERR: [[#@LINE+1]]:8: error: expected relocatable expression
+.word %gotpcrel(extern - .)
-# 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 %gotpcrel(extern - und)
.endif
|
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.