1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[DebugInfo/DWARF] [4/4] Unify handling of compile and type units. NFC

This is patch 4 of 4 NFC refactorings to handle type units and compile
units more consistently and with less concern about the object-file
section that they came from.

Patch 4 combines separate DWARFUnitVectors for compile and type units
into a single DWARFUnitVector that contains both.  For now the
implementation distinguishes compile units from type units by putting
all compile units at the front of the vector, reflecting the DWARF v4
distinction between .debug_info and .debug_types sections.  A future
patch will change this to allow the free mixing of unit kinds, as is
specified by DWARF v5.

Differential Revision: https://reviews.llvm.org/D49744

llvm-svn: 338633
This commit is contained in:
Paul Robinson 2018-08-01 20:54:11 +00:00
parent a783a0cd41
commit 529af4c47d
4 changed files with 119 additions and 85 deletions

View File

@ -57,8 +57,7 @@ enum class ErrorPolicy { Halt, Continue };
/// This data structure is the top level entity that deals with dwarf debug
/// information parsing. The actual data is supplied through DWARFObj.
class DWARFContext : public DIContext {
DWARFUnitVector CUs;
DWARFUnitVector TUs;
DWARFUnitVector NormalUnits;
std::unique_ptr<DWARFUnitIndex> CUIndex;
std::unique_ptr<DWARFGdbIndex> GdbIndex;
std::unique_ptr<DWARFUnitIndex> TUIndex;
@ -75,8 +74,7 @@ class DWARFContext : public DIContext {
std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
std::unique_ptr<AppleAcceleratorTable> AppleObjC;
DWARFUnitVector DWOCUs;
DWARFUnitVector DWOTUs;
DWARFUnitVector DWOUnits;
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
@ -95,22 +93,17 @@ class DWARFContext : public DIContext {
std::unique_ptr<MCRegisterInfo> RegInfo;
/// Read compile units from the debug_info section (if necessary)
/// and store them in CUs.
void parseCompileUnits();
/// Read type units from the debug_types sections (if necessary)
/// and store them in TUs.
void parseTypeUnits();
/// and type units from the debug_types sections (if necessary)
/// and store them in NormalUnits.
void parseNormalUnits();
/// Read compile units from the debug_info.dwo section (if necessary)
/// and store them in DWOCUs.
void parseDWOCompileUnits();
/// and type units from the debug_types.dwo section (if necessary)
/// and store them in DWOUnits.
/// If \p Lazy is true, set up to parse but don't actually parse them.
enum { EagerParse = false, LazyParse = true };
void parseDWOUnits(bool Lazy = false);
/// Read type units from the debug_types.dwo section (if necessary)
/// and store them in DWOTUs.
void parseDWOTypeUnits();
protected:
std::unique_ptr<const DWARFObject> DObj;
public:
@ -142,64 +135,81 @@ public:
using cu_iterator_range = DWARFUnitVector::iterator_range;
using tu_iterator_range = DWARFUnitVector::iterator_range;
/// Get compile units in this context.
cu_iterator_range compile_units() {
parseCompileUnits();
return cu_iterator_range(CUs.begin(), CUs.end());
/// Get units from .debug_info in this context.
cu_iterator_range info_section_units() {
parseNormalUnits();
return cu_iterator_range(NormalUnits.begin(),
NormalUnits.begin() +
NormalUnits.getNumInfoUnits());
}
/// Get units from .debug_types in this context.
tu_iterator_range types_section_units() {
parseNormalUnits();
return tu_iterator_range(
NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
}
/// Get compile units in this context.
cu_iterator_range compile_units() { return info_section_units(); }
/// Get type units in this context.
tu_iterator_range type_units() {
parseTypeUnits();
return tu_iterator_range(TUs.begin(), TUs.end());
tu_iterator_range type_units() { return types_section_units(); }
/// Get units from .debug_info..dwo in the DWO context.
cu_iterator_range dwo_info_section_units() {
parseDWOUnits();
return cu_iterator_range(DWOUnits.begin(),
DWOUnits.begin() + DWOUnits.getNumInfoUnits());
}
/// Get units from .debug_types.dwo in the DWO context.
tu_iterator_range dwo_types_section_units() {
parseDWOUnits();
return tu_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
DWOUnits.end());
}
/// Get compile units in the DWO context.
cu_iterator_range dwo_compile_units() {
parseDWOCompileUnits();
return cu_iterator_range(DWOCUs.begin(), DWOCUs.end());
}
cu_iterator_range dwo_compile_units() { return dwo_info_section_units(); }
/// Get type units in the DWO context.
tu_iterator_range dwo_type_units() {
parseDWOTypeUnits();
return tu_iterator_range(DWOTUs.begin(), DWOTUs.end());
}
tu_iterator_range dwo_type_units() { return dwo_types_section_units(); }
/// Get the number of compile units in this context.
unsigned getNumCompileUnits() {
parseCompileUnits();
return CUs.size();
parseNormalUnits();
return NormalUnits.getNumInfoUnits();
}
/// Get the number of compile units in this context.
/// Get the number of type units in this context.
unsigned getNumTypeUnits() {
parseTypeUnits();
return TUs.size();
parseNormalUnits();
return NormalUnits.getNumTypesUnits();
}
/// Get the number of compile units in the DWO context.
unsigned getNumDWOCompileUnits() {
parseDWOCompileUnits();
return DWOCUs.size();
parseDWOUnits();
return DWOUnits.getNumInfoUnits();
}
/// Get the number of compile units in the DWO context.
/// Get the number of type units in the DWO context.
unsigned getNumDWOTypeUnits() {
parseDWOTypeUnits();
return DWOTUs.size();
parseDWOUnits();
return DWOUnits.getNumTypesUnits();
}
/// Get the unit at the specified index.
DWARFUnit *getUnitAtIndex(unsigned index) {
parseCompileUnits();
return CUs[index].get();
parseNormalUnits();
return NormalUnits[index].get();
}
/// Get the unit at the specified index for the DWO units.
DWARFUnit *getDWOUnitAtIndex(unsigned index) {
parseDWOCompileUnits();
return DWOCUs[index].get();
parseDWOUnits();
return DWOUnits[index].get();
}
DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);

View File

@ -104,10 +104,13 @@ public:
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
DWARFSectionKind Kind);
/// Describes one section's Units.
/// Describe a collection of units. Intended to hold all units either from
/// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo.
class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
std::function<std::unique_ptr<DWARFUnit>(uint32_t, const DWARFSection *)>
std::function<std::unique_ptr<DWARFUnit>(uint32_t, DWARFSectionKind,
const DWARFSection *)>
Parser;
unsigned NumInfoUnits = 0;
public:
using UnitVector = SmallVectorImpl<std::unique_ptr<DWARFUnit>>;
@ -116,11 +119,31 @@ public:
DWARFUnit *getUnitForOffset(uint32_t Offset) const;
DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
/// Read units from a .debug_info or .debug_types section. Calls made
/// before finishedInfoUnits() are assumed to be for .debug_info sections,
/// calls after finishedInfoUnits() are for .debug_types sections. Caller
/// must not mix calls to addUnitsForSection and addUnitsForDWOSection.
void addUnitsForSection(DWARFContext &C, const DWARFSection &Section,
DWARFSectionKind SectionKind);
/// Read units from a .debug_info.dwo or .debug_types.dwo section. Calls
/// made before finishedInfoUnits() are assumed to be for .debug_info.dwo
/// sections, calls after finishedInfoUnits() are for .debug_types.dwo
/// sections. Caller must not mix calls to addUnitsForSection and
/// addUnitsForDWOSection.
void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection,
DWARFSectionKind SectionKind, bool Lazy = false);
/// Returns number of all units held by this instance.
unsigned getNumUnits() { return size(); }
/// Returns number of units from all .debug_info[.dwo] sections.
unsigned getNumInfoUnits() { return NumInfoUnits; }
/// Returns number of units from all .debug_types[.dwo] sections.
unsigned getNumTypesUnits() { return size() - NumInfoUnits; }
/// Indicate that parsing .debug_info[.dwo] is done, and remaining units
/// will be from .debug_types[.dwo].
void finishedInfoUnits() { NumInfoUnits = size(); }
private:
void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj,
const DWARFSection &Section, const DWARFDebugAbbrev *DA,
@ -238,6 +261,7 @@ public:
virtual ~DWARFUnit();
DWARFContext& getContext() const { return Context; }
const DWARFSection &getInfoSection() const { return InfoSection; }
uint32_t getOffset() const { return Header.getOffset(); }
const dwarf::FormParams &getFormParams() const {
return Header.getFormParams();

View File

@ -351,9 +351,9 @@ void DWARFContext::dump(
}
};
dumpDebugInfo(Explicit, ".debug_info", DObj->getInfoSection(),
compile_units());
info_section_units());
dumpDebugInfo(ExplicitDWO, ".debug_info.dwo", DObj->getInfoDWOSection(),
dwo_compile_units());
dwo_info_section_units());
auto dumpDebugType = [&](const char *Name, tu_iterator_range TUs) {
OS << '\n' << Name << " contents:\n";
@ -367,9 +367,9 @@ void DWARFContext::dump(
};
if ((DumpType & DIDT_DebugTypes)) {
if (Explicit || getNumTypeUnits())
dumpDebugType(".debug_types", type_units());
dumpDebugType(".debug_types", types_section_units());
if (ExplicitDWO || getNumDWOTypeUnits())
dumpDebugType(".debug_types.dwo", dwo_type_units());
dumpDebugType(".debug_types.dwo", dwo_types_section_units());
}
if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
@ -581,13 +581,12 @@ void DWARFContext::dump(
}
DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
if (DWOCUs.empty())
DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
true);
parseDWOUnits(LazyParse);
if (const auto &CUI = getCUIndex()) {
if (const auto *R = CUI.getFromHash(Hash))
return dyn_cast_or_null<DWARFCompileUnit>(DWOCUs.getUnitForIndexEntry(*R));
return dyn_cast_or_null<DWARFCompileUnit>(
DWOUnits.getUnitForIndexEntry(*R));
return nullptr;
}
@ -612,8 +611,8 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
}
DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
parseCompileUnits();
if (auto *CU = CUs.getUnitForOffset(Offset))
parseNormalUnits();
if (auto *CU = NormalUnits.getUnitForOffset(Offset))
return CU->getDIEForOffset(Offset);
return DWARFDie();
}
@ -842,37 +841,31 @@ Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
RecoverableErrorCallback);
}
void DWARFContext::parseCompileUnits() {
if (!CUs.empty())
return;
CUs.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
}
void DWARFContext::parseTypeUnits() {
if (!TUs.empty())
void DWARFContext::parseNormalUnits() {
if (!NormalUnits.empty())
return;
NormalUnits.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
NormalUnits.finishedInfoUnits();
DObj->forEachTypesSections([&](const DWARFSection &S) {
TUs.addUnitsForSection(*this, S, DW_SECT_TYPES);
NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
});
}
void DWARFContext::parseDWOCompileUnits() {
if (!DWOCUs.empty())
return;
DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO);
}
void DWARFContext::parseDWOTypeUnits() {
if (!DWOTUs.empty())
void DWARFContext::parseDWOUnits(bool Lazy) {
if (!DWOUnits.empty())
return;
DWOUnits.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
Lazy);
DWOUnits.finishedInfoUnits();
DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
DWOTUs.addUnitsForDWOSection(*this, S, DW_SECT_TYPES);
DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
});
}
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
parseCompileUnits();
return dyn_cast_or_null<DWARFCompileUnit>(CUs.getUnitForOffset(Offset));
parseNormalUnits();
return dyn_cast_or_null<DWARFCompileUnit>(
NormalUnits.getUnitForOffset(Offset));
}
DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {

View File

@ -62,16 +62,16 @@ void DWARFUnitVector::addUnitsImpl(
DWARFDataExtractor Data(Obj, Section, LE, 0);
// Lazy initialization of Parser, now that we have all section info.
if (!Parser) {
const DWARFUnitIndex *Index = nullptr;
if (IsDWO)
Index = &getDWARFUnitIndex(Context, SectionKind);
Parser = [=, &Context, &Obj, &Section, &SOS, &LS](
uint32_t Offset,
uint32_t Offset, DWARFSectionKind SectionKind,
const DWARFSection *CurSection) -> std::unique_ptr<DWARFUnit> {
const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
if (!Data.isValidOffset(Offset))
return nullptr;
const DWARFUnitIndex *Index = nullptr;
if (IsDWO)
Index = &getDWARFUnitIndex(Context, SectionKind);
DWARFUnitHeader Header;
if (!Header.extract(Context, Data, &Offset, SectionKind, Index))
return nullptr;
@ -89,14 +89,21 @@ void DWARFUnitVector::addUnitsImpl(
}
if (Lazy)
return;
// Find a reasonable insertion point within the vector. We skip over
// (a) units from a different section, (b) units from the same section
// but with lower offset-within-section. This keeps units in order
// within a section, although not necessarily within the object file,
// even if we do lazy parsing.
auto I = this->begin();
uint32_t Offset = 0;
while (Data.isValidOffset(Offset)) {
if (I != this->end() && (*I)->getOffset() == Offset) {
if (I != this->end() &&
(&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
++I;
continue;
}
auto U = Parser(Offset, &Section);
auto U = Parser(Offset, SectionKind, &Section);
// If parsing failed, we're done with this section.
if (!U)
break;
Offset = U->getNextUnitOffset();
@ -134,7 +141,7 @@ DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
if (!Parser)
return nullptr;
auto U = Parser(Offset, nullptr);
auto U = Parser(Offset, DW_SECT_INFO, nullptr);
if (!U)
U = nullptr;