#include "OutputSections.h"
#include "Config.h"
#include "EhFrame.h"
-#include "GdbIndex.h"
#include "LinkerScript.h"
#include "Memory.h"
#include "Strings.h"
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.
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>;
#define LLD_ELF_OUTPUT_SECTIONS_H
#include "Config.h"
-#include "GdbIndex.h"
#include "Relocations.h"
#include "lld/Core/LLVM.h"
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
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;
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;
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();
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>;
#ifndef LLD_ELF_SYNTHETIC_SECTION_H
#define LLD_ELF_SYNTHETIC_SECTION_H
+#include "GdbIndex.h"
#include "InputSection.h"
#include "llvm/ADT/SmallPtrSet.h"
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();
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;
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;
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*/);
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() {
// 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);