MCFragment::MCFragment() : Kind(FragmentType(~0)) {
}
+MCFragment::~MCFragment() {
+}
+
MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
- : Kind(_Kind), Parent(_Parent), Atom(0), EffectiveSize(~UINT64_C(0))
+ : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0)),
+ EffectiveSize(~UINT64_C(0))
{
if (Parent)
Parent->getFragmentList().push_back(this);
uint64_t _Offset, MCAssembler *A)
: Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset),
IsExternal(false), IsPrivateExtern(false),
- CommonSize(0), CommonAlign(0), Flags(0), Index(0)
+ CommonSize(0), SymbolSize(0), CommonAlign(0),
+ Flags(0), Index(0)
{
if (A)
A->getSymbolList().push_back(this);
return !B_Base && BaseSymbol == A_Base;
}
-bool MCAssembler::isSymbolLinkerVisible(const MCSymbolData *SD) const {
+bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
// Non-temporary labels should always be visible to the linker.
- if (!SD->getSymbol().isTemporary())
+ if (!Symbol.isTemporary())
return true;
// Absolute temporary labels are never visible.
- if (!SD->getFragment())
+ if (!Symbol.isInSection())
return false;
// Otherwise, check if the section requires symbols even for temporary labels.
- return getBackend().doesSectionRequireSymbols(
- SD->getFragment()->getParent()->getSection());
+ return getBackend().doesSectionRequireSymbols(Symbol.getSection());
}
const MCSymbolData *MCAssembler::getAtom(const MCAsmLayout &Layout,
const MCSymbolData *SD) const {
// Linker visible symbols define atoms.
- if (isSymbolLinkerVisible(SD))
+ if (isSymbolLinkerVisible(SD->getSymbol()))
return SD;
// Absolute and undefined symbols have no defining atom.
// FIXME: We need a way to communicate this error.
int64_t Offset = TargetLocation - FragmentOffset;
- if (Offset < 0)
+ if (Offset < 0 || Offset >= 0x40000000)
report_fatal_error("invalid .org offset '" + Twine(TargetLocation) +
"' (at offset '" + Twine(FragmentOffset) + "'");
switch (it->getKind()) {
default:
assert(0 && "Invalid fragment in virtual section!");
+ case MCFragment::FT_Data: {
+ // Check that we aren't trying to write a non-zero contents (or fixups)
+ // into a virtual section. This is to support clients which use standard
+ // directives to fill the contents of virtual sections.
+ MCDataFragment &DF = cast<MCDataFragment>(*it);
+ 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!");
+ break;
+ }
case MCFragment::FT_Align:
- assert(!cast<MCAlignFragment>(it)->getValueSize() &&
+ // Check that we aren't trying to write a non-zero value into a virtual
+ // section.
+ assert((!cast<MCAlignFragment>(it)->getValueSize() ||
+ !cast<MCAlignFragment>(it)->getValue()) &&
"Invalid align in virtual section!");
break;
case MCFragment::FT_Fill:
assert(OW->getStream().tell() - Start == Layout.getSectionFileSize(SD));
}
-void MCAssembler::Finish() {
+void MCAssembler::AddSectionToTheEnd(MCSectionData &SD, MCAsmLayout &Layout) {
+ // Create dummy fragments and assign section ordinals.
+ unsigned SectionIndex = 0;
+ for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it)
+ SectionIndex++;
+
+ SD.setOrdinal(SectionIndex);
+
+ // Assign layout order indices to sections and fragments.
+ unsigned FragmentIndex = 0;
+ unsigned i = 0;
+ for (unsigned e = Layout.getSectionOrder().size(); i != e; ++i) {
+ MCSectionData *SD = Layout.getSectionOrder()[i];
+
+ for (MCSectionData::iterator it2 = SD->begin(),
+ ie2 = SD->end(); it2 != ie2; ++it2)
+ FragmentIndex++;
+ }
+
+ SD.setLayoutOrder(i);
+ for (MCSectionData::iterator it2 = SD.begin(),
+ ie2 = SD.end(); it2 != ie2; ++it2) {
+ it2->setLayoutOrder(FragmentIndex++);
+ }
+ Layout.getSectionOrder().push_back(&SD);
+
+ Layout.LayoutSection(&SD);
+
+ // Layout until everything fits.
+ while (LayoutOnce(Layout))
+ continue;
+
+}
+
+void MCAssembler::Finish(MCObjectWriter *Writer) {
DEBUG_WITH_TYPE("mc-dump", {
llvm::errs() << "assembler backend - pre-layout\n--\n";
dump(); });
for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) {
// Create dummy fragments to eliminate any empty sections, this simplifies
// layout.
- if (it->getFragmentList().empty()) {
- unsigned ValueSize = 1;
- if (getBackend().isVirtualSection(it->getSection()))
- ValueSize = 1;
- new MCFillFragment(0, 1, 0, it);
- }
+ if (it->getFragmentList().empty())
+ new MCDataFragment(it);
it->setOrdinal(SectionIndex++);
}
dump(); });
uint64_t StartOffset = OS.tell();
- llvm::OwningPtr<MCObjectWriter> Writer(getBackend().createObjectWriter(OS));
- if (!Writer)
- report_fatal_error("unable to create object writer!");
+
+ llvm::OwningPtr<MCObjectWriter> OwnWriter(0);
+ if (Writer == 0) {
+ //no custom Writer_ : create the default one life-managed by OwningPtr
+ OwnWriter.reset(getBackend().createObjectWriter(OS));
+ Writer = OwnWriter.get();
+ if (!Writer)
+ report_fatal_error("unable to create object writer!");
+ }
// Allow the object writer a chance to perform post-layout binding (for
// example, to set the index fields in the symbol data).
// Write the object file.
Writer->WriteObject(*this, Layout);
- OS.flush();
stats::ObjectBytes += OS.tell() - StartOffset;
}
for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
IF->getFixups().push_back(Fixups[i]);
- // Update the layout, and remember that we relaxed. If we are relaxing
- // everything, we can skip this step since nothing will depend on updating
- // the values.
- if (!getRelaxAll())
- Layout.UpdateForSlide(IF, SlideAmount);
+ // Update the layout, and remember that we relaxed.
+ Layout.UpdateForSlide(IF, SlideAmount);
WasRelaxed = true;
}
}