Skip to content

Commit ca2ea02

Browse files
committed
AArch64: Replace @plt/%gotpcrel in data directives with %pltpcrel %gotpcrel
Similar to llvm#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. Pull Request: llvm#155776
1 parent 856555b commit ca2ea02

12 files changed

+119
-61
lines changed

lld/test/ELF/aarch64-branch-to-branch.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ vtable:
3535
# B2B-NEXT: [[VF:[0-9a-f]{8}]]
3636
# B2B-RELOC-NEXT: R_AARCH64_PLT32 f3
3737
# NOB2B-RELOC-NEXT: R_AARCH64_PLT32 f1
38-
.4byte f1@PLT - vtable
38+
.4byte %pltpcrel(f1)
3939
# B2B-SAME: [[VF]]
4040
# B2B-RELOC-NEXT: R_AARCH64_PLT32 f3+0x4
4141
# NOB2B-RELOC-NEXT: R_AARCH64_PLT32 f2+0x4
42-
.4byte f2@PLT - vtable
42+
.4byte %pltpcrel(f2+4)
4343
# B2B-SAME: [[VF]]
4444
# RELOC-NEXT: R_AARCH64_PLT32 f3+0x8
45-
.4byte f3@PLT - vtable
45+
.4byte %pltpcrel(f3+8)
4646

4747
.section .text._start,"ax"
4848
.globl _start

lld/test/ELF/aarch64-feature-bti.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,5 +290,5 @@ func1:
290290

291291
.ifdef RELVTABLE_PLT
292292
// R_AARCH64_PLT32
293-
.word funcRelVtable@PLT - .
293+
.word %pltpcrel(funcRelVtable)
294294
.endif

lld/test/ELF/aarch64-range-thunk-extension-plt32.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
.global _start
2626
.type _start, %function
2727
_start:
28-
.word callee@PLT - .
28+
.word %pltpcrel(callee)
2929

3030
.section .text.2, "ax", %progbits
3131
.global callee

lld/test/ELF/aarch64-reloc-gotpcrel32.s

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ _start: // PC = 0x303a0
1717
// bar@GOTPCREL-4 = 0x20390 (got entry for `bar`) - 0x303a8 (.) - 4 = 0xe4fffeff
1818
// CHECK: Contents of section .data:
1919
// CHECK-NEXT: {{.*}} f0fffeff f0fffeff e4fffeff
20-
.word bar@GOTPCREL
21-
.word bar@GOTPCREL+4
22-
.word bar@GOTPCREL-4
20+
.word %gotpcrel(bar)
21+
.word %gotpcrel(bar+4)
22+
.word %gotpcrel(bar-4)
2323

2424
// WARN: relocation R_AARCH64_GOTPCREL32 out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
2525
// WARN: relocation R_AARCH64_GOTPCREL32 out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
26-
.word baz@GOTPCREL+0xffffffff
27-
.word baz@GOTPCREL-0xffffffff
26+
.word %gotpcrel(baz+0xffffffff)
27+
.word %gotpcrel(baz-0xffffffff)

lld/test/ELF/aarch64-reloc-plt32.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@
3232
.globl _start
3333
_start:
3434
.data
35-
.word foo@PLT - . + 2149589079
36-
.word foo@PLT - . - 2145378212
37-
.word foo@PLT - .
35+
.word %pltpcrel(foo + 2149589079)
36+
.word %pltpcrel(foo - 2145378212)
37+
.word %pltpcrel(foo)

lld/test/ELF/aarch64-undefined-weak.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ _start:
3737
// R_AARCH64_PREL16
3838
.hword target - .
3939
// R_AARCH64_PLT32
40-
.word target@PLT - .
40+
.word %pltpcrel(target)
4141

4242
bl_undefweak2:
4343
bl undefweak2

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
181181
bool showMatchError(SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo,
182182
OperandVector &Operands);
183183

184+
bool parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E);
184185
bool parseDataExpr(const MCExpr *&Res) override;
185186
bool parseAuthExpr(const MCExpr *&Res, SMLoc &EndLoc);
186187

@@ -8190,8 +8191,31 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
81908191
return false;
81918192
}
81928193

8194+
bool AArch64AsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) {
8195+
SMLoc Loc = getLoc();
8196+
if (getLexer().getKind() != AsmToken::Identifier)
8197+
return TokError("expected '%' relocation specifier");
8198+
StringRef Identifier = getParser().getTok().getIdentifier();
8199+
auto Spec = AArch64::parsePercentSpecifierName(Identifier);
8200+
if (!Spec)
8201+
return TokError("invalid relocation specifier");
8202+
8203+
getParser().Lex(); // Eat the identifier
8204+
if (parseToken(AsmToken::LParen, "expected '('"))
8205+
return true;
8206+
8207+
const MCExpr *SubExpr;
8208+
if (getParser().parseParenExpression(SubExpr, E))
8209+
return true;
8210+
8211+
Res = MCSpecifierExpr::create(SubExpr, Spec, getContext(), Loc);
8212+
return false;
8213+
}
8214+
81938215
bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) {
81948216
SMLoc EndLoc;
8217+
if (parseOptionalToken(AsmToken::Percent))
8218+
return parseExprWithSpecifier(Res, EndLoc);
81958219

81968220
if (getParser().parseExpression(Res))
81978221
return true;
@@ -8211,14 +8235,6 @@ bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) {
82118235
if (STI->getTargetTriple().isOSBinFormatMachO()) {
82128236
if (Identifier == "got")
82138237
Spec = AArch64::S_MACHO_GOT;
8214-
} else {
8215-
// Unofficial, experimental syntax that will be changed.
8216-
if (Identifier == "gotpcrel")
8217-
Spec = AArch64::S_GOTPCREL;
8218-
else if (Identifier == "plt")
8219-
Spec = AArch64::S_PLT;
8220-
else if (Identifier == "funcinit")
8221-
Spec = AArch64::S_FUNCINIT;
82228238
}
82238239
if (Spec == AArch64::S_None)
82248240
return Error(Loc, "invalid relocation specifier");

llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,18 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup,
104104
break;
105105
}
106106

