#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"
#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"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
-
+#include <tuple>
using namespace llvm;
#define DEBUG_TYPE "assembler"
{
// Compute the section layout order. Virtual sections must go last.
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
- if (!it->getSection().isVirtualSection())
+ if (!it->isVirtualSection())
SectionOrder.push_back(&*it);
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
- if (it->getSection().isVirtualSection())
+ if (it->isVirtualSection())
SectionOrder.push_back(&*it);
}
bool MCAsmLayout::isFragmentValid(const MCFragment *F) const {
- const MCSectionData &SD = *F->getParent();
- const MCFragment *LastValid = LastValidFragment.lookup(&SD);
+ const MCSection *Sec = F->getParent();
+ const MCFragment *LastValid = LastValidFragment.lookup(Sec);
if (!LastValid)
return false;
- assert(LastValid->getParent() == F->getParent());
+ assert(LastValid->getParent() == Sec);
return F->getLayoutOrder() <= LastValid->getLayoutOrder();
}
// Otherwise, reset the last valid fragment to the previous fragment
// (if this is the first fragment, it will be NULL).
- const MCSectionData &SD = *F->getParent();
- LastValidFragment[&SD] = F->getPrevNode();
+ LastValidFragment[F->getParent()] = F->getPrevNode();
}
void MCAsmLayout::ensureValid(const MCFragment *F) const {
- MCSectionData &SD = *F->getParent();
-
- MCFragment *Cur = LastValidFragment[&SD];
+ MCSection *Sec = F->getParent();
+ MCFragment *Cur = LastValidFragment[Sec];
if (!Cur)
- Cur = &*SD.begin();
+ Cur = Sec->begin();
else
Cur = Cur->getNextNode();
return F->Offset;
}
-uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const {
- 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 '" +
+// Simple getSymbolOffset helper for the non-varibale case.
+static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S,
+ bool ReportError, uint64_t &Val) {
+ const MCSymbolData &SD = S.getData();
+ if (!SD.getFragment()) {
+ if (ReportError)
+ report_fatal_error("unable to evaluate offset to undefined symbol '" +
S.getName() + "'");
+ return false;
+ }
+ Val = Layout.getFragmentOffset(SD.getFragment()) + S.getOffset();
+ return true;
+}
- // 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;
+static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S,
+ bool ReportError, uint64_t &Val) {
+ if (!S.isVariable())
+ return getLabelOffset(Layout, S, ReportError, Val);
+
+ // 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 MCSymbolRefExpr *A = Target.getSymA();
+ if (A) {
+ uint64_t ValA;
+ if (!getLabelOffset(Layout, A->getSymbol(), ReportError, ValA))
+ return false;
+ Offset += ValA;
}
- assert(SD->getFragment() && "Invalid getOffset() on undefined symbol!");
- return getFragmentOffset(SD->getFragment()) + SD->getOffset();
+ const MCSymbolRefExpr *B = Target.getSymB();
+ if (B) {
+ uint64_t ValB;
+ if (!getLabelOffset(Layout, B->getSymbol(), ReportError, ValB))
+ return false;
+ Offset -= ValB;
+ }
+
+ Val = Offset;
+ return true;
+}
+
+bool MCAsmLayout::getSymbolOffset(const MCSymbol &S, uint64_t &Val) const {
+ return getSymbolOffsetImpl(*this, S, false, Val);
+}
+
+uint64_t MCAsmLayout::getSymbolOffset(const MCSymbol &S) const {
+ uint64_t Val;
+ getSymbolOffsetImpl(*this, S, true, Val);
+ return Val;
}
-uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {
+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();
+ if (ASym.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 MCSection *Sec) const {
// The size is the last fragment's end offset.
- const MCFragment &F = SD->getFragmentList().back();
+ const MCFragment &F = Sec->getFragmentList().back();
return getFragmentOffset(&F) + getAssembler().computeFragmentSize(*this, F);
}
-uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
+uint64_t MCAsmLayout::getSectionFileSize(const MCSection *Sec) const {
// Virtual sections have no file size.
- if (SD->getSection().isVirtualSection())
+ if (Sec->isVirtualSection())
return 0;
// Otherwise, the file size is the same as the address space size.
- return getSectionAddressSize(SD);
+ return getSectionAddressSize(Sec);
}
-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");
MCFragment::~MCFragment() {
}
-MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
- : Kind(_Kind), Parent(_Parent), Atom(nullptr), Offset(~UINT64_C(0))
-{
+MCFragment::MCFragment(FragmentType Kind, MCSection *Parent)
+ : Kind(Kind), Parent(Parent), Atom(nullptr), Offset(~UINT64_C(0)) {
if (Parent)
Parent->getFragmentList().push_back(this);
}
/* *** */
-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)
-{
- if (A)
- A->getSectionList().push_back(this);
-}
-
-MCSectionData::iterator
-MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) {
- if (Subsection == 0 && SubsectionFragmentMap.empty())
- return end();
-
- SmallVectorImpl<std::pair<unsigned, MCFragment *> >::iterator MI =
- std::lower_bound(SubsectionFragmentMap.begin(), SubsectionFragmentMap.end(),
- std::make_pair(Subsection, (MCFragment *)nullptr));
- bool ExactMatch = false;
- if (MI != SubsectionFragmentMap.end()) {
- ExactMatch = MI->first == Subsection;
- if (ExactMatch)
- ++MI;
- }
- iterator IP;
- if (MI == SubsectionFragmentMap.end())
- IP = end();
- else
- IP = MI->second;
- if (!ExactMatch && Subsection != 0) {
- // The GNU as documentation claims that subsections have an alignment of 4,
- // although this appears not to be the case.
- MCFragment *F = new MCDataFragment();
- SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F));
- getFragmentList().insert(IP, F);
- F->setParent(this);
- }
- return IP;
-}
-
-/* *** */
-
-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(nullptr), CommonAlign(0),
- Flags(0), Index(0)
-{
- if (A)
- A->getSymbolList().push_back(this);
-}
-
-/* *** */
-
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"
}
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();
if (!Symbol->isVariable())
return false;
- // FIXME: It looks like gas support some cases of the form "foo + 2". It
+ // 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<MCSymbolRefExpr>(Expr);
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 {
// Non-temporary labels should always be visible to the linker.
if (!Symbol.isTemporary())
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 MCSymbol &S) const {
// Linker visible symbols define atoms.
- if (isSymbolLinkerVisible(SD->getSymbol()))
- return SD;
+ if (isSymbolLinkerVisible(S))
+ return &S;
// Absolute and undefined symbols have no defining atom.
- if (!SD->getFragment())
+ if (!S.getData().getFragment())
return nullptr;
// Non-linker visible symbols in sections which can't be atomized have no
// defining atom.
- if (!getBackend().isSectionAtomizable(
- SD->getFragment()->getParent()->getSection()))
+ if (!getContext().getAsmInfo()->isSectionAtomizableBySymbols(
+ *S.getData().getFragment()->getParent()))
return nullptr;
// Otherwise, return the atom for the containing fragment.
- return SD->getFragment()->getAtom();
+ return S.getData().getFragment()->getAtom();
}
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;
} 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 {
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));
+ Value += Layout.getSymbolOffset(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));
+ Value -= Layout.getSymbolOffset(Sym);
}
// 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<MCEncodedFragment>(F) &&
"Only MCEncodedFragment implementations have instructions");
uint64_t FSize = Assembler.computeFragmentSize(*this, *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<uint8_t>(RequiredBundlePadding));
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<unsigned>(FragmentSize);
- if (F.alignToBundleEnd() && TotalLength > Asm.getBundleAlignSize()) {
+ unsigned TotalLength = BundlePadding + static_cast<unsigned>(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
// | 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.
case MCFragment::FT_LEB: {
const MCLEBFragment &LF = cast<MCLEBFragment>(F);
- OW->WriteBytes(LF.getContents().str());
+ OW->WriteBytes(LF.getContents());
break;
}
case MCFragment::FT_Dwarf: {
const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F);
- OW->WriteBytes(OF.getContents().str());
+ OW->WriteBytes(OF.getContents());
break;
}
case MCFragment::FT_DwarfFrame: {
const MCDwarfCallFrameFragment &CF = cast<MCDwarfCallFrameFragment>(F);
- OW->WriteBytes(CF.getContents().str());
+ OW->WriteBytes(CF.getContents());
break;
}
}
"The stream should advance by fragment size");
}
-void MCAssembler::writeSectionData(const MCSectionData *SD,
+void MCAssembler::writeSectionData(const MCSection *Sec,
const MCAsmLayout &Layout) const {
// Ignore virtual sections.
- if (SD->getSection().isVirtualSection()) {
- assert(Layout.getSectionFileSize(SD) == 0 && "Invalid size for section!");
+ if (Sec->isVirtualSection()) {
+ assert(Layout.getSectionFileSize(Sec) == 0 && "Invalid size for section!");
// Check that contents are only things legal inside a virtual section.
- for (MCSectionData::const_iterator it = SD->begin(),
- ie = SD->end(); it != ie; ++it) {
+ for (MCSection::const_iterator it = Sec->begin(), ie = Sec->end(); it != ie;
+ ++it) {
switch (it->getKind()) {
default: llvm_unreachable("Invalid fragment in virtual section!");
case MCFragment::FT_Data: {
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<const MCSectionELF>(Sec))
+ 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:
uint64_t Start = getWriter().getStream().tell();
(void)Start;
- for (MCSectionData::const_iterator it = SD->begin(), ie = SD->end();
- it != ie; ++it)
+ for (MCSection::const_iterator it = Sec->begin(), ie = Sec->end(); it != ie;
+ ++it)
writeFragment(*this, Layout, *it);
assert(getWriter().getStream().tell() - Start ==
- Layout.getSectionAddressSize(SD));
+ Layout.getSectionAddressSize(Sec));
}
std::pair<uint64_t, bool> MCAssembler::handleFixup(const MCAsmLayout &Layout,
// Create dummy fragments to eliminate any empty sections, this simplifies
// layout.
if (it->getFragmentList().empty())
- new MCDataFragment(it);
+ new MCDataFragment(&*it);
it->setOrdinal(SectionIndex++);
}
// Assign layout order indices to sections and fragments.
for (unsigned i = 0, e = Layout.getSectionOrder().size(); i != e; ++i) {
- MCSectionData *SD = Layout.getSectionOrder()[i];
- SD->setLayoutOrder(i);
+ MCSection *Sec = Layout.getSectionOrder()[i];
+ Sec->setLayoutOrder(i);
unsigned FragmentIndex = 0;
- for (MCSectionData::iterator iFrag = SD->begin(), iFragEnd = SD->end();
+ for (MCSection::iterator iFrag = Sec->begin(), iFragEnd = Sec->end();
iFrag != iFragEnd; ++iFrag)
iFrag->setLayoutOrder(FragmentIndex++);
}
// Evaluate and apply the fixups, generating relocation entries as necessary.
for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) {
- for (MCSectionData::iterator it2 = it->begin(),
- ie2 = it->end(); it2 != ie2; ++it2) {
+ for (MCSection::iterator it2 = it->begin(), ie2 = it->end(); it2 != ie2;
+ ++it2) {
MCEncodedFragmentWithFixups *F =
dyn_cast<MCEncodedFragmentWithFixups>(it2);
if (F) {
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
- getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo());
+ getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo());
VecOS.flush();
// Update the fragment.
}
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);
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();
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);
return OldSize != Data.size();
}
-bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) {
+bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec) {
// Holds the first fragment which needed relaxing during this layout. It will
// remain NULL if none were relaxed.
// When a fragment is relaxed, all the fragments following it should get
MCFragment *FirstRelaxedFragment = nullptr;
// Attempt to relax all the fragments in the section.
- for (MCSectionData::iterator I = SD.begin(), IE = SD.end(); I != IE; ++I) {
+ for (MCSection::iterator I = Sec.begin(), IE = Sec.end(); I != IE; ++I) {
// Check if this is a fragment that needs relaxation.
bool RelaxedFrag = false;
switch(I->getKind()) {
bool WasRelaxed = false;
for (iterator it = begin(), ie = end(); it != ie; ++it) {
- MCSectionData &SD = *it;
- while (layoutSectionOnce(Layout, SD))
+ MCSection &Sec = *it;
+ while (layoutSectionOnce(Layout, Sec))
WasRelaxed = true;
}
OS << ">";
}
-void MCSectionData::dump() {
- raw_ostream &OS = llvm::errs();
-
- OS << "<MCSectionData";
- OS << " Alignment:" << getAlignment()
- << " Fragments:[\n ";
- for (iterator it = begin(), ie = end(); it != ie; ++it) {
- if (it != begin()) OS << ",\n ";
- it->dump();
- }
- OS << "]>";
-}
-
-void MCSymbolData::dump() {
+void MCSymbolData::dump() const {
raw_ostream &OS = llvm::errs();
- OS << "<MCSymbolData Symbol:" << getSymbol()
- << " Fragment:" << getFragment() << " Offset:" << getOffset()
- << " Flags:" << getFlags() << " Index:" << getIndex();
- if (isCommon())
- OS << " (common, size:" << getCommonSize()
- << " align: " << getCommonAlignment() << ")";
+ OS << "<MCSymbolData"
+ << " Fragment:" << getFragment();
+ OS << " Flags:" << getFlags();
if (isExternal())
OS << " (external)";
if (isPrivateExtern())
for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) {
if (it != symbol_begin()) OS << ",\n ";
+ OS << "(";
it->dump();
+ OS << ", Index:" << it->getIndex() << ", ";
+ it->getData().dump();
+ OS << ")";
}
OS << "]>\n";
}