X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FMC%2FMCAssembler.cpp;h=18687cdd6a2b17768463f95c560acbcafb8e52bf;hp=10c35be83828e1e4c9720be6e70c378c167734ac;hb=19696daa2159e059b9a15cda222e97d2b91b279d;hpb=286cc1354606638fef69eee80e98dadb90406e51 diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 10c35be8382..18687cdd6a2 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "assembler" #include "llvm/MC/MCAssembler.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" @@ -21,6 +21,7 @@ #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/Debug.h" @@ -28,9 +29,11 @@ #include "llvm/Support/LEB128.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" - +#include using namespace llvm; +#define DEBUG_TYPE "assembler" + namespace { namespace stats { STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total"); @@ -116,36 +119,99 @@ uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const { return F->Offset; } -uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const { +// Simple getSymbolOffset helper for the non-varibale case. +static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbolData &SD, + bool ReportError, uint64_t &Val) { + if (!SD.getFragment()) { + if (ReportError) + report_fatal_error("unable to evaluate offset to undefined symbol '" + + SD.getSymbol().getName() + "'"); + return false; + } + Val = Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset(); + return true; +} + +static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, + const MCSymbolData *SD, bool ReportError, + uint64_t &Val) { const MCSymbol &S = SD->getSymbol(); - // If this is a variable, then recursively evaluate now. - if (S.isVariable()) { - MCValue Target; - if (!S.getVariableValue()->EvaluateAsRelocatable(Target, *this)) - report_fatal_error("unable to evaluate offset for variable '" + - S.getName() + "'"); + if (!S.isVariable()) + return getLabelOffset(Layout, *SD, ReportError, Val); - // Verify that any used symbols are defined. - if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined()) - report_fatal_error("unable to evaluate offset to undefined symbol '" + - Target.getSymA()->getSymbol().getName() + "'"); - if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined()) - report_fatal_error("unable to evaluate offset to undefined symbol '" + - Target.getSymB()->getSymbol().getName() + "'"); - - uint64_t Offset = Target.getConstant(); - if (Target.getSymA()) - Offset += getSymbolOffset(&Assembler.getSymbolData( - Target.getSymA()->getSymbol())); - if (Target.getSymB()) - Offset -= getSymbolOffset(&Assembler.getSymbolData( - Target.getSymB()->getSymbol())); - return Offset; + // If SD is a variable, evaluate it. + MCValue Target; + if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout, nullptr)) + report_fatal_error("unable to evaluate offset for variable '" + + S.getName() + "'"); + + uint64_t Offset = Target.getConstant(); + + const MCAssembler &Asm = Layout.getAssembler(); + + const MCSymbolRefExpr *A = Target.getSymA(); + if (A) { + uint64_t ValA; + if (!getLabelOffset(Layout, Asm.getSymbolData(A->getSymbol()), ReportError, + ValA)) + return false; + Offset += ValA; + } + + const MCSymbolRefExpr *B = Target.getSymB(); + if (B) { + uint64_t ValB; + if (!getLabelOffset(Layout, Asm.getSymbolData(B->getSymbol()), ReportError, + ValB)) + return false; + Offset -= ValB; } - assert(SD->getFragment() && "Invalid getOffset() on undefined symbol!"); - return getFragmentOffset(SD->getFragment()) + SD->getOffset(); + Val = Offset; + return true; +} + +bool MCAsmLayout::getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const { + return getSymbolOffsetImpl(*this, SD, false, Val); +} + +uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const { + uint64_t Val; + getSymbolOffsetImpl(*this, SD, true, Val); + return Val; +} + +const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { + if (!Symbol.isVariable()) + return &Symbol; + + const MCExpr *Expr = Symbol.getVariableValue(); + MCValue Value; + if (!Expr->evaluateAsValue(Value, *this)) + llvm_unreachable("Invalid Expression"); + + const MCSymbolRefExpr *RefB = Value.getSymB(); + if (RefB) + Assembler.getContext().reportFatalError( + SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() + + "' could not be evaluated in a subtraction expression"); + + const MCSymbolRefExpr *A = Value.getSymA(); + if (!A) + return nullptr; + + const MCSymbol &ASym = A->getSymbol(); + const MCAssembler &Asm = getAssembler(); + const MCSymbolData &ASD = Asm.getSymbolData(ASym); + if (ASD.isCommon()) { + // FIXME: we should probably add a SMLoc to MCExpr. + Asm.getContext().reportFatalError(SMLoc(), + "Common symbol " + ASym.getName() + + " cannot be used in assignment expr"); + } + + return &ASym; } uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const { @@ -163,8 +229,9 @@ uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const { return getSectionAddressSize(SD); } -uint64_t MCAsmLayout::computeBundlePadding(const MCFragment *F, - uint64_t FOffset, uint64_t FSize) { +uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler, + const MCFragment *F, + uint64_t FOffset, uint64_t FSize) { uint64_t BundleSize = Assembler.getBundleAlignSize(); assert(BundleSize > 0 && "computeBundlePadding should only be called if bundling is enabled"); @@ -211,9 +278,8 @@ MCFragment::MCFragment() : Kind(FragmentType(~0)) { MCFragment::~MCFragment() { } -MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) - : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0)) -{ +MCFragment::MCFragment(FragmentType Kind, MCSectionData *Parent) + : Kind(Kind), Parent(Parent), Atom(nullptr), Offset(~UINT64_C(0)) { if (Parent) Parent->getFragmentList().push_back(this); } @@ -230,15 +296,12 @@ MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() { /* *** */ -MCSectionData::MCSectionData() : Section(0) {} +MCSectionData::MCSectionData() : Section(nullptr) {} -MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) - : Section(&_Section), - Ordinal(~UINT32_C(0)), - Alignment(1), - BundleLockState(NotBundleLocked), BundleGroupBeforeFirstInst(false), - HasInstructions(false) -{ +MCSectionData::MCSectionData(const MCSection &Section, MCAssembler *A) + : Section(&Section), Ordinal(~UINT32_C(0)), Alignment(1), + BundleLockState(NotBundleLocked), BundleLockNestingDepth(0), + BundleGroupBeforeFirstInst(false), HasInstructions(false) { if (A) A->getSectionList().push_back(this); } @@ -250,7 +313,7 @@ MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) { SmallVectorImpl >::iterator MI = std::lower_bound(SubsectionFragmentMap.begin(), SubsectionFragmentMap.end(), - std::make_pair(Subsection, (MCFragment *)0)); + std::make_pair(Subsection, (MCFragment *)nullptr)); bool ExactMatch = false; if (MI != SubsectionFragmentMap.end()) { ExactMatch = MI->first == Subsection; @@ -270,22 +333,44 @@ MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) { getFragmentList().insert(IP, F); F->setParent(this); } + return IP; } +void MCSectionData::setBundleLockState(BundleLockStateType NewState) { + if (NewState == NotBundleLocked) { + if (BundleLockNestingDepth == 0) { + report_fatal_error("Mismatched bundle_lock/unlock directives"); + } + if (--BundleLockNestingDepth == 0) { + BundleLockState = NotBundleLocked; + } + return; + } + + // If any of the directives is an align_to_end directive, the whole nested + // group is align_to_end. So don't downgrade from align_to_end to just locked. + if (BundleLockState != BundleLockedAlignToEnd) { + BundleLockState = NewState; + } + ++BundleLockNestingDepth; +} + /* *** */ -MCSymbolData::MCSymbolData() : Symbol(0) {} +MCSymbolData::MCSymbolData() : Symbol(nullptr) {} -MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, - uint64_t _Offset, MCAssembler *A) - : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset), - IsExternal(false), IsPrivateExtern(false), - CommonSize(0), SymbolSize(0), CommonAlign(0), - Flags(0), Index(0) -{ - if (A) - A->getSymbolList().push_back(this); +void MCSymbolData::initialize(const MCSymbol &Symbol, MCFragment *Fragment, + uint64_t Offset) { + assert(!isInitialized() && "Expected uninitialized symbol"); + + this->Symbol = &Symbol; + this->Fragment.setPointer(Fragment); + this->Offset = Offset; + this->SymbolSize = nullptr; + this->CommonAlign = -1U; + this->Flags = 0; + this->Index = 0; } /* *** */ @@ -293,9 +378,10 @@ MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, raw_ostream &OS_) - : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_), - OS(OS_), BundleAlignSize(0), RelaxAll(false), NoExecStack(false), - SubsectionsViaSymbols(false), ELFHeaderEFlags(0) { + : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_), + OS(OS_), BundleAlignSize(0), RelaxAll(false), + SubsectionsViaSymbols(false), ELFHeaderEFlags(0) { + VersionMinInfo.Major = 0; // Major version == 0 for "none specified" } MCAssembler::~MCAssembler() { @@ -305,19 +391,58 @@ void MCAssembler::reset() { Sections.clear(); Symbols.clear(); SectionMap.clear(); - SymbolMap.clear(); IndirectSymbols.clear(); DataRegions.clear(); + LinkerOptions.clear(); + FileNames.clear(); ThumbFuncs.clear(); + BundleAlignSize = 0; RelaxAll = false; - NoExecStack = false; SubsectionsViaSymbols = false; ELFHeaderEFlags = 0; + LOHContainer.reset(); + VersionMinInfo.Major = 0; // reset objects owned by us getBackend().reset(); getEmitter().reset(); getWriter().reset(); + getLOHContainer().reset(); +} + +bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const { + if (ThumbFuncs.count(Symbol)) + return true; + + if (!Symbol->isVariable()) + return false; + + // FIXME: It looks like gas supports some cases of the form "foo + 2". It + // is not clear if that is a bug or a feature. + const MCExpr *Expr = Symbol->getVariableValue(); + const MCSymbolRefExpr *Ref = dyn_cast(Expr); + if (!Ref) + return false; + + if (Ref->getKind() != MCSymbolRefExpr::VK_None) + return false; + + const MCSymbol &Sym = Ref->getSymbol(); + if (!isThumbFunc(&Sym)) + return false; + + ThumbFuncs.insert(Symbol); // Cache it. + return true; +} + +void MCAssembler::addLocalUsedInReloc(const MCSymbol &Sym) { + assert(Sym.isTemporary()); + LocalsUsedInReloc.insert(&Sym); +} + +bool MCAssembler::isLocalUsedInReloc(const MCSymbol &Sym) const { + assert(Sym.isTemporary()); + return LocalsUsedInReloc.count(&Sym); } bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const { @@ -329,24 +454,26 @@ bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const { if (!Symbol.isInSection()) return false; - // Otherwise, check if the section requires symbols even for temporary labels. - return getBackend().doesSectionRequireSymbols(Symbol.getSection()); + if (isLocalUsedInReloc(Symbol)) + return true; + + return false; } -const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const { +const MCSymbol *MCAssembler::getAtom(const MCSymbolData *SD) const { // Linker visible symbols define atoms. if (isSymbolLinkerVisible(SD->getSymbol())) - return SD; + return &SD->getSymbol(); // Absolute and undefined symbols have no defining atom. if (!SD->getFragment()) - return 0; + return nullptr; // Non-linker visible symbols in sections which can't be atomized have no // defining atom. - if (!getBackend().isSectionAtomizable( - SD->getFragment()->getParent()->getSection())) - return 0; + if (!getContext().getAsmInfo()->isSectionAtomizableBySymbols( + SD->getFragment()->getParent()->getSection())) + return nullptr; // Otherwise, return the atom for the containing fragment. return SD->getFragment()->getAtom(); @@ -357,8 +484,12 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, MCValue &Target, uint64_t &Value) const { ++stats::evaluateFixup; - if (!Fixup.getValue()->EvaluateAsRelocatable(Target, Layout)) - getContext().FatalError(Fixup.getLoc(), "expected relocatable expression"); + // FIXME: This code has some duplication with RecordRelocation. We should + // probably merge the two into a single callback that tries to evaluate a + // fixup and records a relocation if one is needed. + const MCExpr *Expr = Fixup.getValue(); + if (!Expr->EvaluateAsRelocatable(Target, &Layout, &Fixup)) + getContext().reportFatalError(Fixup.getLoc(), "expected relocatable expression"); bool IsPCRel = Backend.getFixupKindInfo( Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; @@ -372,14 +503,11 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, } else { const MCSymbolRefExpr *A = Target.getSymA(); const MCSymbol &SA = A->getSymbol(); - if (A->getKind() != MCSymbolRefExpr::VK_None || - SA.AliasedSymbol().isUndefined()) { + if (A->getKind() != MCSymbolRefExpr::VK_None || SA.isUndefined()) { IsResolved = false; } else { - const MCSymbolData &DataA = getSymbolData(SA); - IsResolved = - getWriter().IsSymbolRefDifferenceFullyResolvedImpl(*this, DataA, - *DF, false, true); + IsResolved = getWriter().IsSymbolRefDifferenceFullyResolvedImpl( + *this, SA, *DF, false, true); } } } else { @@ -389,12 +517,12 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, Value = Target.getConstant(); if (const MCSymbolRefExpr *A = Target.getSymA()) { - const MCSymbol &Sym = A->getSymbol().AliasedSymbol(); + const MCSymbol &Sym = A->getSymbol(); if (Sym.isDefined()) Value += Layout.getSymbolOffset(&getSymbolData(Sym)); } if (const MCSymbolRefExpr *B = Target.getSymB()) { - const MCSymbol &Sym = B->getSymbol().AliasedSymbol(); + const MCSymbol &Sym = B->getSymbol(); if (Sym.isDefined()) Value -= Layout.getSymbolOffset(&getSymbolData(Sym)); } @@ -509,7 +637,12 @@ void MCAsmLayout::layoutFragment(MCFragment *F) { // The fragment's offset will point to after the padding, and its computed // size won't include the padding. // - if (Assembler.isBundlingEnabled() && F->hasInstructions()) { + // When the -mc-relax-all flag is used, we optimize bundling by writting the + // bundle padding directly into fragments when the instructions are emitted + // inside the streamer. + // + if (Assembler.isBundlingEnabled() && !Assembler.getRelaxAll() && + F->hasInstructions()) { assert(isa(F) && "Only MCEncodedFragment implementations have instructions"); uint64_t FSize = Assembler.computeFragmentSize(*this, *F); @@ -517,7 +650,8 @@ void MCAsmLayout::layoutFragment(MCFragment *F) { if (FSize > Assembler.getBundleAlignSize()) report_fatal_error("Fragment can't be larger than a bundle size"); - uint64_t RequiredBundlePadding = computeBundlePadding(F, F->Offset, FSize); + uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F, + F->Offset, FSize); if (RequiredBundlePadding > UINT8_MAX) report_fatal_error("Padding cannot exceed 255 bytes"); F->setBundlePadding(static_cast(RequiredBundlePadding)); @@ -532,24 +666,18 @@ static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) { OW->WriteBytes(EF.getContents()); } -/// \brief Write the fragment \p F to the output file. -static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment &F) { - MCObjectWriter *OW = &Asm.getWriter(); - - // FIXME: Embed in fragments instead? - uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); - +void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize, + MCObjectWriter *OW) const { // Should NOP padding be written out before this fragment? unsigned BundlePadding = F.getBundlePadding(); if (BundlePadding > 0) { - assert(Asm.isBundlingEnabled() && + assert(isBundlingEnabled() && "Writing bundle padding with disabled bundling"); assert(F.hasInstructions() && "Writing bundle padding for a fragment without instructions"); - unsigned TotalLength = BundlePadding + static_cast(FragmentSize); - if (F.alignToBundleEnd() && TotalLength > Asm.getBundleAlignSize()) { + unsigned TotalLength = BundlePadding + static_cast(FSize); + if (F.alignToBundleEnd() && TotalLength > getBundleAlignSize()) { // If the padding itself crosses a bundle boundary, it must be emitted // in 2 pieces, since even nop instructions must not cross boundaries. // v--------------v <- BundleAlignSize @@ -558,16 +686,27 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, // | Prev |####|####| F | // ---------------------------- // ^-------------------^ <- TotalLength - unsigned DistanceToBoundary = TotalLength - Asm.getBundleAlignSize(); - if (!Asm.getBackend().writeNopData(DistanceToBoundary, OW)) + unsigned DistanceToBoundary = TotalLength - getBundleAlignSize(); + if (!getBackend().writeNopData(DistanceToBoundary, OW)) report_fatal_error("unable to write NOP sequence of " + Twine(DistanceToBoundary) + " bytes"); BundlePadding -= DistanceToBoundary; } - if (!Asm.getBackend().writeNopData(BundlePadding, OW)) + if (!getBackend().writeNopData(BundlePadding, OW)) report_fatal_error("unable to write NOP sequence of " + Twine(BundlePadding) + " bytes"); } +} + +/// \brief Write the fragment \p F to the output file. +static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment &F) { + MCObjectWriter *OW = &Asm.getWriter(); + + // FIXME: Embed in fragments instead? + uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); + + Asm.writeFragmentPadding(F, FragmentSize, OW); // This variable (and its dummy usage) is to participate in the assert at // the end of the function. @@ -652,7 +791,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, case MCFragment::FT_LEB: { const MCLEBFragment &LF = cast(F); - OW->WriteBytes(LF.getContents().str()); + OW->WriteBytes(LF.getContents()); break; } @@ -668,12 +807,12 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, case MCFragment::FT_Dwarf: { const MCDwarfLineAddrFragment &OF = cast(F); - OW->WriteBytes(OF.getContents().str()); + OW->WriteBytes(OF.getContents()); break; } case MCFragment::FT_DwarfFrame: { const MCDwarfCallFrameFragment &CF = cast(F); - OW->WriteBytes(CF.getContents().str()); + OW->WriteBytes(CF.getContents()); break; } } @@ -701,8 +840,13 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, assert(DF.fixup_begin() == DF.fixup_end() && "Cannot have fixups in virtual section!"); for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i) - assert(DF.getContents()[i] == 0 && - "Invalid data value for virtual section!"); + if (DF.getContents()[i]) { + if (auto *ELFSec = dyn_cast(&SD->getSection())) + report_fatal_error("non-zero initializer found in section '" + + ELFSec->getSectionName() + "'"); + else + report_fatal_error("non-zero initializer found in virtual section"); + } break; } case MCFragment::FT_Align: @@ -734,20 +878,22 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, Layout.getSectionAddressSize(SD)); } - -uint64_t MCAssembler::handleFixup(const MCAsmLayout &Layout, - MCFragment &F, - const MCFixup &Fixup) { +std::pair MCAssembler::handleFixup(const MCAsmLayout &Layout, + MCFragment &F, + const MCFixup &Fixup) { // Evaluate the fixup. MCValue Target; uint64_t FixedValue; + bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; if (!evaluateFixup(Layout, Fixup, &F, Target, FixedValue)) { // The fixup was unresolved, we need a relocation. Inform the object // writer of the relocation, and give it an opportunity to adjust the // fixup value if need be. - getWriter().RecordRelocation(*this, Layout, &F, Fixup, Target, FixedValue); + getWriter().RecordRelocation(*this, Layout, &F, Fixup, Target, IsPCRel, + FixedValue); } - return FixedValue; + return std::make_pair(FixedValue, IsPCRel); } void MCAssembler::Finish() { @@ -811,9 +957,11 @@ void MCAssembler::Finish() { for (MCEncodedFragmentWithFixups::fixup_iterator it3 = F->fixup_begin(), ie3 = F->fixup_end(); it3 != ie3; ++it3) { MCFixup &Fixup = *it3; - uint64_t FixedValue = handleFixup(Layout, *F, Fixup); + uint64_t FixedValue; + bool IsPCRel; + std::tie(FixedValue, IsPCRel) = handleFixup(Layout, *F, Fixup); getBackend().applyFixup(Fixup, F->getContents().data(), - F->getContents().size(), FixedValue); + F->getContents().size(), FixedValue, IsPCRel); } } } @@ -875,7 +1023,7 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, SmallVector Fixups; SmallString<256> Code; raw_svector_ostream VecOS(Code); - getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups); + getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo()); VecOS.flush(); // Update the fragment. @@ -887,11 +1035,11 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, } bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { - int64_t Value = 0; uint64_t OldSize = LF.getContents().size(); - bool IsAbs = LF.getValue().EvaluateAsAbsolute(Value, Layout); - (void)IsAbs; - assert(IsAbs); + int64_t Value; + bool Abs = LF.getValue().evaluateKnownAbsolute(Value, Layout); + if (!Abs) + report_fatal_error("sleb128 and uleb128 expressions must be absolute"); SmallString<8> &Data = LF.getContents(); Data.clear(); raw_svector_ostream OSE(Data); @@ -906,11 +1054,11 @@ bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF) { MCContext &Context = Layout.getAssembler().getContext(); - int64_t AddrDelta = 0; uint64_t OldSize = DF.getContents().size(); - bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout); - (void)IsAbs; - assert(IsAbs); + int64_t AddrDelta; + bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout); + assert(Abs && "We created a line delta with an invalid expression"); + (void) Abs; int64_t LineDelta; LineDelta = DF.getLineDelta(); SmallString<8> &Data = DF.getContents(); @@ -924,11 +1072,11 @@ bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout, bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout, MCDwarfCallFrameFragment &DF) { MCContext &Context = Layout.getAssembler().getContext(); - int64_t AddrDelta = 0; uint64_t OldSize = DF.getContents().size(); - bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout); - (void)IsAbs; - assert(IsAbs); + int64_t AddrDelta; + bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout); + assert(Abs && "We created call frame with an invalid expression"); + (void) Abs; SmallString<8> &Data = DF.getContents(); Data.clear(); raw_svector_ostream OSE(Data); @@ -942,7 +1090,7 @@ bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { // remain NULL if none were relaxed. // When a fragment is relaxed, all the fragments following it should get // invalidated because their offset is going to change. - MCFragment *FirstRelaxedFragment = NULL; + MCFragment *FirstRelaxedFragment = nullptr; // Attempt to relax all the fragments in the section. for (MCSectionData::iterator I = SD.begin(), IE = SD.end(); I != IE; ++I) { @@ -1137,12 +1285,14 @@ void MCSectionData::dump() { OS << "]>"; } -void MCSymbolData::dump() { +void MCSymbolData::dump() const { raw_ostream &OS = llvm::errs(); OS << "