diff options
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/ELFObjectWriter.cpp | 14 | ||||
-rw-r--r-- | lib/MC/MCAssembler.cpp | 122 | ||||
-rw-r--r-- | lib/MC/MCELFStreamer.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCExpr.cpp | 59 | ||||
-rw-r--r-- | lib/MC/MCMachOStreamer.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCObjectStreamer.cpp | 4 | ||||
-rw-r--r-- | lib/MC/MCPureStreamer.cpp | 3 | ||||
-rw-r--r-- | lib/MC/MachObjectWriter.cpp | 101 | ||||
-rw-r--r-- | lib/MC/WinCOFFObjectWriter.cpp | 7 | ||||
-rw-r--r-- | lib/MC/WinCOFFStreamer.cpp | 2 |
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) { } |