aboutsummaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/ELFObjectWriter.cpp14
-rw-r--r--lib/MC/MCAssembler.cpp122
-rw-r--r--lib/MC/MCELFStreamer.cpp2
-rw-r--r--lib/MC/MCExpr.cpp59
-rw-r--r--lib/MC/MCMachOStreamer.cpp2
-rw-r--r--lib/MC/MCObjectStreamer.cpp4
-rw-r--r--lib/MC/MCPureStreamer.cpp3
-rw-r--r--lib/MC/MachObjectWriter.cpp101
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp7
-rw-r--r--lib/MC/WinCOFFStreamer.cpp2
10 files changed, 156 insertions, 160 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 4daab49089..b51e508ab2 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -325,7 +325,8 @@ namespace {
virtual void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout,
GroupMapTy &GroupMap, RevGroupMapTy &RevGroupMap);
- virtual void ExecutePostLayoutBinding(MCAssembler &Asm);
+ virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout);
virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
uint64_t Address, uint64_t Offset,
@@ -557,7 +558,8 @@ static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout) {
return 0;
}
-void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) {
+void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
// The presence of symbol versions causes undefined symbols and
// versions declared with @@@ to be renamed.
@@ -1365,11 +1367,11 @@ static uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
return Layout.getSectionFileSize(&SD);
}
-static uint64_t GetSectionSize(const MCAsmLayout &Layout,
- const MCSectionData &SD) {
+static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout,
+ const MCSectionData &SD) {
if (IsELFMetaDataSection(SD))
return DataSectionSize(SD);
- return Layout.getSectionSize(&SD);
+ return Layout.getSectionAddressSize(&SD);
}
static void WriteDataSectionData(ELFObjectWriter *W, const MCSectionData &SD) {
@@ -1479,7 +1481,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
else
GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]);
- uint64_t Size = GetSectionSize(Layout, SD);
+ uint64_t Size = GetSectionAddressSize(Layout, SD);
WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
SectionOffsetMap[&Section], Size,
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 299eb0ab67..4f63a081ae 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -38,7 +38,6 @@ STATISTIC(FragmentLayouts, "Number of fragment layouts");
STATISTIC(ObjectBytes, "Number of emitted object file bytes");
STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps");
STATISTIC(RelaxedInstructions, "Number of relaxed instructions");
-STATISTIC(SectionLayouts, "Number of section layouts");
}
}
@@ -113,11 +112,6 @@ void MCAsmLayout::EnsureValid(const MCFragment *F) const {
}
}
-uint64_t MCAsmLayout::getFragmentAddress(const MCFragment *F) const {
- assert(F->getParent() && "Missing section()!");
- return getSectionAddress(F->getParent()) + getFragmentOffset(F);
-}
-
uint64_t MCAsmLayout::getFragmentEffectiveSize(const MCFragment *F) const {
EnsureValid(F);
assert(F->EffectiveSize != ~UINT64_C(0) && "Address not set!");
@@ -135,17 +129,6 @@ uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const {
return getFragmentOffset(SD->getFragment()) + SD->getOffset();
}
-uint64_t MCAsmLayout::getSymbolAddress(const MCSymbolData *SD) const {
- assert(SD->getFragment() && "Invalid getAddress() on undefined symbol!");
- return getFragmentAddress(SD->getFragment()) + SD->getOffset();
-}
-
-uint64_t MCAsmLayout::getSectionAddress(const MCSectionData *SD) const {
- EnsureValid(SD->begin());
- assert(SD->Address != ~UINT64_C(0) && "Address not set!");
- return SD->Address;
-}
-
uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {
// The size is the last fragment's end offset.
const MCFragment &F = SD->getFragmentList().back();
@@ -161,17 +144,6 @@ uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
return getSectionAddressSize(SD);
}
-uint64_t MCAsmLayout::getSectionSize(const MCSectionData *SD) const {
- // The logical size is the address space size minus any tail padding.
- uint64_t Size = getSectionAddressSize(SD);
- const MCAlignFragment *AF =
- dyn_cast<MCAlignFragment>(&(SD->getFragmentList().back()));
- if (AF && AF->hasOnlyAlignAddress())
- Size -= getFragmentEffectiveSize(AF);
-
- return Size;
-}
-
/* *** */
MCFragment::MCFragment() : Kind(FragmentType(~0)) {
@@ -196,7 +168,6 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
: Section(&_Section),
Ordinal(~UINT32_C(0)),
Alignment(1),
- Address(~UINT64_C(0)),
HasInstructions(false)
{
if (A)
@@ -221,11 +192,9 @@ MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment,
/* *** */
MCAssembler::MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
- MCCodeEmitter &_Emitter, bool _PadSectionToAlignment,
- raw_ostream &_OS)
+ MCCodeEmitter &_Emitter, raw_ostream &_OS)
: Context(_Context), Backend(_Backend), Emitter(_Emitter),
- OS(_OS), RelaxAll(false), SubsectionsViaSymbols(false),
- PadSectionToAlignment(_PadSectionToAlignment)
+ OS(_OS), RelaxAll(false), SubsectionsViaSymbols(false)
{
}
@@ -285,14 +254,14 @@ bool MCAssembler::EvaluateFixup(const MCObjectWriter &Writer,
if (const MCSymbolRefExpr *A = Target.getSymA()) {
const MCSymbol &Sym = A->getSymbol().AliasedSymbol();
if (Sym.isDefined())
- Value += Layout.getSymbolAddress(&getSymbolData(Sym));
+ Value += Layout.getSymbolOffset(&getSymbolData(Sym));
else
IsResolved = false;
}
if (const MCSymbolRefExpr *B = Target.getSymB()) {
const MCSymbol &Sym = B->getSymbol().AliasedSymbol();
if (Sym.isDefined())
- Value -= Layout.getSymbolAddress(&getSymbolData(Sym));
+ Value -= Layout.getSymbolOffset(&getSymbolData(Sym));
else
IsResolved = false;
}
@@ -301,13 +270,12 @@ bool MCAssembler::EvaluateFixup(const MCObjectWriter &Writer,
IsResolved = Writer.IsFixupFullyResolved(*this, Target, IsPCRel, DF);
if (IsPCRel)
- Value -= Layout.getFragmentAddress(DF) + Fixup.getOffset();
+ Value -= Layout.getFragmentOffset(DF) + Fixup.getOffset();
return IsResolved;
}
uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F,
- uint64_t SectionAddress,
uint64_t FragmentOffset) const {
switch (F.getKind()) {
case MCFragment::FT_Data:
@@ -323,11 +291,7 @@ uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F,
case MCFragment::FT_Align: {
const MCAlignFragment &AF = cast<MCAlignFragment>(F);
- assert((!AF.hasOnlyAlignAddress() || !AF.getNextNode()) &&
- "Invalid OnlyAlignAddress bit, not the last fragment!");
-
- uint64_t Size = OffsetToAlignment(SectionAddress + FragmentOffset,
- AF.getAlignment());
+ uint64_t Size = OffsetToAlignment(FragmentOffset, AF.getAlignment());
// Honor MaxBytesToEmit.
if (Size > AF.getMaxBytesToEmit())
@@ -351,8 +315,6 @@ void MCAsmLayout::LayoutFile() {
// Initialize the first section and set the valid fragment layout point. All
// actual layout computations are done lazily.
LastValidFragment = 0;
- if (!getSectionOrder().empty())
- getSectionOrder().front()->Address = 0;
}
void MCAsmLayout::LayoutFragment(MCFragment *F) {
@@ -371,43 +333,14 @@ void MCAsmLayout::LayoutFragment(MCFragment *F) {
++stats::FragmentLayouts;
- // Compute the fragment start address.
- uint64_t StartAddress = F->getParent()->Address;
- uint64_t Address = StartAddress;
+ // Compute fragment offset and size.
+ uint64_t Offset = 0;
if (Prev)
- Address += Prev->Offset + Prev->EffectiveSize;
+ Offset += Prev->Offset + Prev->EffectiveSize;
- // Compute fragment offset and size.
- F->Offset = Address - StartAddress;
- F->EffectiveSize = getAssembler().ComputeFragmentSize(*F, StartAddress,
- F->Offset);
+ F->Offset = Offset;
+ F->EffectiveSize = getAssembler().ComputeFragmentSize(*F, F->Offset);
LastValidFragment = F;
-
- // If this is the last fragment in a section, update the next section address.
- if (!F->getNextNode()) {
- unsigned NextIndex = F->getParent()->getLayoutOrder() + 1;
- if (NextIndex != getSectionOrder().size())
- LayoutSection(getSectionOrder()[NextIndex]);
- }
-}
-
-void MCAsmLayout::LayoutSection(MCSectionData *SD) {
- unsigned SectionOrderIndex = SD->getLayoutOrder();
-
- ++stats::SectionLayouts;
-
- // Compute the section start address.
- uint64_t StartAddress = 0;
- if (SectionOrderIndex) {
- MCSectionData *Prev = getSectionOrder()[SectionOrderIndex - 1];
- StartAddress = getSectionAddress(Prev) + getSectionAddressSize(Prev);
- }
-
- // Honor the section alignment requirements.
- StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment());
-
- // Set the section address.
- SD->Address = StartAddress;
}
/// WriteFragmentData - Write the \arg F data to the output file.
@@ -566,7 +499,7 @@ void MCAssembler::WriteSectionData(const MCSectionData *SD,
ie = SD->end(); it != ie; ++it)
WriteFragmentData(*this, Layout, *it, OW);
- assert(OW->getStream().tell() - Start == Layout.getSectionFileSize(SD));
+ assert(OW->getStream().tell() - Start == Layout.getSectionAddressSize(SD));
}
@@ -594,29 +527,7 @@ void MCAssembler::Finish(MCObjectWriter *Writer) {
// Create the layout object.
MCAsmLayout Layout(*this);
- // Insert additional align fragments for concrete sections to explicitly pad
- // the previous section to match their alignment requirements. This is for
- // 'gas' compatibility, it shouldn't strictly be necessary.
- if (PadSectionToAlignment) {
- for (unsigned i = 1, e = Layout.getSectionOrder().size(); i < e; ++i) {
- MCSectionData *SD = Layout.getSectionOrder()[i];
-
- // Ignore sections without alignment requirements.
- unsigned Align = SD->getAlignment();
- if (Align <= 1)
- continue;
-
- // Ignore virtual sections, they don't cause file size modifications.
- if (SD->getSection().isVirtualSection())
- continue;
-
- // Otherwise, create a new align fragment at the end of the previous
- // section.
- MCAlignFragment *AF = new MCAlignFragment(Align, 0, 1, Align,
- Layout.getSectionOrder()[i - 1]);
- AF->setOnlyAlignAddress(true);
- }
- }
+
// Create dummy fragments and assign section ordinals.
unsigned SectionIndex = 0;
@@ -668,7 +579,7 @@ void MCAssembler::Finish(MCObjectWriter *Writer) {
// Allow the object writer a chance to perform post-layout binding (for
// example, to set the index fields in the symbol data).
- Writer->ExecutePostLayoutBinding(*this);
+ Writer->ExecutePostLayoutBinding(*this, Layout);
// Evaluate and apply the fixups, generating relocation entries as necessary.
for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) {
@@ -920,8 +831,6 @@ void MCFragment::dump() {
const MCAlignFragment *AF = cast<MCAlignFragment>(this);
if (AF->hasEmitNops())
OS << " (emit nops)";
- if (AF->hasOnlyAlignAddress())
- OS << " (only align section)";
OS << "\n ";
OS << " Alignment:" << AF->getAlignment()
<< " Value:" << AF->getValue() << " ValueSize:" << AF->getValueSize()
@@ -991,8 +900,7 @@ void MCSectionData::dump() {
raw_ostream &OS = llvm::errs();
OS << "<MCSectionData";
- OS << " Alignment:" << getAlignment() << " Address:" << Address
- << " Fragments:[\n ";
+ OS << " Alignment:" << getAlignment() << " Fragments:[\n ";
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (it != begin()) OS << ",\n ";
it->dump();
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index f18c420cb9..18d8fa39ed 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -71,7 +71,7 @@ class MCELFStreamer : public MCObjectStreamer {
public:
MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter, false) {}
+ : MCObjectStreamer(Context, TAB, OS, Emitter) {}
~MCELFStreamer() {}
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index b4712c2035..756e7598d5 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -238,20 +238,27 @@ void MCTargetExpr::Anchor() {}
/* *** */
bool MCExpr::EvaluateAsAbsolute(int64_t &Res) const {
- return EvaluateAsAbsolute(Res, 0, 0);
+ return EvaluateAsAbsolute(Res, 0, 0, 0);
}
bool MCExpr::EvaluateAsAbsolute(int64_t &Res,
const MCAsmLayout &Layout) const {
- return EvaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout);
+ return EvaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, 0);
+}
+
+bool MCExpr::EvaluateAsAbsolute(int64_t &Res,
+ const MCAsmLayout &Layout,
+ const SectionAddrMap &Addrs) const {
+ return EvaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, &Addrs);
}
bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const {
- return EvaluateAsAbsolute(Res, &Asm, 0);
+ return EvaluateAsAbsolute(Res, &Asm, 0, 0);
}
bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
- const MCAsmLayout *Layout) const {
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs) const {
MCValue Value;
// Fast path constants.
@@ -260,7 +267,7 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
return true;
}
- if (!EvaluateAsRelocatableImpl(Value, Asm, Layout, false) ||
+ if (!EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, Addrs) ||
!Value.isAbsolute()) {
// EvaluateAsAbsolute is defined to return the "current value" of
// the expression if we are given a Layout object, even in cases
@@ -268,11 +275,11 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
if (Layout) {
Res = Value.getConstant();
if (Value.getSymA()) {
- Res += Layout->getSymbolAddress(
+ Res += Layout->getSymbolOffset(
&Layout->getAssembler().getSymbolData(Value.getSymA()->getSymbol()));
}
if (Value.getSymB()) {
- Res -= Layout->getSymbolAddress(
+ Res -= Layout->getSymbolOffset(
&Layout->getAssembler().getSymbolData(Value.getSymB()->getSymbol()));
}
}
@@ -283,8 +290,9 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
return true;
}
-static bool EvaluateSymbolicAdd(const MCAsmLayout *Layout,
- const MCAssembler *Asm,
+static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs,
bool InSet,
const MCValue &LHS,const MCSymbolRefExpr *RHS_A,
const MCSymbolRefExpr *RHS_B, int64_t RHS_Cst,
@@ -327,10 +335,19 @@ static bool EvaluateSymbolicAdd(const MCAsmLayout *Layout,
}
if (Layout) {
- Res = MCValue::get(+ Layout->getSymbolAddress(&AD)
- - Layout->getSymbolAddress(&BD)
- + LHS.getConstant()
- + RHS_Cst);
+ const MCSectionData &SecA = *AD.getFragment()->getParent();
+ const MCSectionData &SecB = *BD.getFragment()->getParent();
+ int64_t Val = + Layout->getSymbolOffset(&AD)
+ - Layout->getSymbolOffset(&BD)
+ + LHS.getConstant()
+ + RHS_Cst;
+ if (&SecA != &SecB) {
+ if (!Addrs)
+ return false;
+ Val += Addrs->lookup(&SecA);
+ Val -= Addrs->lookup(&SecB);
+ }
+ Res = MCValue::get(Val);
return true;
}
}
@@ -344,14 +361,15 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
const MCAsmLayout *Layout) const {
if (Layout)
return EvaluateAsRelocatableImpl(Res, &Layout->getAssembler(), Layout,
- false);
+ 0, false);
else
- return EvaluateAsRelocatableImpl(Res, 0, 0, false);
+ return EvaluateAsRelocatableImpl(Res, 0, 0, 0, false);
}
bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCAssembler *Asm,
const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs,
bool InSet) const {
++stats::MCExprEvaluate;
@@ -371,6 +389,7 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
bool Ret = Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Asm,
Layout,
+ Addrs,
true);
// If we failed to simplify this to a constant, let the target
// handle it.
@@ -387,7 +406,7 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
MCValue Value;
if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout,
- InSet))
+ Addrs, InSet))
return false;
switch (AUE->getOpcode()) {
@@ -421,9 +440,9 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
MCValue LHSValue, RHSValue;
if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout,
- InSet) ||
+ Addrs, InSet) ||
!ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout,
- InSet))
+ Addrs, InSet))
return false;
// We only support a few operations on non-constant expressions, handle
@@ -434,13 +453,13 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
return false;
case MCBinaryExpr::Sub:
// Negate RHS and add.
- return EvaluateSymbolicAdd(Layout, Asm, InSet, LHSValue,
+ return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
RHSValue.getSymB(), RHSValue.getSymA(),
-RHSValue.getConstant(),
Res);
case MCBinaryExpr::Add:
- return EvaluateSymbolicAdd(Layout, Asm, InSet, LHSValue,
+ return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
RHSValue.getSymA(), RHSValue.getSymB(),
RHSValue.getConstant(),
Res);
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 1ee2d48260..6f36001037 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -36,7 +36,7 @@ private:
public:
MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter, true) {}
+ : MCObjectStreamer(Context, TAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index 6348a2b69e..683f2c6adc 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -19,11 +19,9 @@
using namespace llvm;
MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
- raw_ostream &_OS, MCCodeEmitter *_Emitter,
- bool _PadSectionToAlignment)
+ raw_ostream &_OS, MCCodeEmitter *_Emitter)
: MCStreamer(Context), Assembler(new MCAssembler(Context, TAB,
*_Emitter,
- _PadSectionToAlignment,
_OS)),
CurSectionData(0)
{
diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp
index af23c91211..5341844f74 100644
--- a/lib/MC/MCPureStreamer.cpp
+++ b/lib/MC/MCPureStreamer.cpp
@@ -30,8 +30,7 @@ private:
public:
MCPureStreamer(MCContext &Context, TargetAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter,
- /*PadSectionToAlignment=*/true) {}
+ : MCObjectStreamer(Context, TAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index 1236dc1126..de96d64c27 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -197,6 +197,34 @@ class MachObjectWriter : public MCObjectWriter {
/// @}
+ SectionAddrMap SectionAddress;
+ uint64_t getSectionAddress(const MCSectionData* SD) const {
+ return SectionAddress.lookup(SD);
+ }
+ uint64_t getSymbolAddress(const MCSymbolData* SD,
+ const MCAsmLayout &Layout) const {
+ return getSectionAddress(SD->getFragment()->getParent()) +
+ Layout.getSymbolOffset(SD);
+ }
+ uint64_t getFragmentAddress(const MCFragment *Fragment,
+ const MCAsmLayout &Layout) const {
+ return getSectionAddress(Fragment->getParent()) +
+ Layout.getFragmentOffset(Fragment);
+ }
+
+ uint64_t getPaddingSize(const MCSectionData *SD,
+ const MCAsmLayout &Layout) const {
+ uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD);
+ unsigned Next = SD->getLayoutOrder() + 1;
+ if (Next >= Layout.getSectionOrder().size())
+ return 0;
+
+ const MCSectionData &NextSD = *Layout.getSectionOrder()[Next];
+ if (NextSD.getSection().isVirtualSection())
+ return 0;
+ return OffsetToAlignment(EndAddr, NextSD.getAlignment());
+ }
+
unsigned Is64Bit : 1;
uint32_t CPUType;
@@ -283,7 +311,7 @@ public:
void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCSectionData &SD, uint64_t FileOffset,
uint64_t RelocationsStart, unsigned NumRelocations) {
- uint64_t SectionSize = Layout.getSectionSize(&SD);
+ uint64_t SectionSize = Layout.getSectionAddressSize(&SD);
// The offset is unused for virtual sections.
if (SD.getSection().isVirtualSection()) {
@@ -301,10 +329,10 @@ public:
WriteBytes(Section.getSectionName(), 16);
WriteBytes(Section.getSegmentName(), 16);
if (Is64Bit) {
- Write64(Layout.getSectionAddress(&SD)); // address
+ Write64(getSectionAddress(&SD)); // address
Write64(SectionSize); // size
} else {
- Write32(Layout.getSectionAddress(&SD)); // address
+ Write32(getSectionAddress(&SD)); // address
Write32(SectionSize); // size
}
Write32(FileOffset);
@@ -413,7 +441,7 @@ public:
if (Symbol.isAbsolute()) {
Address = cast<MCConstantExpr>(Symbol.getVariableValue())->getValue();
} else {
- Address = Layout.getSymbolAddress(&Data);
+ Address = getSymbolAddress(&Data, Layout);
}
} else if (Data.isCommon()) {
// Common symbols are encoded with the size in the address
@@ -473,7 +501,7 @@ public:
uint32_t FixupOffset =
Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
uint32_t FixupAddress =
- Layout.getFragmentAddress(Fragment) + Fixup.getOffset();
+ getFragmentAddress(Fragment, Layout) + Fixup.getOffset();
int64_t Value = 0;
unsigned Index = 0;
unsigned IsExtern = 0;
@@ -603,10 +631,21 @@ public:
// The index is the section ordinal (1-based).
Index = SD.getFragment()->getParent()->getOrdinal() + 1;
IsExtern = 0;
- Value += Layout.getSymbolAddress(&SD);
+ Value += getSymbolAddress(&SD, Layout);
if (IsPCRel)
Value -= FixupAddress + (1 << Log2Size);
+ } else if (Symbol->isVariable()) {
+ const MCExpr *Value = Symbol->getVariableValue();
+ int64_t Res;
+ bool isAbs = Value->EvaluateAsAbsolute(Res, Layout, SectionAddress);
+ if (isAbs) {
+ FixedValue = Res;
+ return;
+ } else {
+ report_fatal_error("unsupported relocation of variable '" +
+ Symbol->getName() + "'");
+ }
} else {
report_fatal_error("unsupported relocation of undefined symbol '" +
Symbol->getName() + "'");
@@ -708,7 +747,9 @@ public:
report_fatal_error("symbol '" + A->getName() +
"' can not be undefined in a subtraction expression");
- uint32_t Value = Layout.getSymbolAddress(A_SD);
+ uint32_t Value = getSymbolAddress(A_SD, Layout);
+ uint64_t SecAddr = getSectionAddress(A_SD->getFragment()->getParent());
+ FixedValue += SecAddr;
uint32_t Value2 = 0;
if (const MCSymbolRefExpr *B = Target.getSymB()) {
@@ -725,7 +766,8 @@ public:
// for pedantic compatibility with 'as'.
Type = A_SD->isExternal() ? macho::RIT_Difference :
macho::RIT_LocalDifference;
- Value2 = Layout.getSymbolAddress(B_SD);
+ Value2 = getSymbolAddress(B_SD, Layout);
+ FixedValue -= getSectionAddress(B_SD->getFragment()->getParent());
}
// Relocations are written out in reverse order, so the PAIR comes first.
@@ -774,10 +816,10 @@ public:
if (Target.getSymB()) {
// If this is a subtraction then we're pcrel.
uint32_t FixupAddress =
- Layout.getFragmentAddress(Fragment) + Fixup.getOffset();
+ getFragmentAddress(Fragment, Layout) + Fixup.getOffset();
MCSymbolData *SD_B = &Asm.getSymbolData(Target.getSymB()->getSymbol());
IsPCRel = 1;
- FixedValue = (FixupAddress - Layout.getSymbolAddress(SD_B) +
+ FixedValue = (FixupAddress - getSymbolAddress(SD_B, Layout) +
Target.getConstant());
FixedValue += 1ULL << Log2Size;
} else {
@@ -855,10 +897,13 @@ public:
// compensate for the addend of the symbol address, if it was
// undefined. This occurs with weak definitions, for example.
if (!SD->Symbol->isUndefined())
- FixedValue -= Layout.getSymbolAddress(SD);
+ FixedValue -= getSymbolAddress(SD, Layout);
} else {
// The index is the section ordinal (1-based).
Index = SD->getFragment()->getParent()->getOrdinal() + 1;
+ FixedValue += getSectionAddress(SD->getFragment()->getParent());
+ if (IsPCRel)
+ FixedValue -= getSectionAddress(Fragment->getParent());
}
Type = macho::RIT_Vanilla;
@@ -1039,7 +1084,25 @@ public:
StringTable += '\x00';
}
- void ExecutePostLayoutBinding(MCAssembler &Asm) {
+ void computeSectionAddresses(const MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ uint64_t StartAddress = 0;
+ const SmallVectorImpl<MCSectionData*> &Order = Layout.getSectionOrder();
+ for (int i = 0, n = Order.size(); i != n ; ++i) {
+ const MCSectionData *SD = Order[i];
+ StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment());
+ SectionAddress[SD] = StartAddress;
+ StartAddress += Layout.getSectionAddressSize(SD);
+ // Explicitly pad the section to match the alignment requirements of the
+ // following one. This is for 'gas' compatibility, it shouldn't
+ /// strictly be necessary.
+ StartAddress += getPaddingSize(SD, Layout);
+ }
+ }
+
+ void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) {
+ computeSectionAddresses(Asm, Layout);
+
// Create symbol data for any indirect symbols.
BindIndirectSymbols(Asm);
@@ -1113,9 +1176,10 @@ public:
for (MCAssembler::const_iterator it = Asm.begin(),
ie = Asm.end(); it != ie; ++it) {
const MCSectionData &SD = *it;
- uint64_t Address = Layout.getSectionAddress(&SD);
- uint64_t Size = Layout.getSectionSize(&SD);
+ uint64_t Address = getSectionAddress(&SD);
+ uint64_t Size = Layout.getSectionAddressSize(&SD);
uint64_t FileSize = Layout.getSectionFileSize(&SD);
+ FileSize += getPaddingSize(&SD, Layout);
VMSize = std::max(VMSize, Address + Size);
@@ -1144,7 +1208,7 @@ public:
ie = Asm.end(); it != ie; ++it) {
std::vector<macho::RelocationEntry> &Relocs = Relocations[it];
unsigned NumRelocs = Relocs.size();
- uint64_t SectionStart = SectionDataStart + Layout.getSectionAddress(it);
+ uint64_t SectionStart = SectionDataStart + getSectionAddress(it);
WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs);
RelocTableEnd += NumRelocs * macho::RelocationInfoSize;
}
@@ -1185,9 +1249,14 @@ public:
// Write the actual section data.
for (MCAssembler::const_iterator it = Asm.begin(),
- ie = Asm.end(); it != ie; ++it)
+ ie = Asm.end(); it != ie; ++it) {
Asm.WriteSectionData(it, Layout, this);
+ uint64_t Pad = getPaddingSize(it, Layout);
+ for (unsigned int i = 0; i < Pad; ++i)
+ Write8(0);
+ }
+
// Write the extra padding.
WriteZeros(SectionDataPadding);
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index 1bfd3a4fd7..66fd92015f 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/lib/MC/WinCOFFObjectWriter.cpp
@@ -170,7 +170,7 @@ public:
// MCObjectWriter interface implementation.
- void ExecutePostLayoutBinding(MCAssembler &Asm);
+ void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
void RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
@@ -616,7 +616,8 @@ void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
////////////////////////////////////////////////////////////////////////////////
// MCObjectWriter interface implementations
-void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) {
+void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
// "Define" each section & symbol. This creates section & symbol
// entries in the staging area.
@@ -753,7 +754,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
for (sections::iterator i = Sections.begin(),
e = Sections.end(); i != e; i++) {
- if (Layout.getSectionSize((*i)->MCData) > 0) {
+ if (Layout.getSectionAddressSize((*i)->MCData) > 0) {
MakeSectionReal(**i, ++Header.NumberOfSections);
} else {
(*i)->Number = -1;
diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp
index 3654add4f4..46968e601b 100644
--- a/lib/MC/WinCOFFStreamer.cpp
+++ b/lib/MC/WinCOFFStreamer.cpp
@@ -124,7 +124,7 @@ WinCOFFStreamer::WinCOFFStreamer(MCContext &Context,
TargetAsmBackend &TAB,
MCCodeEmitter &CE,
raw_ostream &OS)
- : MCObjectStreamer(Context, TAB, OS, &CE, false)
+ : MCObjectStreamer(Context, TAB, OS, &CE)
, CurSymbol(NULL) {
}