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:
Rui Ueyama
2017-03-01 22:54:50 +00:00
parent 92938657a0
commit ac2d815a2a
4 changed files with 85 additions and 125 deletions

View File

@@ -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>;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);