diff options
-rw-r--r-- | lld/ELF/OutputSections.cpp | 50 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 27 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 48 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 29 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 11 |
5 files changed, 83 insertions, 82 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index e4bc68db25a..85635e7d45f 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -10,7 +10,6 @@ #include "OutputSections.h" #include "Config.h" #include "EhFrame.h" -#include "GdbIndex.h" #include "LinkerScript.h" #include "Memory.h" #include "Strings.h" @@ -63,50 +62,6 @@ void OutputSectionBase::writeHeaderTo(typename ELFT::Shdr *Shdr) { Shdr->sh_name = ShName; } -template <class ELFT> -GdbIndexSection<ELFT>::GdbIndexSection() - : OutputSectionBase(".gdb_index", SHT_PROGBITS, 0) {} - -template <class ELFT> void GdbIndexSection<ELFT>::parseDebugSections() { - std::vector<InputSection<ELFT> *> &IS = - static_cast<OutputSection<ELFT> *>(Out<ELFT>::DebugInfo)->Sections; - - for (InputSection<ELFT> *I : IS) - readDwarf(I); -} - -template <class ELFT> -void GdbIndexSection<ELFT>::readDwarf(InputSection<ELFT> *I) { - std::vector<std::pair<uintX_t, uintX_t>> CuList = readCuList(I); - CompilationUnits.insert(CompilationUnits.end(), CuList.begin(), CuList.end()); -} - -template <class ELFT> void GdbIndexSection<ELFT>::finalize() { - parseDebugSections(); - - // GdbIndex header consist from version fields - // and 5 more fields with different kinds of offsets. - CuTypesOffset = CuListOffset + CompilationUnits.size() * CompilationUnitSize; - this->Size = CuTypesOffset; -} - -template <class ELFT> void GdbIndexSection<ELFT>::writeTo(uint8_t *Buf) { - write32le(Buf, 7); // Write Version - write32le(Buf + 4, CuListOffset); // CU list offset - write32le(Buf + 8, CuTypesOffset); // Types CU list offset - write32le(Buf + 12, CuTypesOffset); // Address area offset - write32le(Buf + 16, CuTypesOffset); // Symbol table offset - write32le(Buf + 20, CuTypesOffset); // Constant pool offset - Buf += 24; - - // Write the CU list. - for (std::pair<uintX_t, uintX_t> CU : CompilationUnits) { - write64le(Buf, CU.first); - write64le(Buf + 8, CU.second); - Buf += 16; - } -} - // Returns the number of version definition entries. Because the first entry // is for the version definition itself, it is the number of versioned symbols // plus one. Note that we don't support multiple versions yet. @@ -908,11 +863,6 @@ template class VersionDefinitionSection<ELF32BE>; template class VersionDefinitionSection<ELF64LE>; template class VersionDefinitionSection<ELF64BE>; -template class GdbIndexSection<ELF32LE>; -template class GdbIndexSection<ELF32BE>; -template class GdbIndexSection<ELF64LE>; -template class GdbIndexSection<ELF64BE>; - template class OutputSectionFactory<ELF32LE>; template class OutputSectionFactory<ELF32BE>; template class OutputSectionFactory<ELF64LE>; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 0c1c027e345..43995c7e52b 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -11,7 +11,6 @@ #define LLD_ELF_OUTPUT_SECTIONS_H #include "Config.h" -#include "GdbIndex.h" #include "Relocations.h" #include "lld/Core/LLVM.h" @@ -105,30 +104,6 @@ public: uint32_t Link = 0; }; -template <class ELFT> class GdbIndexSection final : public OutputSectionBase { - typedef typename ELFT::uint uintX_t; - - const unsigned OffsetTypeSize = 4; - const unsigned CuListOffset = 6 * OffsetTypeSize; - const unsigned CompilationUnitSize = 16; - const unsigned AddressEntrySize = 16 + OffsetTypeSize; - const unsigned SymTabEntrySize = 2 * OffsetTypeSize; - -public: - GdbIndexSection(); - void finalize() override; - void writeTo(uint8_t *Buf) override; - - // Pairs of [CU Offset, CU length]. - std::vector<std::pair<uintX_t, uintX_t>> CompilationUnits; - -private: - void parseDebugSections(); - void readDwarf(InputSection<ELFT> *I); - - uint32_t CuTypesOffset; -}; - // For more information about .gnu.version and .gnu.version_r see: // https://www.akkadia.org/drepper/symbol-versioning @@ -338,7 +313,6 @@ template <class ELFT> struct Out { static uint8_t First; static EhFrameHeader<ELFT> *EhFrameHdr; static EhOutputSection<ELFT> *EhFrame; - static GdbIndexSection<ELFT> *GdbIndex; static OutputSection<ELFT> *Bss; static OutputSection<ELFT> *MipsRldMap; static OutputSectionBase *Opd; @@ -391,7 +365,6 @@ template <class ELFT> uint64_t getHeaderSize() { template <class ELFT> uint8_t Out<ELFT>::First; template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr; template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame; -template <class ELFT> GdbIndexSection<ELFT> *Out<ELFT>::GdbIndex; template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss; template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap; template <class ELFT> OutputSectionBase *Out<ELFT>::Opd; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 8f66ade0fd1..65ca4237385 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1360,6 +1360,49 @@ template <class ELFT> size_t PltSection<ELFT>::getSize() const { return Target->PltHeaderSize + Entries.size() * Target->PltEntrySize; } +template <class ELFT> +GdbIndexSection<ELFT>::GdbIndexSection() + : SyntheticSection<ELFT>(0, SHT_PROGBITS, 1, ".gdb_index") {} + +template <class ELFT> void GdbIndexSection<ELFT>::parseDebugSections() { + std::vector<InputSection<ELFT> *> &IS = + static_cast<OutputSection<ELFT> *>(Out<ELFT>::DebugInfo)->Sections; + + for (InputSection<ELFT> *I : IS) + readDwarf(I); +} + +template <class ELFT> +void GdbIndexSection<ELFT>::readDwarf(InputSection<ELFT> *I) { + std::vector<std::pair<uintX_t, uintX_t>> CuList = readCuList(I); + CompilationUnits.insert(CompilationUnits.end(), CuList.begin(), CuList.end()); +} + +template <class ELFT> void GdbIndexSection<ELFT>::finalize() { + parseDebugSections(); + + // GdbIndex header consist from version fields + // and 5 more fields with different kinds of offsets. + CuTypesOffset = CuListOffset + CompilationUnits.size() * CompilationUnitSize; +} + +template <class ELFT> void GdbIndexSection<ELFT>::writeTo(uint8_t *Buf) { + write32le(Buf, 7); // Write Version + write32le(Buf + 4, CuListOffset); // CU list offset + write32le(Buf + 8, CuTypesOffset); // Types CU list offset + write32le(Buf + 12, CuTypesOffset); // Address area offset + write32le(Buf + 16, CuTypesOffset); // Symbol table offset + write32le(Buf + 20, CuTypesOffset); // Constant pool offset + Buf += 24; + + // Write the CU list. + for (std::pair<uintX_t, uintX_t> CU : CompilationUnits) { + write64le(Buf, CU.first); + write64le(Buf + 8, CU.second); + Buf += 16; + } +} + template InputSection<ELF32LE> *elf::createCommonSection(); template InputSection<ELF32BE> *elf::createCommonSection(); template InputSection<ELF64LE> *elf::createCommonSection(); @@ -1469,3 +1512,8 @@ template class elf::PltSection<ELF32LE>; template class elf::PltSection<ELF32BE>; template class elf::PltSection<ELF64LE>; template class elf::PltSection<ELF64BE>; + +template class elf::GdbIndexSection<ELF32LE>; +template class elf::GdbIndexSection<ELF32BE>; +template class elf::GdbIndexSection<ELF64LE>; +template class elf::GdbIndexSection<ELF64BE>; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index e441f99a18c..106e84e3106 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -10,6 +10,7 @@ #ifndef LLD_ELF_SYNTHETIC_SECTION_H #define LLD_ELF_SYNTHETIC_SECTION_H +#include "GdbIndex.h" #include "InputSection.h" #include "llvm/ADT/SmallPtrSet.h" @@ -502,6 +503,32 @@ private: std::vector<std::pair<const SymbolBody *, unsigned>> Entries; }; +template <class ELFT> +class GdbIndexSection final : public SyntheticSection<ELFT> { + typedef typename ELFT::uint uintX_t; + + const unsigned OffsetTypeSize = 4; + const unsigned CuListOffset = 6 * OffsetTypeSize; + const unsigned CompilationUnitSize = 16; + const unsigned AddressEntrySize = 16 + OffsetTypeSize; + const unsigned SymTabEntrySize = 2 * OffsetTypeSize; + +public: + GdbIndexSection(); + void finalize() override; + void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return CuTypesOffset; } + + // Pairs of [CU Offset, CU length]. + std::vector<std::pair<uintX_t, uintX_t>> CompilationUnits; + +private: + void parseDebugSections(); + void readDwarf(InputSection<ELFT> *I); + + uint32_t CuTypesOffset; +}; + template <class ELFT> InputSection<ELFT> *createCommonSection(); template <class ELFT> InputSection<ELFT> *createInterpSection(); template <class ELFT> MergeInputSection<ELFT> *createCommentSection(); @@ -514,6 +541,7 @@ template <class ELFT> struct In { static StringTableSection<ELFT> *DynStrTab; static SymbolTableSection<ELFT> *DynSymTab; static GnuHashTableSection<ELFT> *GnuHashTab; + static GdbIndexSection<ELFT> *GdbIndex; static GotSection<ELFT> *Got; static MipsGotSection<ELFT> *MipsGot; static GotPltSection<ELFT> *GotPlt; @@ -535,6 +563,7 @@ template <class ELFT> InputSection<ELFT> *In<ELFT>::Common; template <class ELFT> DynamicSection<ELFT> *In<ELFT>::Dynamic; template <class ELFT> StringTableSection<ELFT> *In<ELFT>::DynStrTab; template <class ELFT> SymbolTableSection<ELFT> *In<ELFT>::DynSymTab; +template <class ELFT> GdbIndexSection<ELFT> *In<ELFT>::GdbIndex; template <class ELFT> GnuHashTableSection<ELFT> *In<ELFT>::GnuHashTab; template <class ELFT> GotSection<ELFT> *In<ELFT>::Got; template <class ELFT> MipsGotSection<ELFT> *In<ELFT>::MipsGot; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 213ecf66f4c..64c80b93190 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -268,7 +268,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { if (Config->SysvHash) In<ELFT>::HashTab = make<HashTableSection<ELFT>>(); if (Config->GdbIndex) - Out<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>(); + In<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>(); In<ELFT>::RelaPlt = make<RelocationSection<ELFT>>( Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/); @@ -979,8 +979,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { finalizeSynthetic<ELFT>( {In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::HashTab, In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab, - In<ELFT>::DynStrTab, In<ELFT>::Got, In<ELFT>::MipsGot, In<ELFT>::GotPlt, - In<ELFT>::RelaDyn, In<ELFT>::RelaPlt, In<ELFT>::Plt, In<ELFT>::Dynamic}); + In<ELFT>::DynStrTab, In<ELFT>::GdbIndex, In<ELFT>::Got, + In<ELFT>::MipsGot, In<ELFT>::GotPlt, In<ELFT>::RelaDyn, + In<ELFT>::RelaPlt, In<ELFT>::Plt, In<ELFT>::Dynamic}); } template <class ELFT> bool Writer<ELFT>::needsGot() { @@ -1006,8 +1007,8 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() { // This order is not the same as the final output order // because we sort the sections using their attributes below. - if (Out<ELFT>::GdbIndex && Out<ELFT>::DebugInfo) - Add(Out<ELFT>::GdbIndex); + if (In<ELFT>::GdbIndex && Out<ELFT>::DebugInfo) + addInputSec(In<ELFT>::GdbIndex); addInputSec(In<ELFT>::SymTab); addInputSec(In<ELFT>::ShStrTab); addInputSec(In<ELFT>::StrTab); |