107+
switch (RefKind) {
108+
case AArch64::S_GOTPCREL:
109+
case AArch64::S_PLT:
110+
if (Kind == FK_Data_4)
111+
break;
112+
reportError(Fixup.getLoc(), AArch64::getSpecifierName(RefKind) +
113+
" can only be used in a .word directive");
114+
return ELF::R_AARCH64_NONE;
115+
default:
116+
break;
117+
}
118+
107119
// Extract the relocation type from the fixup kind, after applying STT_TLS as
108120
// needed.
109121
if (mc::isRelocation(Fixup.getKind()))
@@ -117,8 +129,7 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup,
117129
case FK_Data_2:
118130
return R_CLS(PREL16);
119131
case FK_Data_4: {
120-
return Target.getSpecifier() == AArch64::S_PLT ? R_CLS(PLT32)
121-
: R_CLS(PREL32);
132+
return R_CLS(PREL32);
122133
}
123134
case FK_Data_8:
124135
if (IsILP32) {
@@ -220,9 +231,13 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup,
220231
case FK_Data_2:
221232
return R_CLS(ABS16);
222233
case FK_Data_4:
223-
return (!IsILP32 && Target.getSpecifier() == AArch64::S_GOTPCREL)
224-
? ELF::R_AARCH64_GOTPCREL32
225-
: R_CLS(ABS32);
234+
if (!IsILP32) {
235+
if (Target.getSpecifier() == AArch64::S_GOTPCREL)
236+
return ELF::R_AARCH64_GOTPCREL32;
237+
if (Target.getSpecifier() == AArch64::S_PLT)
238+
return ELF::R_AARCH64_PLT32;
239+
}
240+
return R_CLS(ABS32);
226241
case FK_Data_8: {
227242
if (IsILP32) {
228243
reportError(

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,24 @@ StringRef AArch64::getSpecifierName(AArch64::Specifier S) {
114114
case AArch64::S_GOT_AUTH: return ":got_auth:";
115115
case AArch64::S_GOT_AUTH_PAGE: return ":got_auth:";
116116
case AArch64::S_GOT_AUTH_LO12: return ":got_auth_lo12:";
117+
118+
case AArch64::S_GOTPCREL: return "%gotpcrel";
119+
case AArch64::S_PLT: return "%pltpcrel";
120+
case AArch64::S_FUNCINIT: return "%funcinit";
117121
default:
118122
llvm_unreachable("Invalid relocation specifier");
119123
}
120124
// clang-format on
121125
}
122126

127+
AArch64::Specifier AArch64::parsePercentSpecifierName(StringRef name) {
128+
return StringSwitch<AArch64::Specifier>(name)
129+
.Case("pltpcrel", AArch64::S_PLT)
130+
.Case("gotpcrel", AArch64::S_GOTPCREL)
131+
.Case("funcinit", AArch64::S_FUNCINIT)
132+
.Default(0);
133+
}
134+
123135
static bool evaluate(const MCSpecifierExpr &Expr, MCValue &Res,
124136
const MCAssembler *Asm) {
125137
if (!Expr.getSubExpr()->evaluateAsRelocatable(Res, Asm))
@@ -233,8 +245,13 @@ void AArch64MCAsmInfoELF::printSpecifierExpr(
233245
raw_ostream &OS, const MCSpecifierExpr &Expr) const {
234246
if (auto *AE = dyn_cast<AArch64AuthMCExpr>(&Expr))
235247
return AE->print(OS, this);
236-
OS << AArch64::getSpecifierName(Expr.getSpecifier());
248+
auto Str = AArch64::getSpecifierName(Expr.getSpecifier());
249+
OS << Str;
250+
if (!Str.empty() && Str[0] == '%')
251+
OS << '(';
237252
printExpr(OS, *Expr.getSubExpr());
253+
if (!Str.empty() && Str[0] == '%')
254+
OS << ')';
238255
}
239256

240257
bool AArch64MCAsmInfoELF::evaluateAsRelocatableImpl(

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ enum {
184184
/// (e.g. ":got:", ":lo12:").
185185
StringRef getSpecifierName(Specifier S);
186186

187+
Specifier parsePercentSpecifierName(StringRef);
188+
187189
inline Specifier getSymbolLoc(Specifier S) {
188190
return static_cast<Specifier>(S & AArch64::S_SymLocBits);
189191
}

0 commit comments

Comments
 (0)