diff options
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 228 |
1 files changed, 120 insertions, 108 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 3d1358df475f..e39c4a03bc1e 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SourceMgr.h" using namespace llvm; @@ -59,12 +60,8 @@ void MCObjectStreamer::addPendingLabel(MCSymbol* S) { CurSection->addPendingLabel(S, CurSubsectionIdx); // Add this Section to the list of PendingLabelSections. - auto SecIt = std::find(PendingLabelSections.begin(), - PendingLabelSections.end(), CurSection); - if (SecIt == PendingLabelSections.end()) - PendingLabelSections.push_back(CurSection); - } - else + PendingLabelSections.insert(CurSection); + } else // There is no Section / Subsection for this label yet. PendingLabels.push_back(S); } @@ -145,7 +142,7 @@ void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) { if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) { - EmitIntValue(*Diff, Size); + emitIntValue(*Diff, Size); return; } MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size); @@ -154,7 +151,7 @@ void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo) { if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) { - EmitULEB128IntValue(*Diff); + emitULEB128IntValue(*Diff); return; } MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); @@ -171,7 +168,7 @@ void MCObjectStreamer::reset() { MCStreamer::reset(); } -void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) { +void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) { if (!getNumFrameInfos()) return; @@ -191,13 +188,13 @@ MCFragment *MCObjectStreamer::getCurrentFragment() const { return nullptr; } -static bool CanReuseDataFragment(const MCDataFragment &F, +static bool canReuseDataFragment(const MCDataFragment &F, const MCAssembler &Assembler, const MCSubtargetInfo *STI) { if (!F.hasInstructions()) return true; // When bundling is enabled, we don't want to add data to a fragment that - // already has instructions (see MCELFStreamer::EmitInstToData for details) + // already has instructions (see MCELFStreamer::emitInstToData for details) if (Assembler.isBundlingEnabled()) return Assembler.getRelaxAll(); // If the subtarget is changed mid fragment we start a new fragment to record @@ -208,7 +205,7 @@ static bool CanReuseDataFragment(const MCDataFragment &F, MCDataFragment * MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) { MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); - if (!F || !CanReuseDataFragment(*F, *Assembler, STI)) { + if (!F || !canReuseDataFragment(*F, *Assembler, STI)) { F = new MCDataFragment(); insert(F); } @@ -219,15 +216,15 @@ void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) { Assembler->registerSymbol(Sym); } -void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) { - MCStreamer::EmitCFISections(EH, Debug); +void MCObjectStreamer::emitCFISections(bool EH, bool Debug) { + MCStreamer::emitCFISections(EH, Debug); EmitEHFrame = EH; EmitDebugFrame = Debug; } -void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, +void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { - MCStreamer::EmitValueImpl(Value, Size, Loc); + MCStreamer::emitValueImpl(Value, Size, Loc); MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); @@ -241,7 +238,7 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, Loc, "value evaluated as " + Twine(AbsValue) + " is out of range."); return; } - EmitIntValue(AbsValue, Size); + emitIntValue(AbsValue, Size); return; } DF->getFixups().push_back( @@ -250,25 +247,25 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, DF->getContents().resize(DF->getContents().size() + Size, 0); } -MCSymbol *MCObjectStreamer::EmitCFILabel() { +MCSymbol *MCObjectStreamer::emitCFILabel() { MCSymbol *Label = getContext().createTempSymbol("cfi", true); - EmitLabel(Label); + emitLabel(Label); return Label; } -void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { +void MCObjectStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { // We need to create a local symbol to avoid relocations. Frame.Begin = getContext().createTempSymbol(); - EmitLabel(Frame.Begin); + emitLabel(Frame.Begin); } -void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { +void MCObjectStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { Frame.End = getContext().createTempSymbol(); - EmitLabel(Frame.End); + emitLabel(Frame.End); } -void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { - MCStreamer::EmitLabel(Symbol, Loc); +void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { + MCStreamer::emitLabel(Symbol, Loc); getAssembler().registerSymbol(*Symbol); @@ -291,11 +288,11 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { // Emit a label at a previously emitted fragment/offset position. This must be // within the currently-active section. -void MCObjectStreamer::EmitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, +void MCObjectStreamer::emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F, uint64_t Offset) { assert(F->getParent() == getCurrentSectionOnly()); - MCStreamer::EmitLabel(Symbol, Loc); + MCStreamer::emitLabel(Symbol, Loc); getAssembler().registerSymbol(*Symbol); auto *DF = dyn_cast_or_null<MCDataFragment>(F); Symbol->setOffset(Offset); @@ -309,30 +306,30 @@ void MCObjectStreamer::EmitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, } } -void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { +void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) { int64_t IntValue; if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) { - EmitULEB128IntValue(IntValue); + emitULEB128IntValue(IntValue); return; } insert(new MCLEBFragment(*Value, false)); } -void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { +void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) { int64_t IntValue; if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) { - EmitSLEB128IntValue(IntValue); + emitSLEB128IntValue(IntValue); return; } insert(new MCLEBFragment(*Value, true)); } -void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, +void MCObjectStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { report_fatal_error("This file format doesn't support weak aliases."); } -void MCObjectStreamer::ChangeSection(MCSection *Section, +void MCObjectStreamer::changeSection(MCSection *Section, const MCExpr *Subsection) { changeSectionImpl(Section, Subsection); } @@ -356,25 +353,32 @@ bool MCObjectStreamer::changeSectionImpl(MCSection *Section, return Created; } -void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { +void MCObjectStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) { getAssembler().registerSymbol(*Symbol); - MCStreamer::EmitAssignment(Symbol, Value); + MCStreamer::emitAssignment(Symbol, Value); } bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { return Sec.hasInstructions(); } -void MCObjectStreamer::EmitInstruction(const MCInst &Inst, +void MCObjectStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { - getAssembler().getBackend().alignBranchesBegin(*this, Inst); - EmitInstructionImpl(Inst, STI); - getAssembler().getBackend().alignBranchesEnd(*this, Inst); + const MCSection &Sec = *getCurrentSectionOnly(); + if (Sec.isVirtualSection()) { + getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) + + " section '" + Sec.getName() + + "' cannot have instructions"); + return; + } + getAssembler().getBackend().emitInstructionBegin(*this, Inst); + emitInstructionImpl(Inst, STI); + getAssembler().getBackend().emitInstructionEnd(*this, Inst); } -void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst, +void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI) { - MCStreamer::EmitInstruction(Inst, STI); + MCStreamer::emitInstruction(Inst, STI); MCSection *Sec = getCurrentSectionOnly(); Sec->setHasInstructions(true); @@ -385,8 +389,10 @@ void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst, // If this instruction doesn't need relaxation, just emit it as data. MCAssembler &Assembler = getAssembler(); - if (!Assembler.getBackend().mayNeedRelaxation(Inst, STI)) { - EmitInstToData(Inst, STI); + MCAsmBackend &Backend = Assembler.getBackend(); + if (!(Backend.mayNeedRelaxation(Inst, STI) || + Backend.allowEnhancedRelaxation())) { + emitInstToData(Inst, STI); return; } @@ -397,19 +403,18 @@ void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst, // fragment. if (Assembler.getRelaxAll() || (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) { - MCInst Relaxed; - getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed); - while (getAssembler().getBackend().mayNeedRelaxation(Relaxed, STI)) - getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed); - EmitInstToData(Relaxed, STI); + MCInst Relaxed = Inst; + while (Backend.mayNeedRelaxation(Relaxed, STI)) + Backend.relaxInstruction(Relaxed, STI); + emitInstToData(Relaxed, STI); return; } // Otherwise emit to a separate fragment. - EmitInstToFragment(Inst, STI); + emitInstToFragment(Inst, STI); } -void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst, +void MCObjectStreamer::emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &STI) { if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled()) llvm_unreachable("All instructions should have already been relaxed"); @@ -431,19 +436,19 @@ static const char *const BundlingNotImplementedMsg = "Aligned bundling is not implemented for this object format"; #endif -void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) { +void MCObjectStreamer::emitBundleAlignMode(unsigned AlignPow2) { llvm_unreachable(BundlingNotImplementedMsg); } -void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) { +void MCObjectStreamer::emitBundleLock(bool AlignToEnd) { llvm_unreachable(BundlingNotImplementedMsg); } -void MCObjectStreamer::EmitBundleUnlock() { +void MCObjectStreamer::emitBundleUnlock() { llvm_unreachable(BundlingNotImplementedMsg); } -void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, +void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, @@ -452,8 +457,8 @@ void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, // first one gets a line entry. MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); - this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, - Isa, Discriminator, FileName); + this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa, + Discriminator, FileName); } static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A, @@ -472,16 +477,16 @@ static void emitDwarfSetLineAddr(MCObjectStreamer &OS, int64_t LineDelta, const MCSymbol *Label, int PointerSize) { // emit the sequence to set the address - OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1); - OS.EmitULEB128IntValue(PointerSize + 1); - OS.EmitIntValue(dwarf::DW_LNE_set_address, 1); - OS.EmitSymbolValue(Label, PointerSize); + OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); + OS.emitULEB128IntValue(PointerSize + 1); + OS.emitIntValue(dwarf::DW_LNE_set_address, 1); + OS.emitSymbolValue(Label, PointerSize); // emit the sequence for the LineDelta (from 1) and a zero address delta. MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); } -void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, +void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize) { @@ -500,7 +505,7 @@ void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta)); } -void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, +void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label) { const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel); int64_t Res; @@ -511,7 +516,7 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, insert(new MCDwarfCallFrameFragment(*AddrDelta)); } -void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, +void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt, StringRef FileName, SMLoc Loc) { @@ -521,31 +526,31 @@ void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, // Emit a label at the current position and record it in the CodeViewContext. MCSymbol *LineSym = getContext().createTempSymbol(); - EmitLabel(LineSym); + emitLabel(LineSym); getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId, FileNo, Line, Column, PrologueEnd, IsStmt); } -void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId, +void MCObjectStreamer::emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin, const MCSymbol *End) { getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin, End); - this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End); + this->MCStreamer::emitCVLinetableDirective(FunctionId, Begin, End); } -void MCObjectStreamer::EmitCVInlineLinetableDirective( +void MCObjectStreamer::emitCVInlineLinetableDirective( unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) { getContext().getCVContext().emitInlineLineTableForFunction( *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym); - this->MCStreamer::EmitCVInlineLinetableDirective( + this->MCStreamer::emitCVInlineLinetableDirective( PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym); } -void MCObjectStreamer::EmitCVDefRangeDirective( +void MCObjectStreamer::emitCVDefRangeDirective( ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, StringRef FixedSizePortion) { MCFragment *Frag = @@ -553,28 +558,28 @@ void MCObjectStreamer::EmitCVDefRangeDirective( // Attach labels that were pending before we created the defrange fragment to // the beginning of the new fragment. flushPendingLabels(Frag, 0); - this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion); + this->MCStreamer::emitCVDefRangeDirective(Ranges, FixedSizePortion); } -void MCObjectStreamer::EmitCVStringTableDirective() { +void MCObjectStreamer::emitCVStringTableDirective() { getContext().getCVContext().emitStringTable(*this); } -void MCObjectStreamer::EmitCVFileChecksumsDirective() { +void MCObjectStreamer::emitCVFileChecksumsDirective() { getContext().getCVContext().emitFileChecksums(*this); } -void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) { +void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) { getContext().getCVContext().emitFileChecksumOffset(*this, FileNo); } -void MCObjectStreamer::EmitBytes(StringRef Data) { +void MCObjectStreamer::emitBytes(StringRef Data) { MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); DF->getContents().append(Data.begin(), Data.end()); } -void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, +void MCObjectStreamer::emitValueToAlignment(unsigned ByteAlignment, int64_t Value, unsigned ValueSize, unsigned MaxBytesToEmit) { @@ -588,9 +593,9 @@ void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, CurSec->setAlignment(Align(ByteAlignment)); } -void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, +void MCObjectStreamer::emitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit) { - EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); + emitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); } @@ -601,7 +606,7 @@ void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, } // Associate DTPRel32 fixup with data and resize data area -void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) { +void MCObjectStreamer::emitDTPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); @@ -611,7 +616,7 @@ void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) { } // Associate DTPRel64 fixup with data and resize data area -void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) { +void MCObjectStreamer::emitDTPRel64Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); @@ -621,7 +626,7 @@ void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) { } // Associate TPRel32 fixup with data and resize data area -void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) { +void MCObjectStreamer::emitTPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); @@ -631,7 +636,7 @@ void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) { } // Associate TPRel64 fixup with data and resize data area -void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) { +void MCObjectStreamer::emitTPRel64Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); @@ -641,7 +646,7 @@ void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) { } // Associate GPRel32 fixup with data and resize data area -void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { +void MCObjectStreamer::emitGPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); @@ -651,7 +656,7 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { } // Associate GPRel64 fixup with data and resize data area -void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { +void MCObjectStreamer::emitGPRel64Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); @@ -660,12 +665,13 @@ void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { DF->getContents().resize(DF->getContents().size() + 8, 0); } -bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name, - const MCExpr *Expr, SMLoc Loc, - const MCSubtargetInfo &STI) { +Optional<std::pair<bool, std::string>> +MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc, + const MCSubtargetInfo &STI) { Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name); if (!MaybeKind.hasValue()) - return true; + return std::make_pair(true, std::string("unknown relocation name")); MCFixupKind Kind = *MaybeKind; @@ -676,27 +682,33 @@ bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name, MCDataFragment *DF = getOrCreateDataFragment(&STI); flushPendingLabels(DF, DF->getContents().size()); - int64_t OffsetValue; - if (Offset.evaluateAsAbsolute(OffsetValue)) { - if (OffsetValue < 0) - llvm_unreachable(".reloc offset is negative"); - DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc)); - return false; + MCValue OffsetVal; + if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr, 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->getFixups().push_back( + MCFixup::create(OffsetVal.getConstant(), Expr, Kind, Loc)); + return None; } + if (OffsetVal.getSymB()) + return std::make_pair(false, + std::string(".reloc offset is not representable")); - if (Offset.getKind() != llvm::MCExpr::SymbolRef) - llvm_unreachable(".reloc offset is not absolute nor a label"); - - const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(Offset); + const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA()); if (SRE.getSymbol().isDefined()) { - DF->getFixups().push_back(MCFixup::create(SRE.getSymbol().getOffset(), - Expr, Kind, Loc)); - return false; + // FIXME SRE.getSymbol() may not be relative to DF. + DF->getFixups().push_back( + MCFixup::create(SRE.getSymbol().getOffset() + OffsetVal.getConstant(), + Expr, Kind, Loc)); + return None; } PendingFixups.emplace_back(&SRE.getSymbol(), DF, - MCFixup::create(-1, Expr, Kind, Loc)); - return false; + MCFixup::create(-1, Expr, Kind, Loc)); + return None; } void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, @@ -723,9 +735,9 @@ void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t NonZeroSize = Size > 4 ? 4 : Size; Expr &= ~0ULL >> (64 - NonZeroSize * 8); for (uint64_t i = 0, e = IntNumValues; i != e; ++i) { - EmitIntValue(Expr, NonZeroSize); + emitIntValue(Expr, NonZeroSize); if (NonZeroSize < Size) - EmitIntValue(0, Size - NonZeroSize); + emitIntValue(0, Size - NonZeroSize); } return; } @@ -738,20 +750,20 @@ void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size, insert(new MCFillFragment(Expr, Size, NumValues, Loc)); } -void MCObjectStreamer::EmitFileDirective(StringRef Filename) { +void MCObjectStreamer::emitFileDirective(StringRef Filename) { getAssembler().addFileName(Filename); } -void MCObjectStreamer::EmitAddrsig() { +void MCObjectStreamer::emitAddrsig() { getAssembler().getWriter().emitAddrsigSection(); } -void MCObjectStreamer::EmitAddrsigSym(const MCSymbol *Sym) { +void MCObjectStreamer::emitAddrsigSym(const MCSymbol *Sym) { getAssembler().registerSymbol(*Sym); getAssembler().getWriter().addAddrsigSymbol(Sym); } -void MCObjectStreamer::FinishImpl() { +void MCObjectStreamer::finishImpl() { getContext().RemapDebugPaths(); // If we are generating dwarf for assembly source files dump out the sections. |