mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 20:53:29 +08:00
Split GdbIndexBuilder class into non-member functions.
That class had three member functions, and all of them are just reader methods that did not depend on class members, so they can be just non- member functions. Probably we should reorganize the functions themselves because their return types doesn't make much sense to me, but for now I just moved these functions out of the class. llvm-svn: 296700
This commit is contained in:
@@ -68,59 +68,6 @@ using namespace llvm::object;
|
||||
using namespace lld;
|
||||
using namespace lld::elf;
|
||||
|
||||
class lld::elf::ObjInfoTy : public llvm::LoadedObjectInfo {
|
||||
uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override {
|
||||
auto &S = static_cast<const ELFSectionRef &>(Sec);
|
||||
if (S.getFlags() & ELF::SHF_ALLOC)
|
||||
return S.getOffset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::LoadedObjectInfo> clone() const override { return {}; }
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
GdbIndexBuilder<ELFT>::GdbIndexBuilder(InputSection *Sec)
|
||||
: DebugInfoSec(Sec), ObjInfo(new ObjInfoTy) {
|
||||
elf::ObjectFile<ELFT> *File = Sec->template getFile<ELFT>();
|
||||
Expected<std::unique_ptr<object::ObjectFile>> Obj =
|
||||
object::ObjectFile::createObjectFile(File->MB);
|
||||
|
||||
if (Obj)
|
||||
Dwarf.reset(new DWARFContextInMemory(*Obj.get(), ObjInfo.get()));
|
||||
else
|
||||
error(toString(File) + ": error creating DWARF context");
|
||||
}
|
||||
|
||||
template <class ELFT> GdbIndexBuilder<ELFT>::~GdbIndexBuilder() {}
|
||||
|
||||
template <class ELFT>
|
||||
std::vector<std::pair<typename ELFT::uint, typename ELFT::uint>>
|
||||
GdbIndexBuilder<ELFT>::readCUList() {
|
||||
std::vector<std::pair<uintX_t, uintX_t>> Ret;
|
||||
for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf->compile_units())
|
||||
Ret.push_back(
|
||||
{DebugInfoSec->OutSecOff + CU->getOffset(), CU->getLength() + 4});
|
||||
return Ret;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::vector<std::pair<StringRef, uint8_t>>
|
||||
GdbIndexBuilder<ELFT>::readPubNamesAndTypes() {
|
||||
const bool IsLE = ELFT::TargetEndianness == llvm::support::little;
|
||||
StringRef Data[] = {Dwarf->getGnuPubNamesSection(),
|
||||
Dwarf->getGnuPubTypesSection()};
|
||||
|
||||
std::vector<std::pair<StringRef, uint8_t>> Ret;
|
||||
for (StringRef D : Data) {
|
||||
DWARFDebugPubTable PubTable(D, IsLE, true);
|
||||
for (const DWARFDebugPubTable::Set &S : PubTable.getData())
|
||||
for (const DWARFDebugPubTable::Entry &E : S.Entries)
|
||||
Ret.push_back({E.Name, E.Descriptor.toBits()});
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
std::pair<bool, GdbSymbol *> GdbHashTab::add(uint32_t Hash, size_t Offset) {
|
||||
GdbSymbol *&Sym = Map[Offset];
|
||||
if (Sym)
|
||||
@@ -149,38 +96,3 @@ void GdbHashTab::finalizeContents() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static InputSectionBase *findSection(ArrayRef<InputSectionBase *> Arr,
|
||||
uint64_t Offset) {
|
||||
for (InputSectionBase *S : Arr)
|
||||
if (S && S != &InputSection::Discarded)
|
||||
if (Offset >= S->Offset && Offset < S->Offset + S->getSize<ELFT>())
|
||||
return S;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::vector<AddressEntry<ELFT>>
|
||||
GdbIndexBuilder<ELFT>::readAddressArea(size_t CurrentCU) {
|
||||
std::vector<AddressEntry<ELFT>> Ret;
|
||||
for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf->compile_units()) {
|
||||
DWARFAddressRangesVector Ranges;
|
||||
CU->collectAddressRanges(Ranges);
|
||||
|
||||
ArrayRef<InputSectionBase *> Sections =
|
||||
DebugInfoSec->template getFile<ELFT>()->getSections();
|
||||
|
||||
for (std::pair<uint64_t, uint64_t> &R : Ranges)
|
||||
if (InputSectionBase *S = findSection<ELFT>(Sections, R.first))
|
||||
Ret.push_back(
|
||||
{S, R.first - S->Offset, R.second - S->Offset, CurrentCU});
|
||||
++CurrentCU;
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
template class elf::GdbIndexBuilder<ELF32LE>;
|
||||
template class elf::GdbIndexBuilder<ELF32BE>;
|
||||
template class elf::GdbIndexBuilder<ELF64LE>;
|
||||
template class elf::GdbIndexBuilder<ELF64BE>;
|
||||
|
||||
@@ -18,42 +18,15 @@ namespace lld {
|
||||
namespace elf {
|
||||
|
||||
class InputSection;
|
||||
class ObjInfoTy;
|
||||
|
||||
// Struct represents single entry of address area of gdb index.
|
||||
template <class ELFT> struct AddressEntry {
|
||||
struct AddressEntry {
|
||||
InputSectionBase *Section;
|
||||
uint64_t LowAddress;
|
||||
uint64_t HighAddress;
|
||||
size_t CuIndex;
|
||||
};
|
||||
|
||||
// GdbIndexBuilder is a helper class used for extracting data required
|
||||
// for building .gdb_index section from objects.
|
||||
template <class ELFT> class GdbIndexBuilder {
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
InputSection *DebugInfoSec;
|
||||
std::unique_ptr<llvm::DWARFContext> Dwarf;
|
||||
std::unique_ptr<ObjInfoTy> ObjInfo;
|
||||
|
||||
public:
|
||||
GdbIndexBuilder(InputSection *DebugInfoSec);
|
||||
~GdbIndexBuilder();
|
||||
|
||||
// Extracts the compilation units. Each first element of pair is a offset of a
|
||||
// CU in the .debug_info section and second is the length of that CU.
|
||||
std::vector<std::pair<uintX_t, uintX_t>> readCUList();
|
||||
|
||||
// Extracts the vector of address area entries. Accepts global index of last
|
||||
// parsed CU.
|
||||
std::vector<AddressEntry<ELFT>> readAddressArea(size_t CurrentCU);
|
||||
|
||||
// Method extracts public names and types. It returns list of name and
|
||||
// gnu_pub* kind pairs.
|
||||
std::vector<std::pair<StringRef, uint8_t>> readPubNamesAndTypes();
|
||||
};
|
||||
|
||||
// Element of GdbHashTab hash table.
|
||||
struct GdbSymbol {
|
||||
GdbSymbol(uint32_t Hash, size_t Offset)
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "Threads.h"
|
||||
#include "Writer.h"
|
||||
#include "lld/Config/Version.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/Support/Dwarf.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/MD5.h"
|
||||
@@ -1702,20 +1704,93 @@ static uint32_t hash(StringRef Str) {
|
||||
return R;
|
||||
}
|
||||
|
||||
static std::vector<std::pair<uint64_t, uint64_t>>
|
||||
readCuList(DWARFContext &Dwarf, InputSection *Sec) {
|
||||
std::vector<std::pair<uint64_t, uint64_t>> Ret;
|
||||
for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf.compile_units())
|
||||
Ret.push_back({Sec->OutSecOff + CU->getOffset(), CU->getLength() + 4});
|
||||
return Ret;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static InputSectionBase *findSection(ArrayRef<InputSectionBase *> Arr,
|
||||
uint64_t Offset) {
|
||||
for (InputSectionBase *S : Arr)
|
||||
if (S && S != &InputSection::Discarded)
|
||||
if (Offset >= S->Offset && Offset < S->Offset + S->getSize<ELFT>())
|
||||
return S;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static std::vector<AddressEntry>
|
||||
readAddressArea(DWARFContext &Dwarf, InputSection *Sec, size_t CurrentCU) {
|
||||
std::vector<AddressEntry> Ret;
|
||||
|
||||
for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf.compile_units()) {
|
||||
DWARFAddressRangesVector Ranges;
|
||||
CU->collectAddressRanges(Ranges);
|
||||
|
||||
ArrayRef<InputSectionBase *> Sections =
|
||||
Sec->template getFile<ELFT>()->getSections();
|
||||
|
||||
for (std::pair<uint64_t, uint64_t> &R : Ranges)
|
||||
if (InputSectionBase *S = findSection<ELFT>(Sections, R.first))
|
||||
Ret.push_back(
|
||||
{S, R.first - S->Offset, R.second - S->Offset, CurrentCU});
|
||||
++CurrentCU;
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
static std::vector<std::pair<StringRef, uint8_t>>
|
||||
readPubNamesAndTypes(DWARFContext &Dwarf, bool IsLE) {
|
||||
StringRef Data[] = {Dwarf.getGnuPubNamesSection(),
|
||||
Dwarf.getGnuPubTypesSection()};
|
||||
|
||||
std::vector<std::pair<StringRef, uint8_t>> Ret;
|
||||
for (StringRef D : Data) {
|
||||
DWARFDebugPubTable PubTable(D, IsLE, true);
|
||||
for (const DWARFDebugPubTable::Set &Set : PubTable.getData())
|
||||
for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)
|
||||
Ret.push_back({Ent.Name, Ent.Descriptor.toBits()});
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
class ObjInfoTy : public llvm::LoadedObjectInfo {
|
||||
uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override {
|
||||
auto &S = static_cast<const object::ELFSectionRef &>(Sec);
|
||||
if (S.getFlags() & ELF::SHF_ALLOC)
|
||||
return S.getOffset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::LoadedObjectInfo> clone() const override { return {}; }
|
||||
};
|
||||
|
||||
template <class ELFT> void GdbIndexSection<ELFT>::readDwarf(InputSection *Sec) {
|
||||
GdbIndexBuilder<ELFT> Builder(Sec);
|
||||
if (ErrorCount)
|
||||
elf::ObjectFile<ELFT> *File = Sec->template getFile<ELFT>();
|
||||
|
||||
Expected<std::unique_ptr<object::ObjectFile>> Obj =
|
||||
object::ObjectFile::createObjectFile(File->MB);
|
||||
if (!Obj) {
|
||||
error(toString(File) + ": error creating DWARF context");
|
||||
return;
|
||||
}
|
||||
|
||||
ObjInfoTy ObjInfo;
|
||||
DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo);
|
||||
|
||||
size_t CuId = CompilationUnits.size();
|
||||
std::vector<std::pair<uintX_t, uintX_t>> CuList = Builder.readCUList();
|
||||
CompilationUnits.insert(CompilationUnits.end(), CuList.begin(), CuList.end());
|
||||
for (std::pair<uint64_t, uint64_t> &P : readCuList(Dwarf, Sec))
|
||||
CompilationUnits.push_back(P);
|
||||
|
||||
std::vector<AddressEntry<ELFT>> AddrArea = Builder.readAddressArea(CuId);
|
||||
AddressArea.insert(AddressArea.end(), AddrArea.begin(), AddrArea.end());
|
||||
for (AddressEntry &Ent : readAddressArea<ELFT>(Dwarf, Sec, CuId))
|
||||
AddressArea.push_back(Ent);
|
||||
|
||||
std::vector<std::pair<StringRef, uint8_t>> NamesAndTypes =
|
||||
Builder.readPubNamesAndTypes();
|
||||
readPubNamesAndTypes(Dwarf, ELFT::TargetEndianness == support::little);
|
||||
|
||||
for (std::pair<StringRef, uint8_t> &Pair : NamesAndTypes) {
|
||||
uint32_t Hash = hash(Pair.first);
|
||||
@@ -1785,7 +1860,7 @@ template <class ELFT> void GdbIndexSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
}
|
||||
|
||||
// Write the address area.
|
||||
for (AddressEntry<ELFT> &E : AddressArea) {
|
||||
for (AddressEntry &E : AddressArea) {
|
||||
uintX_t BaseAddr =
|
||||
E.Section->OutSec->Addr + E.Section->template getOffset<ELFT>(0);
|
||||
write64le(Buf, BaseAddr + E.LowAddress);
|
||||
|
||||
@@ -521,7 +521,7 @@ public:
|
||||
// The CU vector portion of the constant pool.
|
||||
std::vector<std::vector<std::pair<uint32_t, uint8_t>>> CuVectors;
|
||||
|
||||
std::vector<AddressEntry<ELFT>> AddressArea;
|
||||
std::vector<AddressEntry> AddressArea;
|
||||
|
||||
private:
|
||||
void readDwarf(InputSection *Sec);
|
||||
|
||||
Reference in New Issue
Block a user