[llvm] [AArch64] Transition from MCSymbolRefExpr::VariantKind constants (PR #133214)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 26 23:25:44 PDT 2025
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/133214
Shift ELF `@plt` and `@gotpcrel` references in data directives, as well as
Mach-O `@specifier` notations, to use `AArch64MCExpr::Specifier` constants.
This is a follow-up to #132595. COFF-specific specifiers are not moved
yet.
In addition, partition @-specifiers into COFF, ELF, and Mach-O, so that
mix-and-match is rejected at parse time.
ELF and Mach-O specifiers are distinct, with `None` being the only
shared value. For Mach-O-specific specifiers, we adopt the `M_xxx` naming
convention.
>From a4afa71d0449c442c349f06a86aeb5ca64d8a3a4 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 26 Mar 2025 23:25:35 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.5-bogner
---
.../CodeGen/TargetLoweringObjectFileImpl.h | 2 +-
llvm/include/llvm/MC/MCAsmInfo.h | 5 +-
llvm/include/llvm/MC/MCExpr.h | 7 --
.../lib/Target/AArch64/AArch64MCInstLower.cpp | 17 +++--
.../AArch64/AArch64TargetObjectFile.cpp | 9 ++-
.../Target/AArch64/AArch64TargetObjectFile.h | 5 --
.../AArch64/AsmParser/AArch64AsmParser.cpp | 73 ++++++++++---------
.../AArch64ExternalSymbolizer.cpp | 21 +++---
.../MCTargetDesc/AArch64ELFObjectWriter.cpp | 21 +++---
.../AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp | 40 ++++++----
.../AArch64/MCTargetDesc/AArch64MCExpr.h | 22 ++++++
.../MCTargetDesc/AArch64MachObjectWriter.cpp | 24 +++---
.../AArch64WinCOFFObjectWriter.cpp | 4 +-
llvm/test/MC/AArch64/coff-relocations.s | 7 ++
.../MC/AArch64/data-directive-specifier.s | 8 ++
15 files changed, 152 insertions(+), 113 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 76571690eeda0..8e321591b7190 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -37,7 +37,7 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
SmallPtrSet<GlobalObject *, 2> Used;
protected:
- uint8_t PLTRelativeSpecifier = 0;
+ uint16_t PLTRelativeSpecifier = 0;
public:
TargetLoweringObjectFileELF();
diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h
index d7beebf614516..2d5e9a51688aa 100644
--- a/llvm/include/llvm/MC/MCAsmInfo.h
+++ b/llvm/include/llvm/MC/MCAsmInfo.h
@@ -65,10 +65,13 @@ class MCAsmInfo {
/// quote, e.g., `'A`.
};
- struct VariantKindDesc {
+ // This describes a @ style relocation specifier (expr at specifier) supported by
+ // AsmParser::parsePrimaryExpr.
+ struct AtSpecifier {
uint32_t Kind;
StringRef Name;
};
+ using VariantKindDesc = AtSpecifier;
protected:
//===------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h
index 5bfbd2d9f8e71..83e122c6b38b4 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -199,13 +199,6 @@ class MCSymbolRefExpr : public MCExpr {
VK_GOT,
VK_GOTPCREL,
VK_PLT,
- VK_TLVP, // Mach-O thread local variable relocations
- VK_TLVPPAGE,
- VK_TLVPPAGEOFF,
- VK_PAGE,
- VK_PAGEOFF,
- VK_GOTPAGE,
- VK_GOTPAGEOFF,
VK_SECREL,
VK_WEAKREF, // The link between the symbols in .weakref foo, bar
diff --git a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
index 6a02a75ddbb4d..165b7d8ad6330 100644
--- a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
@@ -151,31 +151,32 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandMachO(const MachineOperand &MO,
MCSymbol *Sym) const {
// FIXME: We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing.
- MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
+ auto Spec = AArch64MCExpr::None;
if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) {
if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
- RefKind = MCSymbolRefExpr::VK_GOTPAGE;
+ Spec = AArch64MCExpr::M_GOTPAGE;
else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
AArch64II::MO_PAGEOFF)
- RefKind = MCSymbolRefExpr::VK_GOTPAGEOFF;
+ Spec = AArch64MCExpr::M_GOTPAGEOFF;
else
llvm_unreachable("Unexpected target flags with MO_GOT on GV operand");
} else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) {
if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
- RefKind = MCSymbolRefExpr::VK_TLVPPAGE;
+ Spec = AArch64MCExpr::M_TLVPPAGE;
else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
AArch64II::MO_PAGEOFF)
- RefKind = MCSymbolRefExpr::VK_TLVPPAGEOFF;
+ Spec = AArch64MCExpr::M_TLVPPAGEOFF;
else
llvm_unreachable("Unexpected target flags with MO_TLS on GV operand");
} else {
if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
- RefKind = MCSymbolRefExpr::VK_PAGE;
+ Spec = AArch64MCExpr::M_PAGE;
else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
AArch64II::MO_PAGEOFF)
- RefKind = MCSymbolRefExpr::VK_PAGEOFF;
+ Spec = AArch64MCExpr::M_PAGEOFF;
}
- const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
+ // TODO: Migrate to AArch64MCExpr::create like ELF.
+ const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Spec, Ctx);
if (!MO.isJTI() && MO.getOffset())
Expr = MCBinaryExpr::createAdd(
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index b662e75741d38..2649b060c6c9d 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -25,6 +25,9 @@ using namespace dwarf;
void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
+ PLTRelativeSpecifier = AArch64MCExpr::VK_PLT;
+ SupportIndirectSymViaGOTPCRel = true;
+
// AARCH64 ELF ABI does not define static relocation type for TLS offset
// within a module. Do not generate AT_location for TLS variables.
SupportDebugThreadLocalLocation = false;
@@ -58,7 +61,7 @@ const MCExpr *AArch64_ELFTargetObjectFile::getIndirectSymViaGOTPCRel(
int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
int64_t FinalOffset = Offset + MV.getConstant();
const MCExpr *Res =
- MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext());
+ MCSymbolRefExpr::create(Sym, AArch64MCExpr::VK_GOTPCREL, getContext());
const MCExpr *Off = MCConstantExpr::create(FinalOffset, getContext());
return MCBinaryExpr::createAdd(Res, Off, getContext());
}
@@ -77,7 +80,7 @@ const MCExpr *AArch64_MachoTargetObjectFile::getTTypeGlobalReference(
if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) {
const MCSymbol *Sym = TM.getSymbol(GV);
const MCExpr *Res =
- MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOT, getContext());
+ MCSymbolRefExpr::create(Sym, AArch64MCExpr::M_GOT, getContext());
MCSymbol *PCSym = getContext().createTempSymbol();
Streamer.emitLabel(PCSym);
const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext());
@@ -102,7 +105,7 @@ const MCExpr *AArch64_MachoTargetObjectFile::getIndirectSymViaGOTPCRel(
// On ARM64 Darwin, we can reference symbols with foo at GOT-., which
// is an indirect pc-relative reference.
const MCExpr *Res =
- MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOT, getContext());
+ MCSymbolRefExpr::create(Sym, AArch64MCExpr::VK_GOT, getContext());
MCSymbol *PCSym = getContext().createTempSymbol();
Streamer.emitLabel(PCSym);
const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext());
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
index de79acd229873..6b3381452c70b 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
@@ -20,11 +20,6 @@ class AArch64_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
public:
- AArch64_ELFTargetObjectFile() {
- PLTRelativeSpecifier = MCSymbolRefExpr::VK_PLT;
- SupportIndirectSymViaGOTPCRel = true;
- }
-
const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
const MCSymbol *Sym,
const MCValue &MV, int64_t Offset,
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 5be4bd9ec6b26..0caa1c997ccc6 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -339,7 +339,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
static bool classifySymbolRef(const MCExpr *Expr,
AArch64MCExpr::Specifier &ELFSpec,
- MCSymbolRefExpr::VariantKind &DarwinRefKind,
+ AArch64MCExpr::Specifier &DarwinSpec,
int64_t &Addend);
};
@@ -889,16 +889,16 @@ class AArch64Operand : public MCParsedAsmOperand {
bool isSymbolicUImm12Offset(const MCExpr *Expr) const {
AArch64MCExpr::Specifier ELFSpec;
- MCSymbolRefExpr::VariantKind DarwinRefKind;
+ AArch64MCExpr::Specifier DarwinSpec;
int64_t Addend;
- if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinRefKind,
+ if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
Addend)) {
// If we don't understand the expression, assume the best and
// let the fixup and relocation code deal with it.
return true;
}
- if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
+ if (DarwinSpec == AArch64MCExpr::M_PAGEOFF ||
llvm::is_contained(
{AArch64MCExpr::VK_LO12, AArch64MCExpr::VK_GOT_LO12,
AArch64MCExpr::VK_GOT_AUTH_LO12, AArch64MCExpr::VK_DTPREL_LO12,
@@ -912,8 +912,8 @@ class AArch64Operand : public MCParsedAsmOperand {
// size when converted, so there is no "out of range" condition when using
// @pageoff.
return true;
- } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
- DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
+ } else if (DarwinSpec == AArch64MCExpr::M_GOTPAGEOFF ||
+ DarwinSpec == AArch64MCExpr::M_TLVPPAGEOFF) {
// @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
return Addend == 0;
}
@@ -1006,13 +1006,13 @@ class AArch64Operand : public MCParsedAsmOperand {
}
AArch64MCExpr::Specifier ELFSpec;
- MCSymbolRefExpr::VariantKind DarwinRefKind;
+ AArch64MCExpr::Specifier DarwinSpec;
int64_t Addend;
- if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinRefKind,
+ if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
Addend)) {
- return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
- DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF ||
- (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0) ||
+ return DarwinSpec == AArch64MCExpr::M_PAGEOFF ||
+ DarwinSpec == AArch64MCExpr::M_TLVPPAGEOFF ||
+ (DarwinSpec == AArch64MCExpr::M_GOTPAGEOFF && Addend == 0) ||
llvm::is_contained(
{AArch64MCExpr::VK_LO12, AArch64MCExpr::VK_GOT_AUTH_LO12,
AArch64MCExpr::VK_DTPREL_HI12, AArch64MCExpr::VK_DTPREL_LO12,
@@ -1120,13 +1120,13 @@ class AArch64Operand : public MCParsedAsmOperand {
return false;
AArch64MCExpr::Specifier ELFSpec;
- MCSymbolRefExpr::VariantKind DarwinRefKind;
+ AArch64MCExpr::Specifier DarwinSpec;
int64_t Addend;
- if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFSpec, DarwinRefKind,
+ if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFSpec, DarwinSpec,
Addend)) {
return false;
}
- if (DarwinRefKind != MCSymbolRefExpr::VK_None)
+ if (DarwinSpec != AArch64MCExpr::None)
return false;
return llvm::is_contained(AllowedModifiers, ELFSpec);
@@ -3297,22 +3297,22 @@ ParseStatus AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
return ParseStatus::Failure;
AArch64MCExpr::Specifier ELFSpec;
- MCSymbolRefExpr::VariantKind DarwinRefKind;
+ AArch64MCExpr::Specifier DarwinSpec;
int64_t Addend;
- if (classifySymbolRef(Expr, ELFSpec, DarwinRefKind, Addend)) {
- if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
+ if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
+ if (DarwinSpec == AArch64MCExpr::None &&
ELFSpec == AArch64MCExpr::VK_INVALID) {
// No modifier was specified at all; this is the syntax for an ELF basic
// ADRP relocation (unfortunately).
Expr =
AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext());
- } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
- DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
+ } else if ((DarwinSpec == AArch64MCExpr::M_GOTPAGE ||
+ DarwinSpec == AArch64MCExpr::M_TLVPPAGE) &&
Addend != 0) {
return Error(S, "gotpage label reference not allowed an addend");
- } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
- DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
- DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
+ } else if (DarwinSpec != AArch64MCExpr::M_PAGE &&
+ DarwinSpec != AArch64MCExpr::M_GOTPAGE &&
+ DarwinSpec != AArch64MCExpr::M_TLVPPAGE &&
ELFSpec != AArch64MCExpr::VK_ABS_PAGE_NC &&
ELFSpec != AArch64MCExpr::VK_GOT_PAGE &&
ELFSpec != AArch64MCExpr::VK_GOT_AUTH_PAGE &&
@@ -3351,10 +3351,10 @@ ParseStatus AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
return ParseStatus::Failure;
AArch64MCExpr::Specifier ELFSpec;
- MCSymbolRefExpr::VariantKind DarwinRefKind;
+ AArch64MCExpr::Specifier DarwinSpec;
int64_t Addend;
- if (classifySymbolRef(Expr, ELFSpec, DarwinRefKind, Addend)) {
- if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
+ if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
+ if (DarwinSpec == AArch64MCExpr::None &&
ELFSpec == AArch64MCExpr::VK_INVALID) {
// No modifier was specified at all; this is the syntax for an ELF basic
// ADR relocation (unfortunately).
@@ -5817,13 +5817,13 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
if (Inst.getOperand(2).isExpr()) {
const MCExpr *Expr = Inst.getOperand(2).getExpr();
AArch64MCExpr::Specifier ELFSpec;
- MCSymbolRefExpr::VariantKind DarwinRefKind;
+ AArch64MCExpr::Specifier DarwinSpec;
int64_t Addend;
- if (classifySymbolRef(Expr, ELFSpec, DarwinRefKind, Addend)) {
+ if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
// Only allow these with ADDXri.
- if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
- DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
+ if ((DarwinSpec == AArch64MCExpr::M_PAGEOFF ||
+ DarwinSpec == AArch64MCExpr::M_TLVPPAGEOFF) &&
Inst.getOpcode() == AArch64::ADDXri)
return false;
@@ -8192,11 +8192,12 @@ bool AArch64AsmParser::parseAuthExpr(const MCExpr *&Res, SMLoc &EndLoc) {
return false;
}
-bool AArch64AsmParser::classifySymbolRef(
- const MCExpr *Expr, AArch64MCExpr::Specifier &ELFSpec,
- MCSymbolRefExpr::VariantKind &DarwinRefKind, int64_t &Addend) {
+bool AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
+ AArch64MCExpr::Specifier &ELFSpec,
+ AArch64MCExpr::Specifier &DarwinSpec,
+ int64_t &Addend) {
ELFSpec = AArch64MCExpr::VK_INVALID;
- DarwinRefKind = MCSymbolRefExpr::VK_None;
+ DarwinSpec = AArch64MCExpr::None;
Addend = 0;
if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
@@ -8207,7 +8208,7 @@ bool AArch64AsmParser::classifySymbolRef(
const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
if (SE) {
// It's a simple symbol reference with no addend.
- DarwinRefKind = SE->getKind();
+ DarwinSpec = AArch64MCExpr::Specifier(SE->getKind());
return true;
}
@@ -8223,13 +8224,13 @@ bool AArch64AsmParser::classifySymbolRef(
return false;
if (Res.getSymA())
- DarwinRefKind = Res.getSymA()->getKind();
+ DarwinSpec = AArch64MCExpr::Specifier(Res.getSymA()->getKind());
Addend = Res.getConstant();
// It's some symbol reference + a constant addend, but really
// shouldn't use both Darwin and ELF syntax.
return ELFSpec == AArch64MCExpr::VK_INVALID ||
- DarwinRefKind == MCSymbolRefExpr::VK_None;
+ DarwinSpec == AArch64MCExpr::None;
}
/// Force static initialization.
diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.cpp
index 09d706f0a303b..a9f237a5e6d1b 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "AArch64ExternalSymbolizer.h"
+#include "MCTargetDesc/AArch64MCExpr.h"
#include "Utils/AArch64BaseInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@@ -19,23 +20,23 @@ using namespace llvm;
#define DEBUG_TYPE "aarch64-disassembler"
-static MCSymbolRefExpr::VariantKind
+static AArch64MCExpr::Specifier
getVariant(uint64_t LLVMDisassembler_VariantKind) {
switch (LLVMDisassembler_VariantKind) {
case LLVMDisassembler_VariantKind_None:
- return MCSymbolRefExpr::VK_None;
+ return AArch64MCExpr::None;
case LLVMDisassembler_VariantKind_ARM64_PAGE:
- return MCSymbolRefExpr::VK_PAGE;
+ return AArch64MCExpr::VK_PAGE;
case LLVMDisassembler_VariantKind_ARM64_PAGEOFF:
- return MCSymbolRefExpr::VK_PAGEOFF;
+ return AArch64MCExpr::VK_PAGEOFF;
case LLVMDisassembler_VariantKind_ARM64_GOTPAGE:
- return MCSymbolRefExpr::VK_GOTPAGE;
+ return AArch64MCExpr::M_GOTPAGE;
case LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF:
- return MCSymbolRefExpr::VK_GOTPAGEOFF;
+ return AArch64MCExpr::M_GOTPAGEOFF;
case LLVMDisassembler_VariantKind_ARM64_TLVP:
- return MCSymbolRefExpr::VK_TLVPPAGE;
+ return AArch64MCExpr::M_TLVPPAGE;
case LLVMDisassembler_VariantKind_ARM64_TLVOFF:
- return MCSymbolRefExpr::VK_TLVPPAGEOFF;
+ return AArch64MCExpr::M_TLVPPAGEOFF;
default:
llvm_unreachable("bad LLVMDisassembler_VariantKind");
}
@@ -170,8 +171,8 @@ bool AArch64ExternalSymbolizer::tryAddingSymbolicOperand(
if (SymbolicOp.AddSymbol.Name) {
StringRef Name(SymbolicOp.AddSymbol.Name);
MCSymbol *Sym = Ctx.getOrCreateSymbol(Name);
- MCSymbolRefExpr::VariantKind Variant = getVariant(SymbolicOp.VariantKind);
- if (Variant != MCSymbolRefExpr::VK_None)
+ auto Variant = getVariant(SymbolicOp.VariantKind);
+ if (Variant != AArch64MCExpr::None)
Add = MCSymbolRefExpr::create(Sym, Variant, Ctx);
else
Add = MCSymbolRefExpr::create(Sym, Ctx);
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index a509edf160d32..fa72cbf032cdf 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -117,13 +117,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
assert((!Target.getSymA() ||
- Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
- Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
- Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
- "Should only be expression-level modifiers here");
-
- assert((!Target.getSymB() ||
- Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) &&
+ getSpecifier(Target.getSymA()) == AArch64MCExpr::None ||
+ getSpecifier(Target.getSymA()) == AArch64MCExpr::VK_PLT ||
+ getSpecifier(Target.getSymA()) == AArch64MCExpr::VK_GOTPCREL) &&
"Should only be expression-level modifiers here");
switch (SymLoc) {
@@ -147,7 +143,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
case FK_Data_2:
return R_CLS(PREL16);
case FK_Data_4: {
- return Target.getAccessVariant() == MCSymbolRefExpr::VK_PLT
+ return AArch64MCExpr::Specifier(Target.getAccessVariant()) ==
+ AArch64MCExpr::VK_PLT
? R_CLS(PLT32)
: R_CLS(PREL32);
}
@@ -258,8 +255,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
case FK_Data_2:
return R_CLS(ABS16);
case FK_Data_4:
- return (!IsILP32 &&
- Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL)
+ return (!IsILP32 && AArch64MCExpr::Specifier(Target.getAccessVariant()) ==
+ AArch64MCExpr::VK_GOTPCREL)
? ELF::R_AARCH64_GOTPCREL32
: R_CLS(ABS32);
case FK_Data_8: {
@@ -554,8 +551,8 @@ bool AArch64ELFObjectWriter::needsRelocateWithSymbol(const MCValue &Val,
if ((Val.getRefKind() & AArch64MCExpr::VK_GOT) == AArch64MCExpr::VK_GOT)
return true;
- return is_contained({MCSymbolRefExpr::VK_GOTPCREL, MCSymbolRefExpr::VK_PLT},
- Val.getAccessVariant());
+ return is_contained({AArch64MCExpr::VK_GOTPCREL, AArch64MCExpr::VK_PLT},
+ AArch64MCExpr::Specifier(Val.getAccessVariant()));
}
std::unique_ptr<MCObjectTargetWriter>
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
index 9ff53631a995e..e550575a3d1cf 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "AArch64MCAsmInfo.h"
+#include "MCTargetDesc/AArch64MCExpr.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
@@ -30,21 +31,28 @@ static cl::opt<AsmWriterVariantTy> AsmWriterVariant(
cl::values(clEnumValN(Generic, "generic", "Emit generic NEON assembly"),
clEnumValN(Apple, "apple", "Emit Apple-style NEON assembly")));
-const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
+const MCAsmInfo::AtSpecifier COFFAtSpecifiers[] = {
{MCSymbolRefExpr::VK_COFF_IMGREL32, "IMGREL"},
- {MCSymbolRefExpr::VK_GOT, "GOT"},
- {MCSymbolRefExpr::VK_GOTPAGE, "GOTPAGE"},
- {MCSymbolRefExpr::VK_GOTPAGEOFF, "GOTPAGEOFF"},
- {MCSymbolRefExpr::VK_GOTPCREL, "GOTPCREL"},
- {MCSymbolRefExpr::VK_PAGE, "PAGE"},
- {MCSymbolRefExpr::VK_PAGEOFF, "PAGEOFF"},
- {MCSymbolRefExpr::VK_PLT, "PLT"},
- {MCSymbolRefExpr::VK_TLVP, "TLVP"},
- {MCSymbolRefExpr::VK_TLVPPAGE, "TLVPPAGE"},
- {MCSymbolRefExpr::VK_TLVPPAGEOFF, "TLVPPAGEOFF"},
{MCSymbolRefExpr::VK_WEAKREF, "WEAKREF"},
};
+const MCAsmInfo::AtSpecifier ELFAtSpecifiers[] = {
+ {AArch64MCExpr::VK_GOT, "GOT"},
+ {AArch64MCExpr::VK_GOTPCREL, "GOTPCREL"},
+ {AArch64MCExpr::VK_PLT, "PLT"},
+};
+
+const MCAsmInfo::AtSpecifier MachOAtSpecifiers[] = {
+ {AArch64MCExpr::M_GOT, "GOT"},
+ {AArch64MCExpr::M_GOTPAGE, "GOTPAGE"},
+ {AArch64MCExpr::M_GOTPAGEOFF, "GOTPAGEOFF"},
+ {AArch64MCExpr::M_PAGE, "PAGE"},
+ {AArch64MCExpr::M_PAGEOFF, "PAGEOFF"},
+ {AArch64MCExpr::M_TLVP, "TLVP"},
+ {AArch64MCExpr::M_TLVPPAGE, "TLVPPAGE"},
+ {AArch64MCExpr::M_TLVPPAGEOFF, "TLVPPAGEOFF"},
+};
+
AArch64MCAsmInfoDarwin::AArch64MCAsmInfoDarwin(bool IsILP32) {
// We prefer NEON instructions to be printed in the short, Apple-specific
// form when targeting Darwin.
@@ -64,7 +72,7 @@ AArch64MCAsmInfoDarwin::AArch64MCAsmInfoDarwin(bool IsILP32) {
ExceptionsType = ExceptionHandling::DwarfCFI;
- initializeVariantKinds(variantKindDescs);
+ initializeVariantKinds(MachOAtSpecifiers);
}
const MCExpr *AArch64MCAsmInfoDarwin::getExprForPersonalitySymbol(
@@ -75,7 +83,7 @@ const MCExpr *AArch64MCAsmInfoDarwin::getExprForPersonalitySymbol(
// version.
MCContext &Context = Streamer.getContext();
const MCExpr *Res =
- MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOT, Context);
+ MCSymbolRefExpr::create(Sym, AArch64MCExpr::VK_GOT, Context);
MCSymbol *PCSym = Context.createTempSymbol();
Streamer.emitLabel(PCSym);
const MCExpr *PC = MCSymbolRefExpr::create(PCSym, Context);
@@ -115,7 +123,7 @@ AArch64MCAsmInfoELF::AArch64MCAsmInfoELF(const Triple &T) {
HasIdentDirective = true;
- initializeVariantKinds(variantKindDescs);
+ initializeVariantKinds(ELFAtSpecifiers);
}
AArch64MCAsmInfoMicrosoftCOFF::AArch64MCAsmInfoMicrosoftCOFF() {
@@ -134,7 +142,7 @@ AArch64MCAsmInfoMicrosoftCOFF::AArch64MCAsmInfoMicrosoftCOFF() {
ExceptionsType = ExceptionHandling::WinEH;
WinEHEncodingType = WinEH::EncodingType::Itanium;
- initializeVariantKinds(variantKindDescs);
+ initializeVariantKinds(COFFAtSpecifiers);
}
AArch64MCAsmInfoGNUCOFF::AArch64MCAsmInfoGNUCOFF() {
@@ -153,5 +161,5 @@ AArch64MCAsmInfoGNUCOFF::AArch64MCAsmInfoGNUCOFF() {
ExceptionsType = ExceptionHandling::WinEH;
WinEHEncodingType = WinEH::EncodingType::Itanium;
- initializeVariantKinds(variantKindDescs);
+ initializeVariantKinds(COFFAtSpecifiers);
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
index 50abaa9861538..3128f9d10a4bc 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
@@ -25,6 +25,7 @@ class AArch64MCExpr : public MCTargetExpr {
public:
enum Specifier : uint16_t {
// clang-format off
+ None = 0,
// Symbol locations specifying (roughly speaking) what calculation should be
// performed to construct the final address for the relocated
// symbol. E.g. direct, via the GOT, ...
@@ -120,6 +121,20 @@ class AArch64MCExpr : public MCTargetExpr {
VK_SECREL_LO12 = VK_SECREL | VK_PAGEOFF,
VK_SECREL_HI12 = VK_SECREL | VK_HI12,
+ // ELF relocation specifiers in data directives:
+ VK_PLT = 0x400,
+ VK_GOTPCREL,
+
+ // Mach-O @ relocation specifiers:
+ M_GOT,
+ M_GOTPAGE,
+ M_GOTPAGEOFF,
+ M_PAGE,
+ M_PAGEOFF,
+ M_TLVP,
+ M_TLVPPAGE,
+ M_TLVPPAGEOFF,
+
VK_INVALID = 0xfff
// clang-format on
};
@@ -214,6 +229,13 @@ class AArch64AuthMCExpr final : public AArch64MCExpr {
return E->getSpecifier() == VK_AUTH || E->getSpecifier() == VK_AUTHADDR;
}
};
+
+// Getter for the legacy representation that encodes the relocation specifier in
+// MCSymbolRefExpr::SubclassData.
+static inline AArch64MCExpr::Specifier
+getSpecifier(const MCSymbolRefExpr *SRE) {
+ return AArch64MCExpr::Specifier(SRE->getKind());
+}
} // end namespace llvm
#endif
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
index 3deee6548f279..c3a6174131806 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
@@ -66,12 +66,12 @@ bool AArch64MachObjectWriter::getAArch64FixupKindMachOInfo(
return true;
case FK_Data_4:
Log2Size = Log2_32(4);
- if (Sym->getKind() == MCSymbolRefExpr::VK_GOT)
+ if (getSpecifier(Sym) == AArch64MCExpr::M_GOT)
RelocType = unsigned(MachO::ARM64_RELOC_POINTER_TO_GOT);
return true;
case FK_Data_8:
Log2Size = Log2_32(8);
- if (Sym->getKind() == MCSymbolRefExpr::VK_GOT)
+ if (getSpecifier(Sym) == AArch64MCExpr::M_GOT)
RelocType = unsigned(MachO::ARM64_RELOC_POINTER_TO_GOT);
return true;
case AArch64::fixup_aarch64_add_imm12:
@@ -81,34 +81,34 @@ bool AArch64MachObjectWriter::getAArch64FixupKindMachOInfo(
case AArch64::fixup_aarch64_ldst_imm12_scale8:
case AArch64::fixup_aarch64_ldst_imm12_scale16:
Log2Size = Log2_32(4);
- switch (Sym->getKind()) {
+ switch (AArch64MCExpr::Specifier(getSpecifier(Sym))) {
default:
return false;
- case MCSymbolRefExpr::VK_PAGEOFF:
+ case AArch64MCExpr::M_PAGEOFF:
RelocType = unsigned(MachO::ARM64_RELOC_PAGEOFF12);
return true;
- case MCSymbolRefExpr::VK_GOTPAGEOFF:
+ case AArch64MCExpr::M_GOTPAGEOFF:
RelocType = unsigned(MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12);
return true;
- case MCSymbolRefExpr::VK_TLVPPAGEOFF:
+ case AArch64MCExpr::M_TLVPPAGEOFF:
RelocType = unsigned(MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12);
return true;
}
case AArch64::fixup_aarch64_pcrel_adrp_imm21:
Log2Size = Log2_32(4);
// This encompasses the relocation for the whole 21-bit value.
- switch (Sym->getKind()) {
+ switch (getSpecifier(Sym)) {
default:
Asm.getContext().reportError(Fixup.getLoc(),
"ADR/ADRP relocations must be GOT relative");
return false;
- case MCSymbolRefExpr::VK_PAGE:
+ case AArch64MCExpr::M_PAGE:
RelocType = unsigned(MachO::ARM64_RELOC_PAGE21);
return true;
- case MCSymbolRefExpr::VK_GOTPAGE:
+ case AArch64MCExpr::M_GOTPAGE:
RelocType = unsigned(MachO::ARM64_RELOC_GOT_LOAD_PAGE21);
return true;
- case MCSymbolRefExpr::VK_TLVPPAGE:
+ case AArch64MCExpr::M_TLVPPAGE:
RelocType = unsigned(MachO::ARM64_RELOC_TLVP_LOAD_PAGE21);
return true;
}
@@ -221,7 +221,7 @@ void AArch64MachObjectWriter::recordRelocation(
// Check for "_foo at got - .", which comes through here as:
// Ltmp0:
// ... _foo at got - Ltmp0
- if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOT &&
+ if (getSpecifier(Target.getSymA()) == AArch64MCExpr::M_GOT &&
Asm.getSymbolOffset(*B) ==
Asm.getFragmentOffset(*Fragment) + Fixup.getOffset()) {
// SymB is the PC, so use a PC-rel pointer-to-GOT relocation.
@@ -232,7 +232,7 @@ void AArch64MachObjectWriter::recordRelocation(
MRE.r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
Writer->addRelocation(A_Base, Fragment->getParent(), MRE);
return;
- } else if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None) {
+ } else if (getSpecifier(Target.getSymA()) != AArch64MCExpr::None) {
// Otherwise, neither symbol can be modified.
Asm.getContext().reportError(Fixup.getLoc(),
"unsupported relocation of modified symbol");
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp
index 4213edafa9a0f..d679f5f621e0a 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp
@@ -61,8 +61,8 @@ unsigned AArch64WinCOFFObjectWriter::getRelocType(
FixupKind = FK_PCRel_4;
}
- auto Modifier = Target.isAbsolute() ? MCSymbolRefExpr::VK_None
- : Target.getSymA()->getKind();
+ auto Modifier =
+ Target.isAbsolute() ? AArch64MCExpr::None : Target.getSymA()->getKind();
const MCExpr *Expr = Fixup.getValue();
if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
diff --git a/llvm/test/MC/AArch64/coff-relocations.s b/llvm/test/MC/AArch64/coff-relocations.s
index 2370fd9fb4365..f7e15081470f6 100644
--- a/llvm/test/MC/AArch64/coff-relocations.s
+++ b/llvm/test/MC/AArch64/coff-relocations.s
@@ -7,6 +7,8 @@
// RUN: llvm-objdump -s %t.obj | FileCheck %s --check-prefix=DATA
// RUN: llvm-objdump -s %t-ec.obj | FileCheck %s --check-prefix=DATA
+# RUN: not llvm-mc -triple=aarch64-windows -filetype=obj %s --defsym PARSEERR=1 -o /dev/null 2>&1 | FileCheck %s --check-prefix=PARSEERR --implicit-check-not=error:
+
// IMAGE_REL_ARM64_ADDR32
.Linfo_foo:
.asciz "foo"
@@ -121,3 +123,8 @@ tbz x0, #0, target
// DATA: Contents of section .rdata:
// DATA-NEXT: 0000 30000000 08000000
+
+.ifdef PARSEERR
+# PARSEERR: [[#@LINE+1]]:12: error: invalid variant 'plt'
+.long func at plt
+.endif
diff --git a/llvm/test/MC/AArch64/data-directive-specifier.s b/llvm/test/MC/AArch64/data-directive-specifier.s
index 3a8665126097a..b10423345b503 100644
--- a/llvm/test/MC/AArch64/data-directive-specifier.s
+++ b/llvm/test/MC/AArch64/data-directive-specifier.s
@@ -1,4 +1,5 @@
# RUN: llvm-mc -triple=aarch64 -filetype=obj %s | llvm-readobj -r - | FileCheck %s
+# RUN: not llvm-mc -triple=aarch64 -filetype=obj %s --defsym PARSEERR=1 -o /dev/null 2>&1 | FileCheck %s --check-prefix=PARSEERR --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
@@ -31,6 +32,13 @@ data1:
.word extern at gotpcrel+4
.word extern at GOTPCREL-5
+## Test parse-time errors
+.ifdef PARSEERR
+# PARSEERR: [[#@LINE+1]]:14: error: invalid variant 'pageoff'
+.word extern at pageoff
+.endif
+
+## Test assemble-time errors
.ifdef ERR
# ERR: [[#@LINE+1]]:7: error: symbol 'und' can not be undefined in a subtraction expression
.word extern at plt - und
More information about the llvm-commits
mailing list