diff options
-rw-r--r-- | lld/ELF/Relocations.cpp | 5 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCAssembler.h | 8 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCELFStreamer.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCObjectStreamer.h | 14 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCStreamer.h | 10 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/MC/MCELFStreamer.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 142 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 2 | ||||
-rw-r--r-- | llvm/test/MC/ELF/reloc-directive.s | 51 | ||||
-rw-r--r-- | llvm/test/MC/Mips/reloc-directive-bad-obj.s | 4 | ||||
-rw-r--r-- | llvm/test/MC/Mips/reloc-directive-label-offset.s | 8 |
16 files changed, 113 insertions, 206 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index cebd564..4333b03 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1671,8 +1671,9 @@ void RelocationScanner::scan(Relocs<RelTy> rels) { } // Sort relocations by offset for more efficient searching for - // R_RISCV_PCREL_HI20, R_PPC64_ADDR64 and the branch-to-branch optimization. - if (ctx.arg.emachine == EM_RISCV || + // R_RISCV_PCREL_HI20, ALIGN relocations, R_PPC64_ADDR64 and the + // branch-to-branch optimization. + if (is_contained({EM_RISCV, EM_LOONGARCH}, ctx.arg.emachine) || (ctx.arg.emachine == EM_PPC64 && sec->name == ".toc") || ctx.arg.branchToBranch) llvm::stable_sort(sec->relocs(), diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h index aa396ef..ade9ee6f 100644 --- a/llvm/include/llvm/MC/MCAssembler.h +++ b/llvm/include/llvm/MC/MCAssembler.h @@ -69,6 +69,13 @@ private: SmallVector<const MCSymbol *, 0> Symbols; + struct RelocDirective { + const MCExpr &Offset; + const MCExpr *Expr; + uint32_t Kind; + }; + SmallVector<RelocDirective, 0> relocDirectives; + mutable SmallVector<std::pair<SMLoc, std::string>, 0> PendingErrors; MCDwarfLineTableParams LTParams; @@ -205,6 +212,7 @@ public: LLVM_ABI bool registerSection(MCSection &Section); LLVM_ABI bool registerSymbol(const MCSymbol &Symbol); + void addRelocDirective(RelocDirective RD); LLVM_ABI void reportError(SMLoc L, const Twine &Msg) const; // Record pending errors during layout iteration, as they may go away once the diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index ad0961c..144f6bc 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -141,7 +141,8 @@ public: } private: - void finalizeCGProfileEntry(const MCSymbolRefExpr *&S, uint64_t Offset); + void finalizeCGProfileEntry(const MCSymbolRefExpr *Sym, uint64_t Offset, + const MCSymbolRefExpr *&S); void finalizeCGProfile(); bool SeenIdent = false; diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index e2a77b8..a55fd4a 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -40,14 +40,6 @@ class MCObjectStreamer : public MCStreamer { std::unique_ptr<MCAssembler> Assembler; bool EmitEHFrame; bool EmitDebugFrame; - struct PendingMCFixup { - const MCSymbol *Sym; - MCFixup Fixup; - MCFragment *DF; - PendingMCFixup(const MCSymbol *McSym, MCFragment *F, MCFixup McFixup) - : Sym(McSym), Fixup(McFixup), DF(F) {} - }; - SmallVector<PendingMCFixup, 2> PendingFixups; struct PendingAssignment { MCSymbol *Symbol; @@ -63,7 +55,6 @@ class MCObjectStreamer : public MCStreamer { void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI); - void resolvePendingFixups(); protected: MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, @@ -162,9 +153,8 @@ public: void emitCVStringTableDirective() override; void emitCVFileChecksumsDirective() override; void emitCVFileChecksumOffsetDirective(unsigned FileNo) override; - std::optional<std::pair<bool, std::string>> - emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, - SMLoc Loc, const MCSubtargetInfo &STI) override; + void emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc = {}) override; using MCStreamer::emitFill; void emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc = SMLoc()) override; diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 1f7c8b5..b3a9aab 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -1048,13 +1048,9 @@ public: virtual void emitSyntaxDirective(); - /// Record a relocation described by the .reloc directive. Return std::nullopt - /// if succeeded. Otherwise, return a pair (Name is invalid, error message). - virtual std::optional<std::pair<bool, std::string>> - emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, - SMLoc Loc, const MCSubtargetInfo &STI) { - return std::nullopt; - } + /// Record a relocation described by the .reloc directive. + virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc = {}) {} virtual void emitAddrsig() {} virtual void emitAddrsigSym(const MCSymbol *Sym) {} diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 3a330db..67c53e0 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -407,9 +407,8 @@ public: const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym) override; - std::optional<std::pair<bool, std::string>> - emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, - SMLoc Loc, const MCSubtargetInfo &STI) override; + void emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc) override; void emitAddrsig() override; void emitAddrsigSym(const MCSymbol *Sym) override; @@ -2468,10 +2467,8 @@ void MCAsmStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index, EmitEOL(); } -std::optional<std::pair<bool, std::string>> -MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, - const MCExpr *Expr, SMLoc, - const MCSubtargetInfo &STI) { +void MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc) { OS << "\t.reloc "; MAI->printExpr(OS, Offset); OS << ", " << Name; @@ -2480,7 +2477,6 @@ MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, MAI->printExpr(OS, *Expr); } EmitEOL(); - return std::nullopt; } void MCAsmStreamer::emitAddrsig() { diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index d4d10e0..f1a82f6 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -398,6 +398,10 @@ bool MCAssembler::registerSymbol(const MCSymbol &Symbol) { return Changed; } +void MCAssembler::addRelocDirective(RelocDirective RD) { + relocDirectives.push_back(RD); +} + /// Write the fragment \p F to the output file. static void writeFragment(raw_ostream &OS, const MCAssembler &Asm, const MCFragment &F) { @@ -695,6 +699,27 @@ void MCAssembler::layout() { // helps check whether a PC-relative fixup is fully resolved. this->HasFinalLayout = true; + // Resolve .reloc offsets and add fixups. + for (auto &PF : relocDirectives) { + MCValue Res; + auto &O = PF.Offset; + if (!O.evaluateAsValue(Res, *this)) { + getContext().reportError(O.getLoc(), ".reloc offset is not relocatable"); + continue; + } + auto *Sym = Res.getAddSym(); + auto *F = Sym ? Sym->getFragment() : nullptr; + auto *Sec = F ? F->getParent() : nullptr; + if (Res.getSubSym() || !Sec) { + getContext().reportError(O.getLoc(), + ".reloc offset is not relative to a section"); + continue; + } + + uint64_t Offset = Sym ? Sym->getOffset() + Res.getConstant() : 0; + F->addFixup(MCFixup::create(Offset, PF.Expr, PF.Kind)); + } + // Evaluate and apply the fixups, generating relocation entries as necessary. for (MCSection &Sec : *this) { for (MCFragment &F : Sec) { diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index ffc5722..49071bd 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -314,8 +314,9 @@ void MCELFStreamer::emitIdent(StringRef IdentString) { popSection(); } -void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE, - uint64_t Offset) { +void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *Sym, + uint64_t Offset, + const MCSymbolRefExpr *&SRE) { const MCSymbol *S = &SRE->getSymbol(); if (S->isTemporary()) { if (!S->isInSection()) { @@ -328,13 +329,9 @@ void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE, S->setUsedInReloc(); SRE = MCSymbolRefExpr::create(S, getContext(), SRE->getLoc()); } - const MCConstantExpr *MCOffset = MCConstantExpr::create(Offset, getContext()); - if (std::optional<std::pair<bool, std::string>> Err = - MCObjectStreamer::emitRelocDirective( - *MCOffset, "BFD_RELOC_NONE", SRE, SRE->getLoc(), - *getContext().getSubtargetInfo())) - report_fatal_error("Relocation for CG Profile could not be created: " + - Twine(Err->second)); + auto *O = MCBinaryExpr::createAdd( + Sym, MCConstantExpr::create(Offset, getContext()), getContext()); + MCObjectStreamer::emitRelocDirective(*O, "BFD_RELOC_NONE", SRE); } void MCELFStreamer::finalizeCGProfile() { @@ -347,9 +344,11 @@ void MCELFStreamer::finalizeCGProfile() { pushSection(); switchSection(CGProfile); uint64_t Offset = 0; + auto *Sym = + MCSymbolRefExpr::create(CGProfile->getBeginSymbol(), getContext()); for (auto &E : W.getCGProfile()) { - finalizeCGProfileEntry(E.From, Offset); - finalizeCGProfileEntry(E.To, Offset); + finalizeCGProfileEntry(Sym, Offset, E.From); + finalizeCGProfileEntry(Sym, Offset, E.To); emitIntValue(E.Count, sizeof(uint64_t)); Offset += sizeof(uint64_t); } diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index c0cef0f..67433f2 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -46,35 +46,6 @@ MCAssembler *MCObjectStreamer::getAssemblerPtr() { return nullptr; } -// When fixup's offset is a forward declared label, e.g.: -// -// .reloc 1f, R_MIPS_JALR, foo -// 1: nop -// -// postpone adding it to Fixups vector until the label is defined and its offset -// is known. -void MCObjectStreamer::resolvePendingFixups() { - for (PendingMCFixup &PendingFixup : PendingFixups) { - if (!PendingFixup.Sym || PendingFixup.Sym->isUndefined ()) { - getContext().reportError(PendingFixup.Fixup.getLoc(), - "unresolved relocation offset"); - continue; - } - PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset() + - PendingFixup.Fixup.getOffset()); - - // If the location symbol to relocate is in MCEncodedFragment, - // put the Fixup into location symbol's fragment. Otherwise - // put into PendingFixup.DF - MCFragment *F = PendingFixup.Sym->getFragment(); - if (F->isEncoded()) - F->addFixup(PendingFixup.Fixup); - else - PendingFixup.DF->addFixup(PendingFixup.Fixup); - } - PendingFixups.clear(); -} - // As a compile-time optimization, avoid allocating and evaluating an MCExpr // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment's fixed // part. @@ -607,76 +578,14 @@ void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, insert(getContext().allocFragment<MCOrgFragment>(*Offset, Value, Loc)); } -static std::optional<std::pair<bool, std::string>> -getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset, - MCFragment *&DF) { - if (Symbol.isVariable()) { - const MCExpr *SymbolExpr = Symbol.getVariableValue(); - MCValue OffsetVal; - if (!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr)) - return std::make_pair(false, - std::string("symbol in .reloc offset is not " - "relocatable")); - if (OffsetVal.isAbsolute()) { - RelocOffset = OffsetVal.getConstant(); - MCFragment *Fragment = Symbol.getFragment(); - // FIXME Support symbols with no DF. For example: - // .reloc .data, ENUM_VALUE, <some expr> - if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) - return std::make_pair(false, - std::string("symbol in offset has no data " - "fragment")); - DF = cast<MCFragment>(Fragment); - return std::nullopt; - } - - if (OffsetVal.getSubSym()) - return std::make_pair(false, - std::string(".reloc symbol offset is not " - "representable")); - - const MCSymbol &SA = *OffsetVal.getAddSym(); - if (!SA.isDefined()) - return std::make_pair(false, - std::string("symbol used in the .reloc offset is " - "not defined")); - - if (SA.isVariable()) - return std::make_pair(false, - std::string("symbol used in the .reloc offset is " - "variable")); - - MCFragment *Fragment = SA.getFragment(); - // FIXME Support symbols with no DF. For example: - // .reloc .data, ENUM_VALUE, <some expr> - if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) - return std::make_pair(false, - std::string("symbol in offset has no data " - "fragment")); - RelocOffset = SA.getOffset() + OffsetVal.getConstant(); - DF = cast<MCFragment>(Fragment); - } else { - RelocOffset = Symbol.getOffset(); - MCFragment *Fragment = Symbol.getFragment(); - // FIXME Support symbols with no DF. For example: - // .reloc .data, ENUM_VALUE, <some expr> - if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) - return std::make_pair(false, - std::string("symbol in offset has no data " - "fragment")); - DF = cast<MCFragment>(Fragment); - } - return std::nullopt; -} - -std::optional<std::pair<bool, std::string>> -MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, - const MCExpr *Expr, SMLoc Loc, - const MCSubtargetInfo &STI) { +void MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc) { std::optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name); - if (!MaybeKind) - return std::make_pair(true, std::string("unknown relocation name")); + if (!MaybeKind) { + getContext().reportError(Loc, "unknown relocation name"); + return; + } MCFixupKind Kind = *MaybeKind; if (Expr) @@ -685,38 +594,14 @@ MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, Expr = MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext()); - MCFragment *DF = getOrCreateDataFragment(&STI); - MCValue OffsetVal; - if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr)) - return std::make_pair(false, - std::string(".reloc offset is not relocatable")); - if (OffsetVal.isAbsolute()) { - if (OffsetVal.getConstant() < 0) - return std::make_pair(false, std::string(".reloc offset is negative")); - DF->addFixup(MCFixup::create(OffsetVal.getConstant(), Expr, Kind)); - return std::nullopt; - } - if (OffsetVal.getSubSym()) - return std::make_pair(false, - std::string(".reloc offset is not representable")); - - const MCSymbol &Symbol = *OffsetVal.getAddSym(); - if (Symbol.isDefined()) { - uint32_t SymbolOffset = 0; - std::optional<std::pair<bool, std::string>> Error = - getOffsetAndDataFragment(Symbol, SymbolOffset, DF); - - if (Error != std::nullopt) - return Error; - - DF->addFixup( - MCFixup::create(SymbolOffset + OffsetVal.getConstant(), Expr, Kind)); - return std::nullopt; + auto *O = &Offset; + int64_t Val; + if (Offset.evaluateAsAbsolute(Val, nullptr)) { + auto *SecSym = getCurrentSectionOnly()->getBeginSymbol(); + O = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(SecSym, getContext()), + O, getContext(), Loc); } - - PendingFixups.emplace_back( - &Symbol, DF, MCFixup::create(OffsetVal.getConstant(), Expr, Kind)); - return std::nullopt; + getAssembler().addRelocDirective({*O, Expr, Kind}); } void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, @@ -799,6 +684,5 @@ void MCObjectStreamer::finishImpl() { // Emit pseudo probes for the current module. MCPseudoProbeTable::emit(this); - resolvePendingFixups(); getAssembler().Finish(); } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index a36b2de..77bf843 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -3079,7 +3079,6 @@ bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) { const MCExpr *Offset; const MCExpr *Expr = nullptr; - SMLoc OffsetLoc = Lexer.getTok().getLoc(); if (parseExpression(Offset)) return true; @@ -3105,13 +3104,7 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) { if (parseEOL()) return true; - const MCTargetAsmParser &MCT = getTargetParser(); - const MCSubtargetInfo &STI = MCT.getSTI(); - if (std::optional<std::pair<bool, std::string>> Err = - getStreamer().emitRelocDirective(*Offset, Name, Expr, DirectiveLoc, - STI)) - return Error(Err->first ? NameLoc : OffsetLoc, Err->second); - + getStreamer().emitRelocDirective(*Offset, Name, Expr, NameLoc); return false; } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp index 233f42b..08f547a 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp @@ -559,8 +559,7 @@ void AArch64TargetELFStreamer::finish() { if (!Sym.isMemtag()) continue; auto *SRE = MCSymbolRefExpr::create(&Sym, Ctx); - (void)S.emitRelocDirective(*Zero, "BFD_RELOC_NONE", SRE, SMLoc(), - *Ctx.getSubtargetInfo()); + S.emitRelocDirective(*Zero, "BFD_RELOC_NONE", SRE); } } diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 01e4d17..259b71b 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -2101,7 +2101,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, TOut.getStreamer().emitRelocDirective( *TmpExpr, inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR", - RelocJalrExpr, IDLoc, *STI); + RelocJalrExpr); TOut.getStreamer().emitLabel(TmpLabel); } diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index c18ba44..ca03310 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -166,7 +166,7 @@ static void emitDirectiveRelocJalr(const MachineInstr &MI, OutStreamer.emitRelocDirective( *OffsetExpr, Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR", - CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo()); + CaleeExpr); OutStreamer.emitLabel(OffsetLabel); return; } diff --git a/llvm/test/MC/ELF/reloc-directive.s b/llvm/test/MC/ELF/reloc-directive.s index 42995aa..9871fba 100644 --- a/llvm/test/MC/ELF/reloc-directive.s +++ b/llvm/test/MC/ELF/reloc-directive.s @@ -9,15 +9,18 @@ # ASM-NEXT: .reloc .Ltmp1-1, R_X86_64_NONE, foo # ASM-NEXT: .Ltmp2: # ASM-NEXT: .reloc 2+.Ltmp2, R_X86_64_NONE, local -# ASM-NEXT: .reloc 1+foo+3, R_X86_64_NONE, data+1 -# ASM-NEXT: .Ltmp3: -# ASM-NEXT: .reloc .Ltmp3, BFD_RELOC_NONE, unused # CHECK: 0x2 R_X86_64_NONE foo 0x0 # CHECK-NEXT: 0x0 R_X86_64_NONE foo 0x0 # CHECK-NEXT: 0x3 R_X86_64_NONE local 0x0 -# CHECK-NEXT: 0x4 R_X86_64_NONE data 0x1 # CHECK-NEXT: 0x1 R_X86_64_NONE unused 0x0 +# CHECK-NEXT: 0x4 R_X86_64_NONE data 0x1 + +# CHECK: .rela.my { +# CHECK: 0x0 R_X86_64_NONE foo 0x0 +# CHECK-NEXT: 0x4 R_X86_64_NONE foo 0x0 +# CHECK-NEXT: 0x8 R_X86_64_NONE foo 0x0 +# CHECK-NEXT: } .text .globl foo @@ -27,17 +30,25 @@ local: .reloc .+3-2, R_X86_64_NONE, foo .reloc .-1, R_X86_64_NONE, foo .reloc 2+., R_X86_64_NONE, local - .reloc 1+foo+3, R_X86_64_NONE, data+1 .reloc ., BFD_RELOC_NONE, unused + .space 3 .data .globl data data: + .reloc 1+foo+3, R_X86_64_NONE, data+1 .long 0 -# RUN: not llvm-mc -filetype=obj -triple=x86_64 --defsym=ERR=1 %s 2>&1 | FileCheck %s --check-prefix=ERR +## Constant offsets are relative to the section start. +.section .my +.word 0 +.reloc 0, BFD_RELOC_NONE, foo +.word 0 +.p2align 3 +.reloc 2+2, BFD_RELOC_NONE, foo +.p2align 4 +.reloc 8, BFD_RELOC_NONE, foo -.ifdef ERR .text .globl a, b a: ret @@ -45,22 +56,26 @@ b: ret x: ret y: ret -# ERR: {{.*}}.s:[[#@LINE+1]]:10: error: expected comma +# RUN: not llvm-mc -filetype=obj -triple=x86_64 --defsym=PARSE=1 %s 2>&1 | FileCheck %s --check-prefix=PARSE +# RUN: not llvm-mc -filetype=obj -triple=x86_64 --defsym=ERR=1 %s 2>&1 | FileCheck %s --check-prefix=ERR + +.ifdef PARSE +# PARSE: {{.*}}.s:[[#@LINE+1]]:10: error: expected comma .reloc 0 R_X86_64_NONE, a -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is negative +# PARSE: {{.*}}.s:[[#@LINE+1]]:8: error: directional label undefined +.reloc 1f, R_X86_64_NONE, a +.endif + +.ifdef ERR .reloc -1, R_X86_64_NONE, a -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is not relocatable +# ERR: {{.*}}.s:[[#@LINE+1]]:9: error: .reloc offset is not relocatable .reloc 2*., R_X86_64_NONE, a -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is not relocatable +# ERR: {{.*}}.s:[[#@LINE+1]]:9: error: .reloc offset is not relocatable .reloc a+a, R_X86_64_NONE, a -## GNU as accepts a-a but rejects b-a. -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is not representable -.reloc a-a, R_X86_64_NONE, a -## TODO GNU as accepts x-x and y-x. -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is not representable +# ERR: {{.*}}.s:[[#@LINE+1]]:9: error: .reloc offset is not relative to a section +.reloc b-a, R_X86_64_NONE, a +# ERR: {{.*}}.s:[[#@LINE+1]]:9: error: .reloc offset is not relative to a section .reloc x-x, R_X86_64_NONE, a -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: directional label undefined -.reloc 1f, R_X86_64_NONE, a .endif diff --git a/llvm/test/MC/Mips/reloc-directive-bad-obj.s b/llvm/test/MC/Mips/reloc-directive-bad-obj.s index 86d6d0c..74e5dae 100644 --- a/llvm/test/MC/Mips/reloc-directive-bad-obj.s +++ b/llvm/test/MC/Mips/reloc-directive-bad-obj.s @@ -2,8 +2,8 @@ # RUN: -target-abi=o32 -filetype=obj -o /dev/null 2>&1 | FileCheck %s .text nop -.reloc foo, R_MIPS_32, .text # CHECK: :[[@LINE]]:24: error: unresolved relocation offset +.reloc foo, R_MIPS_32, .text # CHECK: :[[@LINE]]:8: error: .reloc offset is not relative to a section nop nop -.reloc bar, R_MIPS_32, .text # CHECK: :[[@LINE]]:24: error: unresolved relocation offset +.reloc bar, R_MIPS_32, .text # CHECK: :[[@LINE]]:8: error: .reloc offset is not relative to a section nop diff --git a/llvm/test/MC/Mips/reloc-directive-label-offset.s b/llvm/test/MC/Mips/reloc-directive-label-offset.s index 257bfeb..279fc78 100644 --- a/llvm/test/MC/Mips/reloc-directive-label-offset.s +++ b/llvm/test/MC/Mips/reloc-directive-label-offset.s @@ -58,18 +58,18 @@ bar: # OBJ-N32-LABEL: Relocations [ # OBJ-N32: 0x4 R_MIPS_NONE .text -# OBJ-N32-NEXT: 0x1C R_MIPS_GOT_OFST .text -# OBJ-N32-NEXT: 0x0 R_MIPS_32 .text # OBJ-N32-NEXT: 0xC R_MIPS_32 .text # OBJ-N32-NEXT: 0x10 R_MIPS_CALL16 foo # OBJ-N32-NEXT: 0x20 R_MIPS_GOT_DISP foo # OBJ-N32-NEXT: 0x24 R_MIPS_GOT_PAGE .text +# OBJ-N32-NEXT: 0x1C R_MIPS_GOT_OFST .text +# OBJ-N32-NEXT: 0x0 R_MIPS_32 .text # OBJ-N64-LABEL: Relocations [ # OBJ-N64: 0x4 R_MIPS_NONE/R_MIPS_NONE/R_MIPS_NONE .text 0x0 -# OBJ-N64-NEXT: 0x1C R_MIPS_GOT_OFST/R_MIPS_NONE/R_MIPS_NONE .text 0x0 -# OBJ-N64-NEXT: 0x0 R_MIPS_32/R_MIPS_NONE/R_MIPS_NONE .text 0x0 # OBJ-N64-NEXT: 0xC R_MIPS_32/R_MIPS_NONE/R_MIPS_NONE .text 0x0 # OBJ-N64-NEXT: 0x10 R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE foo 0x0 # OBJ-N64-NEXT: 0x20 R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE foo 0x0 # OBJ-N64-NEXT: 0x24 R_MIPS_GOT_PAGE/R_MIPS_NONE/R_MIPS_NONE .text 0x0 +# OBJ-N64-NEXT: 0x1C R_MIPS_GOT_OFST/R_MIPS_NONE/R_MIPS_NONE .text 0x0 +# OBJ-N64-NEXT: 0x0 R_MIPS_32/R_MIPS_NONE/R_MIPS_NONE .text 0x0 |