diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-07 00:27:36 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-07 00:27:36 +0000 |
commit | 85f2ecc697a8ca6c8cf08093054cbbb9d2060ccf (patch) | |
tree | 7a6cf772d0ee4c7eca6e6c4a400ebe205a5b8efd | |
parent | 662a816e89a9d77bf75e1328b09cf9235b4682aa (diff) |
Sorry for such a large commit. The summary is that only MachO cares about the
actuall addresses in a .o file, so it is better to let the MachO writer compute
it.
This is good for two reasons. First, areas that shouldn't care about
addresses now don't have access to it. Second, the layout of each section
is independent. I should use this in a subsequent commit to speed it up.
Most of the patch is just removing the section address computation. The two
interesting parts are the change on how we handle padding in the end
of sections and how MachO can get the address of a-b when a and b are in
different sections.
Since now the expression evaluation normally doesn't know the section address,
it will think that a-b needs relocation and let the MachO writer know. Once
it has computed the section addresses, it calls back the expression evaluation
with the section addresses to resolve these expressions.
The remaining problem is the handling of padding. Currently it will create
a special alignment fragment at the end. Since that fragment doesn't update
the alignment of the section, it needs the real address to be computed.
Since now the layout will not compute a-b with a and b in different sections,
the only effect that the special alignment fragment has is update the
address size of the section. This can also be done by the MachO writer.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121076 91177308-0d34-0410-b5e6-96231b3b80d8
-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 } |