diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 8b0e5798d1b6..af8d73b4fa06 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -37,7 +37,7 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { SmallPtrSet Used; protected: - uint8_t PLTRelativeSpecifier = 0; + uint16_t PLTRelativeSpecifier = 0; public: ~TargetLoweringObjectFileELF() override = default; diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h index 6714abac5c72..ec27a47e3682 100644 --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -65,10 +65,13 @@ public: /// quote, e.g., `'A`. }; - struct VariantKindDesc { + // This describes a @ style relocation specifier (expr@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 12830ee648ae..782f7ea8957d 100644 --- a/llvm/include/llvm/MC/MCExpr.h +++ b/llvm/include/llvm/MC/MCExpr.h @@ -198,14 +198,6 @@ public: 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 6a02a75ddbb4..165b7d8ad633 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 b662e75741d3..b9ba2a41877e 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@GOT-., which // is an indirect pc-relative reference. 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()); diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h index de79acd22987..6b3381452c70 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 28b4cbb5efed..38710e934468 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -339,7 +339,7 @@ public: static bool classifySymbolRef(const MCExpr *Expr, AArch64MCExpr::Specifier &ELFSpec, - MCSymbolRefExpr::VariantKind &DarwinRefKind, + AArch64MCExpr::Specifier &DarwinSpec, int64_t &Addend); }; @@ -889,16 +889,16 @@ public: 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 @@ public: // 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 @@ public: } 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 @@ public: 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(Expr)) { @@ -8207,7 +8208,7 @@ bool AArch64AsmParser::classifySymbolRef( const MCSymbolRefExpr *SE = dyn_cast(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 09d706f0a303..8b65f856b2a6 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 -getVariant(uint64_t LLVMDisassembler_VariantKind) { +static AArch64MCExpr::Specifier +getMachOSpecifier(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::M_PAGE; case LLVMDisassembler_VariantKind_ARM64_PAGEOFF: - return MCSymbolRefExpr::VK_PAGEOFF; + return AArch64MCExpr::M_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,9 +171,9 @@ 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) - Add = MCSymbolRefExpr::create(Sym, Variant, Ctx); + auto Spec = getMachOSpecifier(SymbolicOp.VariantKind); + if (Spec != AArch64MCExpr::None) + Add = MCSymbolRefExpr::create(Sym, Spec, Ctx); else Add = MCSymbolRefExpr::create(Sym, Ctx); } else { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp index a509edf160d3..fa72cbf032cd 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 diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp index 9ff53631a995..8cffd9ce557d 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,19 +31,27 @@ static cl::opt 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"}, + {AArch64MCExpr::M_PAGEOFF, "PAGEOFF"}, +}; + +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) { @@ -64,7 +73,7 @@ AArch64MCAsmInfoDarwin::AArch64MCAsmInfoDarwin(bool IsILP32) { ExceptionsType = ExceptionHandling::DwarfCFI; - initializeVariantKinds(variantKindDescs); + initializeVariantKinds(MachOAtSpecifiers); } const MCExpr *AArch64MCAsmInfoDarwin::getExprForPersonalitySymbol( @@ -75,7 +84,7 @@ const MCExpr *AArch64MCAsmInfoDarwin::getExprForPersonalitySymbol( // version. MCContext &Context = Streamer.getContext(); const MCExpr *Res = - MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOT, Context); + MCSymbolRefExpr::create(Sym, AArch64MCExpr::M_GOT, Context); MCSymbol *PCSym = Context.createTempSymbol(); Streamer.emitLabel(PCSym); const MCExpr *PC = MCSymbolRefExpr::create(PCSym, Context); @@ -115,7 +124,7 @@ AArch64MCAsmInfoELF::AArch64MCAsmInfoELF(const Triple &T) { HasIdentDirective = true; - initializeVariantKinds(variantKindDescs); + initializeVariantKinds(ELFAtSpecifiers); } AArch64MCAsmInfoMicrosoftCOFF::AArch64MCAsmInfoMicrosoftCOFF() { @@ -134,7 +143,7 @@ AArch64MCAsmInfoMicrosoftCOFF::AArch64MCAsmInfoMicrosoftCOFF() { ExceptionsType = ExceptionHandling::WinEH; WinEHEncodingType = WinEH::EncodingType::Itanium; - initializeVariantKinds(variantKindDescs); + initializeVariantKinds(COFFAtSpecifiers); } AArch64MCAsmInfoGNUCOFF::AArch64MCAsmInfoGNUCOFF() { @@ -153,5 +162,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 50abaa986153..3128f9d10a4b 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 @@ public: 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 @@ public: 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 3deee6548f27..c3a617413180 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@got - .", which comes through here as: // Ltmp0: // ... _foo@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 4213edafa9a0..d679f5f621e0 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(Expr)) { diff --git a/llvm/test/MC/AArch64/coff-relocations.s b/llvm/test/MC/AArch64/coff-relocations.s index 2370fd9fb436..a8a466c8b581 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 ERR=1 -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --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 ERR +# ERR: [[#@LINE+1]]:12: error: invalid variant 'plt' +.long func@plt +.endif diff --git a/llvm/test/MC/AArch64/data-directive-specifier.s b/llvm/test/MC/AArch64/data-directive-specifier.s index 3a8665126097..c4ca5d760b41 100644 --- a/llvm/test/MC/AArch64/data-directive-specifier.s +++ b/llvm/test/MC/AArch64/data-directive-specifier.s @@ -1,5 +1,6 @@ # RUN: llvm-mc -triple=aarch64 -filetype=obj %s | llvm-readobj -r - | FileCheck %s # 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: +# 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: .globl g g: @@ -31,14 +32,21 @@ data1: .word extern@gotpcrel+4 .word extern@GOTPCREL-5 +## Test parse-time errors .ifdef ERR -# ERR: [[#@LINE+1]]:7: error: symbol 'und' can not be undefined in a subtraction expression +# ERR: [[#@LINE+1]]:14: error: invalid variant 'pageoff' +.word extern@pageoff +.endif + +## Test assemble-time errors +.ifdef OBJERR +# OBJERR: [[#@LINE+1]]:7: error: symbol 'und' can not be undefined in a subtraction expression .word extern@plt - und .quad g@plt - . .word extern@gotpcrel - . -# ERR: [[#@LINE+1]]:7: error: symbol 'und' can not be undefined in a subtraction expression +# OBJERR: [[#@LINE+1]]:7: error: symbol 'und' can not be undefined in a subtraction expression .word extern@gotpcrel - und .endif