diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 8672b8dacfd..f58a25d3319 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -306,6 +306,10 @@ namespace llvm { /// instead of symbolic register names in .cfi_* directives. bool DwarfRegNumForCFI; // Defaults to false; + /// UseParensForSymbolVariant - True if target uses parens to indicate the + /// symbol variant instead of @. For example, foo(plt) instead of foo@plt. + bool UseParensForSymbolVariant; // Defaults to false; + //===--- Prologue State ----------------------------------------------===// std::vector InitialFrameState; @@ -530,6 +534,9 @@ namespace llvm { bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; } + bool useParensForSymbolVariant() const { + return UseParensForSymbolVariant; + } void addInitialFrameState(const MCCFIInstruction &Inst) { InitialFrameState.push_back(Inst); diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 5d559744da9..3052de112fa 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -15,6 +15,7 @@ #include "llvm/Support/DataTypes.h" namespace llvm { +class MCAsmInfo; class MCAsmLayout; class MCAssembler; class MCContext; @@ -159,14 +160,8 @@ public: VK_DTPOFF, VK_TLVP, // Mach-O thread local variable relocation VK_SECREL, - // FIXME: We'd really like to use the generic Kinds listed above for these. + VK_ARM_NONE, - VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT - VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF - VK_ARM_GOT, - VK_ARM_GOTOFF, - VK_ARM_TPOFF, - VK_ARM_GOTTPOFF, VK_ARM_TARGET1, VK_ARM_TARGET2, VK_ARM_PREL31, @@ -258,9 +253,14 @@ private: /// The symbol reference modifier. const VariantKind Kind; - explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) - : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) { + /// MCAsmInfo that is used to print symbol variants correctly. + const MCAsmInfo *MAI; + + explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind, + const MCAsmInfo *_MAI) + : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind), MAI(_MAI) { assert(Symbol); + assert(MAI); } public: @@ -281,6 +281,7 @@ public: /// @{ const MCSymbol &getSymbol() const { return *Symbol; } + const MCAsmInfo &getMCAsmInfo() const { return *MAI; } VariantKind getKind() const { return Kind; } diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index 16506fe89e6..4eaf6c2054c 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -88,6 +88,7 @@ MCAsmInfo::MCAsmInfo() { DwarfRegNumForCFI = false; HasMicrosoftFastStdCallMangling = false; NeedsDwarfSectionOffsetDirective = false; + UseParensForSymbolVariant = false; } MCAsmInfo::~MCAsmInfo() { diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index e806cb9f1c9..b6017859480 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -371,9 +371,6 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { case MCSymbolRefExpr::VK_TLSLDM: case MCSymbolRefExpr::VK_TPOFF: case MCSymbolRefExpr::VK_DTPOFF: - case MCSymbolRefExpr::VK_ARM_TLSGD: - case MCSymbolRefExpr::VK_ARM_TPOFF: - case MCSymbolRefExpr::VK_ARM_GOTTPOFF: case MCSymbolRefExpr::VK_Mips_TLSGD: case MCSymbolRefExpr::VK_Mips_GOTTPREL: case MCSymbolRefExpr::VK_Mips_TPREL_HI: diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index c777e648bdc..69cdfa35440 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -11,6 +11,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" @@ -47,19 +48,12 @@ void MCExpr::print(raw_ostream &OS) const { else OS << Sym; - if (SRE.getKind() == MCSymbolRefExpr::VK_ARM_NONE || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_PLT || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_TLSGD || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOT || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTOFF || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_TPOFF || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTTPOFF || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET1 || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET2 || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_PREL31) - OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); - else if (SRE.getKind() != MCSymbolRefExpr::VK_None) - OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); + if (SRE.getKind() != MCSymbolRefExpr::VK_None) { + if (SRE.getMCAsmInfo().useParensForSymbolVariant()) + OS << '(' << MCSymbolRefExpr::getVariantKindName(SRE.getKind()) << ')'; + else + OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); + } return; } @@ -158,7 +152,7 @@ const MCConstantExpr *MCConstantExpr::Create(int64_t Value, MCContext &Ctx) { const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym, VariantKind Kind, MCContext &Ctx) { - return new (Ctx) MCSymbolRefExpr(Sym, Kind); + return new (Ctx) MCSymbolRefExpr(Sym, Kind, Ctx.getAsmInfo()); } const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, VariantKind Kind, @@ -186,16 +180,10 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_DTPOFF: return "DTPOFF"; case VK_TLVP: return "TLVP"; case VK_SECREL: return "SECREL32"; - case VK_ARM_NONE: return "(NONE)"; - case VK_ARM_PLT: return "(PLT)"; - case VK_ARM_GOT: return "(GOT)"; - case VK_ARM_GOTOFF: return "(GOTOFF)"; - case VK_ARM_TPOFF: return "(tpoff)"; - case VK_ARM_GOTTPOFF: return "(gottpoff)"; - case VK_ARM_TLSGD: return "(tlsgd)"; - case VK_ARM_TARGET1: return "(target1)"; - case VK_ARM_TARGET2: return "(target2)"; - case VK_ARM_PREL31: return "(prel31)"; + case VK_ARM_NONE: return "none"; + case VK_ARM_TARGET1: return "target1"; + case VK_ARM_TARGET2: return "target2"; + case VK_ARM_PREL31: return "prel31"; case VK_PPC_LO: return "l"; case VK_PPC_HI: return "h"; case VK_PPC_HA: return "ha"; @@ -409,6 +397,14 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI) .Case("GOT@TLSLD@HA", VK_PPC_GOT_TLSLD_HA) .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA) + .Case("NONE", VK_ARM_NONE) + .Case("none", VK_ARM_NONE) + .Case("TARGET1", VK_ARM_TARGET1) + .Case("target1", VK_ARM_TARGET1) + .Case("TARGET2", VK_ARM_TARGET2) + .Case("target2", VK_ARM_TARGET2) + .Case("PREL31", VK_ARM_PREL31) + .Case("prel31", VK_ARM_PREL31) .Default(VK_Invalid); } diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index a91bd93105b..01fe87e0d66 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -789,20 +789,34 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { return true; } } + // Parse symbol variant + std::pair Split; + if (!MAI.useParensForSymbolVariant()) { + Split = Identifier.split('@'); + } else if (Lexer.is(AsmToken::LParen)) { + Lexer.Lex(); // eat ( + StringRef VName; + parseIdentifier(VName); + if (Lexer.isNot(AsmToken::RParen)) { + return Error(Lexer.getTok().getLoc(), + "unexpected token in variant, expected ')'"); + } + Lexer.Lex(); // eat ) + Split = std::make_pair(Identifier, VName); + } EndLoc = SMLoc::getFromPointer(Identifier.end()); // This is a symbol reference. StringRef SymbolName = Identifier; MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; - std::pair Split = Identifier.split('@'); // Lookup the symbol variant if used. - if (Split.first.size() != Identifier.size()) { + if (Split.second.size()) { Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); if (Variant != MCSymbolRefExpr::VK_Invalid) { SymbolName = Split.first; - } else if (MAI.doesAllowAtInName()) { + } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) { Variant = MCSymbolRefExpr::VK_None; } else { Variant = MCSymbolRefExpr::VK_None; diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 720c9b0111d..8e28a98277d 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -756,11 +756,11 @@ static MCSymbolRefExpr::VariantKind getModifierVariantKind(ARMCP::ARMCPModifier Modifier) { switch (Modifier) { case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; - case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD; - case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF; - case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF; - case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT; - case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF; + case ARMCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; + case ARMCP::TPOFF: return MCSymbolRefExpr::VK_TPOFF; + case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_GOTTPOFF; + case ARMCP::GOT: return MCSymbolRefExpr::VK_GOT; + case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_GOTOFF; } llvm_unreachable("Invalid ARMCPModifier!"); } diff --git a/lib/Target/ARM/ARMMCInstLower.cpp b/lib/Target/ARM/ARMMCInstLower.cpp index 1cc987ce99d..c8306277590 100644 --- a/lib/Target/ARM/ARMMCInstLower.cpp +++ b/lib/Target/ARM/ARMMCInstLower.cpp @@ -50,7 +50,7 @@ MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO, } case ARMII::MO_PLT: - Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, + Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_PLT, OutContext); break; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index f98bbd204c7..72ac6e22e8d 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -166,9 +166,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_None: Type = ELF::R_ARM_REL32; break; - case MCSymbolRefExpr::VK_ARM_TLSGD: + case MCSymbolRefExpr::VK_TLSGD: llvm_unreachable("unimplemented"); - case MCSymbolRefExpr::VK_ARM_GOTTPOFF: + case MCSymbolRefExpr::VK_GOTTPOFF: Type = ELF::R_ARM_TLS_IE32; break; } @@ -176,7 +176,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case ARM::fixup_arm_blx: case ARM::fixup_arm_uncondbl: switch (Modifier) { - case MCSymbolRefExpr::VK_ARM_PLT: + case MCSymbolRefExpr::VK_PLT: Type = ELF::R_ARM_PLT32; break; default: @@ -223,22 +223,22 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_ARM_NONE: Type = ELF::R_ARM_NONE; break; - case MCSymbolRefExpr::VK_ARM_GOT: + case MCSymbolRefExpr::VK_GOT: Type = ELF::R_ARM_GOT_BREL; break; - case MCSymbolRefExpr::VK_ARM_TLSGD: + case MCSymbolRefExpr::VK_TLSGD: Type = ELF::R_ARM_TLS_GD32; break; - case MCSymbolRefExpr::VK_ARM_TPOFF: + case MCSymbolRefExpr::VK_TPOFF: Type = ELF::R_ARM_TLS_LE32; break; - case MCSymbolRefExpr::VK_ARM_GOTTPOFF: + case MCSymbolRefExpr::VK_GOTTPOFF: Type = ELF::R_ARM_TLS_IE32; break; case MCSymbolRefExpr::VK_None: Type = ELF::R_ARM_ABS32; break; - case MCSymbolRefExpr::VK_ARM_GOTOFF: + case MCSymbolRefExpr::VK_GOTOFF: Type = ELF::R_ARM_GOTOFF32; break; case MCSymbolRefExpr::VK_ARM_TARGET1: diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp index 714142123d9..b2a71a87061 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -54,4 +54,7 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo() { // Exceptions handling if (EnableARMEHABI) ExceptionsType = ExceptionHandling::ARM; + + // foo(plt) instead of foo@plt + UseParensForSymbolVariant = true; } diff --git a/test/CodeGen/ARM/tls-models.ll b/test/CodeGen/ARM/tls-models.ll index ccc9032313b..42c1ba91102 100644 --- a/test/CodeGen/ARM/tls-models.ll +++ b/test/CodeGen/ARM/tls-models.ll @@ -22,9 +22,9 @@ entry: ; Non-PIC code can use initial-exec, PIC code has to use general dynamic. ; CHECK-NONPIC-LABEL: f1: - ; CHECK-NONPIC: external_gd(gottpoff) + ; CHECK-NONPIC: external_gd(GOTTPOFF) ; CHECK-PIC-LABEL: f1: - ; CHECK-PIC: external_gd(tlsgd) + ; CHECK-PIC: external_gd(TLSGD) } define i32* @f2() { @@ -34,9 +34,9 @@ entry: ; Non-PIC code can use local exec, PIC code can use local dynamic, ; but that is not implemented, so falls back to general dynamic. ; CHECK-NONPIC-LABEL: f2: - ; CHECK-NONPIC: internal_gd(tpoff) + ; CHECK-NONPIC: internal_gd(TPOFF) ; CHECK-PIC-LABEL: f2: - ; CHECK-PIC: internal_gd(tlsgd) + ; CHECK-PIC: internal_gd(TLSGD) } @@ -49,9 +49,9 @@ entry: ; Non-PIC code can use initial exec, PIC should use local dynamic, ; but that is not implemented, so falls back to general dynamic. ; CHECK-NONPIC-LABEL: f3: - ; CHECK-NONPIC: external_ld(gottpoff) + ; CHECK-NONPIC: external_ld(GOTTPOFF) ; CHECK-PIC-LABEL: f3: - ; CHECK-PIC: external_ld(tlsgd) + ; CHECK-PIC: external_ld(TLSGD) } define i32* @f4() { @@ -61,9 +61,9 @@ entry: ; Non-PIC code can use local exec, PIC code can use local dynamic, ; but that is not implemented, so it falls back to general dynamic. ; CHECK-NONPIC-LABEL: f4: - ; CHECK-NONPIC: internal_ld(tpoff) + ; CHECK-NONPIC: internal_ld(TPOFF) ; CHECK-PIC-LABEL: f4: - ; CHECK-PIC: internal_ld(tlsgd) + ; CHECK-PIC: internal_ld(TLSGD) } @@ -75,9 +75,9 @@ entry: ; Non-PIC and PIC code will use initial exec as specified. ; CHECK-NONPIC-LABEL: f5: - ; CHECK-NONPIC: external_ie(gottpoff) + ; CHECK-NONPIC: external_ie(GOTTPOFF) ; CHECK-PIC-LABEL: f5: - ; CHECK-PIC: external_ie(gottpoff) + ; CHECK-PIC: external_ie(GOTTPOFF) } define i32* @f6() { @@ -86,9 +86,9 @@ entry: ; Non-PIC code can use local exec, PIC code use initial exec as specified. ; CHECK-NONPIC-LABEL: f6: - ; CHECK-NONPIC: internal_ie(tpoff) + ; CHECK-NONPIC: internal_ie(TPOFF) ; CHECK-PIC-LABEL: f6: - ; CHECK-PIC: internal_ie(gottpoff) + ; CHECK-PIC: internal_ie(GOTTPOFF) } @@ -100,9 +100,9 @@ entry: ; Non-PIC and PIC code will use local exec as specified. ; CHECK-NONPIC-LABEL: f7: - ; CHECK-NONPIC: external_le(tpoff) + ; CHECK-NONPIC: external_le(TPOFF) ; CHECK-PIC-LABEL: f7: - ; CHECK-PIC: external_le(tpoff) + ; CHECK-PIC: external_le(TPOFF) } define i32* @f8() { @@ -111,7 +111,7 @@ entry: ; Non-PIC and PIC code will use local exec as specified. ; CHECK-NONPIC-LABEL: f8: - ; CHECK-NONPIC: internal_le(tpoff) + ; CHECK-NONPIC: internal_le(TPOFF) ; CHECK-PIC-LABEL: f8: - ; CHECK-PIC: internal_le(tpoff) + ; CHECK-PIC: internal_le(TPOFF) } diff --git a/test/CodeGen/ARM/tls1.ll b/test/CodeGen/ARM/tls1.ll index ec4278ce72f..a1ca0b758b4 100644 --- a/test/CodeGen/ARM/tls1.ll +++ b/test/CodeGen/ARM/tls1.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \ -; RUN: grep "i(tpoff)" +; RUN: grep "i(TPOFF)" ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \ ; RUN: grep "__aeabi_read_tp" ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi \ diff --git a/test/CodeGen/ARM/tls2.ll b/test/CodeGen/ARM/tls2.ll index f0481258311..24b4794b061 100644 --- a/test/CodeGen/ARM/tls2.ll +++ b/test/CodeGen/ARM/tls2.ll @@ -8,7 +8,7 @@ define i32 @f() { ; CHECK-NONPIC-LABEL: f: ; CHECK-NONPIC: ldr {{r.}}, [pc, {{r.}}] -; CHECK-NONPIC: i(gottpoff) +; CHECK-NONPIC: i(GOTTPOFF) ; CHECK-PIC-LABEL: f: ; CHECK-PIC: __tls_get_addr entry: @@ -19,7 +19,7 @@ entry: define i32* @g() { ; CHECK-NONPIC-LABEL: g: ; CHECK-NONPIC: ldr {{r.}}, [pc, {{r.}}] -; CHECK-NONPIC: i(gottpoff) +; CHECK-NONPIC: i(GOTTPOFF) ; CHECK-PIC-LABEL: g: ; CHECK-PIC: __tls_get_addr entry: diff --git a/test/CodeGen/Thumb2/tls1.ll b/test/CodeGen/Thumb2/tls1.ll index d91e3b32f9b..40973562d2b 100644 --- a/test/CodeGen/Thumb2/tls1.ll +++ b/test/CodeGen/Thumb2/tls1.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi | \ -; RUN: grep "i(tpoff)" +; RUN: grep "i(TPOFF)" ; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi | \ ; RUN: grep "__aeabi_read_tp" ; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi \ diff --git a/test/CodeGen/Thumb2/tls2.ll b/test/CodeGen/Thumb2/tls2.ll index 6cb019ff00e..e6bed2f65a4 100644 --- a/test/CodeGen/Thumb2/tls2.ll +++ b/test/CodeGen/Thumb2/tls2.ll @@ -8,7 +8,7 @@ entry: ; CHECK-NOT-PIC-LABEL: f: ; CHECK-NOT-PIC: add r0, pc ; CHECK-NOT-PIC: ldr r1, [r0] -; CHECK-NOT-PIC: i(gottpoff) +; CHECK-NOT-PIC: i(GOTTPOFF) ; CHECK-PIC-LABEL: f: ; CHECK-PIC: bl __tls_get_addr(PLT) @@ -21,7 +21,7 @@ entry: ; CHECK-NOT-PIC-LABEL: g: ; CHECK-NOT-PIC: add r0, pc ; CHECK-NOT-PIC: ldr r1, [r0] -; CHECK-NOT-PIC: i(gottpoff) +; CHECK-NOT-PIC: i(GOTTPOFF) ; CHECK-PIC-LABEL: g: ; CHECK-PIC: bl __tls_get_addr(PLT) diff --git a/test/MC/ARM/symbol-variants-errors.s b/test/MC/ARM/symbol-variants-errors.s new file mode 100644 index 00000000000..03401cd98b7 --- /dev/null +++ b/test/MC/ARM/symbol-variants-errors.s @@ -0,0 +1,23 @@ +@ RUN: not llvm-mc < %s -triple armv7-none-linux-gnueabi 2>&1 | FileCheck %s + +@ check for invalid variant +f1: + bl bar(blargh) +@CHECK: error: invalid variant 'blargh' +@CHECK: bl bar(blargh) +@CHECK: ^ + +@ check for missing closed paren +f2: + .word bar(got +@CHECK: error: unexpected token in variant, expected ')' +@CHECK: .word bar(got +@CHECK: ^ + +@ check for invalid symbol before variant end +f3: + .word bar(got+2) + +@CHECK: error: unexpected token in variant, expected ')' +@CHECK: .word bar(got+2) +@CHECK: ^ diff --git a/test/MC/ARM/symbol-variants.s b/test/MC/ARM/symbol-variants.s new file mode 100644 index 00000000000..d24d5c790fb --- /dev/null +++ b/test/MC/ARM/symbol-variants.s @@ -0,0 +1,67 @@ +@ RUN: llvm-mc < %s -triple armv7-none-linux-gnueabi -filetype=obj | llvm-objdump -triple armv7-none-linux-gnueabi -r - | FileCheck %s --check-prefix=CHECK --check-prefix=ARM +@ RUN: llvm-mc < %s -triple thumbv7-none-linux-gnueabi -filetype=obj | llvm-objdump -triple thumbv7-none-linux-gnueabi -r - | FileCheck %s --check-prefix=CHECK --check-prefix=THUMB + +@ CHECK-LABEL: RELOCATION RECORDS FOR [.rel.text] + +@ empty +.word f00 +.word f01 +@CHECK: 0 R_ARM_ABS32 f00 +@CHECK: 4 R_ARM_ABS32 f01 + +@ none +.word f02(NONE) +.word f03(none) +@CHECK: 8 R_ARM_NONE f02 +@CHECK: 12 R_ARM_NONE f03 + +@ plt +bl f04(PLT) +bl f05(plt) +@ARM: 16 R_ARM_PLT32 f04 +@ARM: 20 R_ARM_PLT32 f05 +@THUMB: 16 R_ARM_THM_CALL f04 +@THUMB: 20 R_ARM_THM_CALL f05 + +@ got +.word f06(GOT) +.word f07(got) +@CHECK: 24 R_ARM_GOT_BREL f06 +@CHECK: 28 R_ARM_GOT_BREL f07 + +@ gotoff +.word f08(GOTOFF) +.word f09(gotoff) +@CHECK: 32 R_ARM_GOTOFF32 f08 +@CHECK: 36 R_ARM_GOTOFF32 f09 + +@ tpoff +.word f10(TPOFF) +.word f11(tpoff) +@CHECK: 40 R_ARM_TLS_LE32 f10 +@CHECK: 44 R_ARM_TLS_LE32 f11 + +@ tlsgd +.word f12(TLSGD) +.word f13(tlsgd) +@CHECK: 48 R_ARM_TLS_GD32 f12 +@CHECK: 52 R_ARM_TLS_GD32 f13 + +@ target1 +.word f14(TARGET1) +.word f15(target1) +@CHECK: 56 R_ARM_TARGET1 f14 +@CHECK: 60 R_ARM_TARGET1 f15 + +@ target2 +.word f16(TARGET2) +.word f17(target2) +@CHECK: 64 R_ARM_TARGET2 f16 +@CHECK: 68 R_ARM_TARGET2 f17 + +@ prel31 +.word f18(PREL31) +.word f19(prel31) +@CHECK: 72 R_ARM_PREL31 f18 +@CHECK: 76 R_ARM_PREL31 f19 +