[llvm] 94821ce - MCValue: Store SymA specifier at Specifier
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 5 17:16:59 PDT 2025
Author: Fangrui Song
Date: 2025-04-05T17:16:54-07:00
New Revision: 94821ce45fe93aa78cc5ea03cd9deac91b7af127
URL: https://github.com/llvm/llvm-project/commit/94821ce45fe93aa78cc5ea03cd9deac91b7af127
DIFF: https://github.com/llvm/llvm-project/commit/94821ce45fe93aa78cc5ea03cd9deac91b7af127.diff
LOG: MCValue: Store SymA specifier at Specifier
The relocation specifier should be accessed via MCValue::Specifier.
However, some targets encode the relocation specifier within SymA using
MCSymbolRefExpr::SubclassData and access it via getAccessVariant(), though
this method is now deprecated.
This change stores the SymA specifier at Specifier as well, unifying the
two code paths.
* CSKY: GOT- and PLT- relocations now suppress the STT_SECTION
conversion.
* AArch64: https://reviews.llvm.org/D156505 added `getRefkind` check to
prevent folding. This is a hack and is now removed.
MCValue: Unify relocation specifier storage by storing SymA specifier at Specifier
The relocation specifier is accessed via MCValue::Specifier, but some
targets encoded it within SymA using MCSymbolRefExpr::SubclassData and
retrieved it through the now-deprecated getAccessVariant() method. This
commit unifies the two approaches by storing the SymA specifier at
`Specifier` as well.
Additional changes:
- CSKY: GOT- and PLT- relocations now suppress STT_SECTION conversion.
- AArch64: Removed the `getRefkind` check hack (introduced in https://reviews.llvm.org/D156505) that prevented folding.
Removed the assertion from `getRelocType`.
- RISCV: Removed the assertion from `getRelocType`.
Future plans:
- Replace MCSymbolRefExpr members with MCSymbol within MCValue.
- Remove `getSymSpecifier` (added for migration).
Added:
Modified:
llvm/include/llvm/MC/MCExpr.h
llvm/include/llvm/MC/MCValue.h
llvm/lib/MC/MCAssembler.cpp
llvm/lib/MC/MCExpr.cpp
llvm/lib/MC/MCValue.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
llvm/test/MC/AArch64/elf-reloc-ptrauth.s
llvm/test/MC/CSKY/relocation-specifier.s
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h
index b0e347d690f0e..0d7a961c364db 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -135,7 +135,8 @@ class MCExpr {
static bool evaluateSymbolicAdd(const MCAssembler *, const SectionAddrMap *,
bool, const MCValue &,
const MCSymbolRefExpr *,
- const MCSymbolRefExpr *, int64_t, MCValue &);
+ const MCSymbolRefExpr *, int64_t, uint32_t,
+ MCValue &);
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
diff --git a/llvm/include/llvm/MC/MCValue.h b/llvm/include/llvm/MC/MCValue.h
index 9ef77703356a4..fbe32ae5d59fe 100644
--- a/llvm/include/llvm/MC/MCValue.h
+++ b/llvm/include/llvm/MC/MCValue.h
@@ -36,6 +36,10 @@ class MCValue {
int64_t Cst = 0;
uint32_t Specifier = 0;
+ // SymA has a relocation specifier. This is a workaround for targets
+ // that encode specifiers within MCSymbolRefExpr::SubclassData.
+ bool SymSpecifier = false;
+
// SymB cannot have a specifier. Use getSubSym instead.
const MCSymbolRefExpr *getSymB() const { return SymB; }
@@ -67,18 +71,23 @@ class MCValue {
// Get the relocation specifier from SymA. This is a workaround for targets
// that do not use MCValue::Specifier.
- uint16_t getSymSpecifier() const { return SymA->getSpecifier(); }
- // Get the relocation specifier from SymA, or 0 when SymA is null.
- uint16_t getAccessVariant() const;
+ uint16_t getSymSpecifier() const { return Specifier; }
+ uint16_t getAccessVariant() const { return Specifier; }
static MCValue get(const MCSymbolRefExpr *SymA,
- const MCSymbolRefExpr *SymB = nullptr,
- int64_t Val = 0, uint32_t RefKind = 0) {
+ const MCSymbolRefExpr *SymB = nullptr, int64_t Val = 0,
+ uint32_t Specifier = 0) {
MCValue R;
R.Cst = Val;
R.SymA = SymA;
R.SymB = SymB;
- R.Specifier = RefKind;
+ R.Specifier = Specifier;
+ assert(!(Specifier && SymA && SymA->getSpecifier()) &&
+ "Specifier cannot be used with legacy SymSpecifier");
+ if (!Specifier && SymA && SymA->getSpecifier()) {
+ R.Specifier = SymA->getSpecifier();
+ R.SymSpecifier = true;
+ }
return R;
}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 5e3081251e40a..5739097cc2620 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -168,7 +168,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
IsResolved = false;
} else {
auto &SA = *Target.getAddSym();
- if (Target.getSymSpecifier() || SA.isUndefined()) {
+ if (Target.SymSpecifier || SA.isUndefined()) {
IsResolved = false;
} else {
IsResolved = (FixupFlags & MCFixupKindInfo::FKF_Constant) ||
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index b921b55950772..e3d4c5c27fe69 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -439,7 +439,7 @@ bool MCExpr::evaluateSymbolicAdd(const MCAssembler *Asm,
const MCValue &LHS,
const MCSymbolRefExpr *RhsAdd,
const MCSymbolRefExpr *RhsSub, int64_t RHS_Cst,
- MCValue &Res) {
+ uint32_t RhsSpec, MCValue &Res) {
const MCSymbol *LHS_A = LHS.getAddSym();
const MCSymbol *LHS_B = LHS.getSubSym();
int64_t LHS_Cst = LHS.getConstant();
@@ -451,16 +451,16 @@ bool MCExpr::evaluateSymbolicAdd(const MCAssembler *Asm,
int64_t Result_Cst = LHS_Cst + RHS_Cst;
// If we have a layout, we can fold resolved
diff erences.
- if (Asm) {
+ if (Asm && !LHS.getSpecifier() && !RhsSpec) {
// While LHS_A-LHS_B and RHS_A-RHS_B from recursive calls have already been
// folded, reassociating terms in
// Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
// might bring more opportunities.
- if (LHS_A && RHS_B && !LHS.getSymA()->getSpecifier()) {
+ if (LHS_A && RHS_B) {
attemptToFoldSymbolOffsetDifference(Asm, Addrs, InSet, LHS_A, RHS_B,
Result_Cst);
}
- if (RHS_A && LHS_B && !RhsAdd->getSpecifier()) {
+ if (RHS_A && LHS_B) {
attemptToFoldSymbolOffsetDifference(Asm, Addrs, InSet, RHS_A, LHS_B,
Result_Cst);
}
@@ -476,7 +476,12 @@ bool MCExpr::evaluateSymbolicAdd(const MCAssembler *Asm,
auto *B = LHS_B ? LHS.getSymB() : RHS_B ? RhsSub : nullptr;
if (B && B->getKind() != MCSymbolRefExpr::VK_None)
return false;
+ auto Spec = LHS.getSpecifier();
+ if (!Spec)
+ Spec = RhsSpec;
Res = MCValue::get(A, B, Result_Cst);
+ Res.Specifier = Spec;
+ Res.SymSpecifier = 0;
return true;
}
@@ -634,9 +639,6 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
return false;
case MCBinaryExpr::Add:
case MCBinaryExpr::Sub:
- // TODO: Prevent folding for AArch64 @AUTH operands.
- if (LHSValue.getSpecifier() || RHSValue.getSpecifier())
- return false;
if (Op == MCBinaryExpr::Sub) {
std::swap(RHSValue.SymA, RHSValue.SymB);
RHSValue.Cst = -(uint64_t)RHSValue.Cst;
@@ -652,7 +654,8 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
return true;
}
return evaluateSymbolicAdd(Asm, Addrs, InSet, LHSValue, RHSValue.SymA,
- RHSValue.SymB, RHSValue.Cst, Res);
+ RHSValue.SymB, RHSValue.Cst,
+ RHSValue.SymSpecifier, Res);
}
}
diff --git a/llvm/lib/MC/MCValue.cpp b/llvm/lib/MC/MCValue.cpp
index 913fe83ab94eb..77deb0b4ab671 100644
--- a/llvm/lib/MC/MCValue.cpp
+++ b/llvm/lib/MC/MCValue.cpp
@@ -43,9 +43,3 @@ LLVM_DUMP_METHOD void MCValue::dump() const {
print(dbgs());
}
#endif
-
-uint16_t MCValue::getAccessVariant() const {
- if (!SymA)
- return 0;
- return SymA->getSpecifier();
-}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
index c5accb5e3b51b..3335d9d6f009c 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -426,8 +426,13 @@ void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
AArch64MCExpr::Specifier SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
if (SymLoc == AArch64AuthMCExpr::VK_AUTH ||
SymLoc == AArch64AuthMCExpr::VK_AUTHADDR) {
+ const auto *Expr = dyn_cast<AArch64AuthMCExpr>(Fixup.getValue());
+ if (!Expr) {
+ Asm.getContext().reportError(Fixup.getValue()->getLoc(),
+ "expected relocatable expression");
+ return;
+ }
assert(Value == 0);
- const auto *Expr = cast<AArch64AuthMCExpr>(Fixup.getValue());
Value = (uint64_t(Expr->getDiscriminator()) << 32) |
(uint64_t(Expr->getKey()) << 60) |
(uint64_t(Expr->hasAddressDiversity()) << 63);
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index b03c55cafdcdf..c3c4c64cad5b0 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -116,12 +116,6 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
AArch64MCExpr::Specifier SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
- assert((!Target.getAddSym() ||
- Target.getSymSpecifier() == AArch64MCExpr::None ||
- Target.getSymSpecifier() == AArch64MCExpr::VK_PLT ||
- Target.getSymSpecifier() == AArch64MCExpr::VK_GOTPCREL) &&
- "Should only be expression-level modifiers here");
-
switch (SymLoc) {
case AArch64MCExpr::VK_DTPREL:
case AArch64MCExpr::VK_GOTTPREL:
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
index 845c590478e5c..e33961a973d1e 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
@@ -196,9 +196,9 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
break;
case PPC::fixup_ppc_half16:
- switch (RefKind) {
+ switch (Modifier) {
default:
- break;
+ llvm_unreachable("Unsupported specifier");
case PPCMCExpr::VK_LO:
return ELF::R_PPC_ADDR16_LO;
case PPCMCExpr::VK_HI:
@@ -217,9 +217,7 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
return ELF::R_PPC64_ADDR16_HIGHEST;
case PPCMCExpr::VK_HIGHESTA:
return ELF::R_PPC64_ADDR16_HIGHESTA;
- }
- switch (Modifier) {
- default: llvm_unreachable("Unsupported Modifier");
+
case PPCMCExpr::VK_None:
Type = ELF::R_PPC_ADDR16;
break;
@@ -373,17 +371,12 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
break;
case PPC::fixup_ppc_half16ds:
case PPC::fixup_ppc_half16dq:
- switch (RefKind) {
+ switch (Modifier) {
default:
Ctx.reportError(Fixup.getLoc(), "invalid VariantKind");
return ELF::R_PPC64_NONE;
- case PPCMCExpr::VK_None:
- break;
case PPCMCExpr::VK_LO:
return ELF::R_PPC64_ADDR16_LO_DS;
- }
- switch (Modifier) {
- default: llvm_unreachable("Unsupported Modifier");
case PPCMCExpr::VK_None:
Type = ELF::R_PPC64_ADDR16_DS;
break;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
index 586440f407d71..1662b8068084c 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
@@ -50,9 +50,6 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
- assert((!Target.getAddSym() ||
- Target.getSymSpecifier() == MCSymbolRefExpr::VK_None) &&
- "sym at specifier should have been rejected");
const MCExpr *Expr = Fixup.getValue();
// Determine the type of the relocation
unsigned Kind = Fixup.getTargetKind();
diff --git a/llvm/test/MC/AArch64/elf-reloc-ptrauth.s b/llvm/test/MC/AArch64/elf-reloc-ptrauth.s
index 9fe78a4e4e822..6f47e2d614d19 100644
--- a/llvm/test/MC/AArch64/elf-reloc-ptrauth.s
+++ b/llvm/test/MC/AArch64/elf-reloc-ptrauth.s
@@ -164,15 +164,6 @@ _g9:
// RUN: not llvm-mc -triple=aarch64 -filetype=obj --defsym=ERROBJ=1 %s -o /dev/null 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERROBJ
-// ERROBJ: :[[#@LINE+1]]:7: error: expected relocatable expression
-.quad sym at AUTH(ia,42) + 1
-
-// ERROBJ: :[[#@LINE+1]]:7: error: expected relocatable expression
-.quad 1 + sym at AUTH(ia,42)
-
-// ERROBJ: :[[#@LINE+1]]:7: error: expected relocatable expression
-.quad 1 + sym at AUTH(ia,42) + 1
-
// ERROBJ: :[[#@LINE+1]]:7: error: expected relocatable expression
.quad sym at AUTH(ia,42) + sym at AUTH(ia,42)
@@ -181,11 +172,17 @@ _g9:
// distance remains the same. Leave it in such state as for now since it
// makes code simpler: subtraction of a non-AUTH symbol and of a constant
// are handled identically.
-// ERROBJ: :[[#@LINE+1]]:7: error: expected relocatable expression
+// ERROBJ: :[[#@LINE+1]]:7: error: Cannot represent a
diff erence across sections
.quad _g9 at AUTH(ia,42) - _g8
-// ERROBJ: :[[#@LINE+1]]:7: error: expected relocatable expression
+// ERROBJ: :[[#@LINE+1]]:7: error: Cannot represent a
diff erence across sections
.quad _g9 at AUTH(ia,42) - _g8 at AUTH(ia,42)
.quad 0
+// ERROBJ: :[[#@LINE+1]]:23: error: expected relocatable expression
+.quad sym at AUTH(ia,42) + 1
+
+// ERROBJ: :[[#@LINE+1]]:9: error: expected relocatable expression
+.quad 1 + sym at AUTH(ia,42)
+
.endif // ERROBJ
diff --git a/llvm/test/MC/CSKY/relocation-specifier.s b/llvm/test/MC/CSKY/relocation-specifier.s
index 759d6df5e545c..e305743ddbf39 100644
--- a/llvm/test/MC/CSKY/relocation-specifier.s
+++ b/llvm/test/MC/CSKY/relocation-specifier.s
@@ -2,8 +2,8 @@
# RUN: llvm-readelf -rs %t | FileCheck %s --check-prefix=READELF
# READELF: '.rela.data'
-# READELF: R_CKCORE_GOT32 00000000 .data + 0
-# READELF: R_CKCORE_PLT32 00000000 .data + 0
+# READELF: R_CKCORE_GOT32 00000000 local + 0
+# READELF: R_CKCORE_PLT32 00000000 local + 0
# READELF: TLS GLOBAL DEFAULT UND gd
# READELF: TLS GLOBAL DEFAULT UND ld
More information about the llvm-commits
mailing list