diff options
-rw-r--r-- | include/llvm/MC/MCAsmLayout.h | 23 | ||||
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 21 | ||||
-rw-r--r-- | include/llvm/MC/MCExpr.h | 9 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectStreamer.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectWriter.h | 3 | ||||
-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 |
15 files changed, 169 insertions, 206 deletions
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index ce9692dcaf..805af6257f 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -66,11 +66,6 @@ public: /// been initialized. void LayoutFragment(MCFragment *Fragment); - /// \brief Performs initial layout for a single section, assuming that the - /// previous section (including its fragments) has already been layed out - /// correctly. - void LayoutSection(MCSectionData *SD); - /// @name Section Access (in layout order) /// @{ @@ -93,20 +88,9 @@ public: uint64_t getFragmentOffset(const MCFragment *F) const; /// @} - /// @name Section Layout Data - /// @{ - - /// \brief Get the computed address of the given section. - uint64_t getSectionAddress(const MCSectionData *SD) const; - - /// @} /// @name Utility Functions /// @{ - /// \brief Get the address of the given fragment, as computed in the current - /// layout. - uint64_t getFragmentAddress(const MCFragment *F) const; - /// \brief Get the address space size of the given section, as it effects /// layout. This may differ from the size reported by \see getSectionSize() by /// not including section tail padding. @@ -116,13 +100,6 @@ public: /// file. This may include additional padding, or be 0 for virtual sections. uint64_t getSectionFileSize(const MCSectionData *SD) const; - /// \brief Get the logical data size of the given section. - uint64_t getSectionSize(const MCSectionData *SD) const; - - /// \brief Get the address of the given symbol, as computed in the current - /// layout. - uint64_t getSymbolAddress(const MCSymbolData *SD) const; - /// \brief Get the offset of the given symbol, as computed in the current /// layout. uint64_t getSymbolOffset(const MCSymbolData *SD) const; diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index ba89436981..8a5009ffc4 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -236,19 +236,12 @@ class MCAlignFragment : public MCFragment { /// target dependent. bool EmitNops : 1; - /// OnlyAlignAddress - Flag to indicate that this align is only used to adjust - /// the address space size of a section and that it should not be included as - /// part of the section size. This flag can only be used on the last fragment - /// in a section. - bool OnlyAlignAddress : 1; - public: MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, unsigned _MaxBytesToEmit, MCSectionData *SD = 0) : MCFragment(FT_Align, SD), Alignment(_Alignment), Value(_Value),ValueSize(_ValueSize), - MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false), - OnlyAlignAddress(false) {} + MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} /// @name Accessors /// @{ @@ -264,9 +257,6 @@ public: bool hasEmitNops() const { return EmitNops; } void setEmitNops(bool Value) { EmitNops = Value; } - bool hasOnlyAlignAddress() const { return OnlyAlignAddress; } - void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; } - /// @} static bool classof(const MCFragment *F) { @@ -447,10 +437,6 @@ private: // // FIXME: This could all be kept private to the assembler implementation. - /// Address - The computed address of this section. This is ~0 until - /// initialized. - uint64_t Address; - /// HasInstructions - Whether this section has had instructions emitted into /// it. unsigned HasInstructions : 1; @@ -679,7 +665,6 @@ private: unsigned RelaxAll : 1; unsigned SubsectionsViaSymbols : 1; - unsigned PadSectionToAlignment : 1; private: /// Evaluate a fixup to a relocatable expression and the value which should be @@ -713,7 +698,6 @@ private: /// Compute the effective fragment size assuming it is layed out at the given /// \arg SectionAddress and \arg FragmentOffset. uint64_t ComputeFragmentSize(const MCFragment &F, - uint64_t SectionAddress, uint64_t FragmentOffset) const; /// LayoutOnce - Perform one layout iteration and return true if any offsets @@ -765,8 +749,7 @@ public: // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, - MCCodeEmitter &_Emitter, bool _PadSectionToAlignment, - raw_ostream &OS); + MCCodeEmitter &_Emitter, raw_ostream &OS); ~MCAssembler(); MCContext &getContext() const { return Context; } diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 888934e822..da3cebe414 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCEXPR_H #define LLVM_MC_MCEXPR_H +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" @@ -18,10 +19,12 @@ class MCAsmInfo; class MCAsmLayout; class MCAssembler; class MCContext; +class MCSectionData; class MCSymbol; class MCValue; class raw_ostream; class StringRef; +typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap; /// MCExpr - Base class for the full range of assembler expressions which are /// needed for parsing. @@ -42,12 +45,14 @@ private: void operator=(const MCExpr&); // DO NOT IMPLEMENT bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, - const MCAsmLayout *Layout) const; + const MCAsmLayout *Layout, + const SectionAddrMap *Addrs) const; protected: explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {} bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, + const SectionAddrMap *Addrs, bool InSet) const; public: /// @name Accessors @@ -76,6 +81,8 @@ public: bool EvaluateAsAbsolute(int64_t &Res) const; bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; + bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, + const SectionAddrMap &Addrs) const; /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable /// value, i.e. an expression of the fixed form (a - b + constant). diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index d130ba4bcd..c6dd96068f 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -37,8 +37,7 @@ class MCObjectStreamer : public MCStreamer { protected: MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, - raw_ostream &_OS, MCCodeEmitter *_Emitter, - bool _PadSectionToAlignment); + raw_ostream &_OS, MCCodeEmitter *_Emitter); ~MCObjectStreamer(); MCSectionData *getCurrentSectionData() const { diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 90fe6e8ee1..b819a5778f 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -62,7 +62,8 @@ public: /// /// This routine is called by the assembler after layout and relaxation is /// complete. - virtual void ExecutePostLayoutBinding(MCAssembler &Asm) = 0; + virtual void ExecutePostLayoutBinding(MCAssembler &Asm, + const MCAsmLayout &Layout) = 0; /// Record a relocation entry. /// 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); |