forked from OSchip/llvm-project
General cleanup to minimize the .debug_types patch
This cleanup is designed to make the https://reviews.llvm.org/D32167 patch smaller and easier to read. Cleanup in this patch: Allow DWARFUnit subclasses to hand out the data that should be used when decoding data for a DIE. The information might be in .debug_info or could be in .debug_types. There is a new virtual function on DWARFUnit that each subclass must override: virtual const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const; This allows DWARFCompileUnit and eventually DWARFTypeUnit to hand out different data to be used when decoding the DIE information. Add a new pure virtual function to get the size of the DWARF unit header: virtual uint32_t DWARFUnit::GetHeaderByteSize() const = 0; This allows DWARFCompileUnit and eventually DWARFTypeUnit to hand out different offsets where the first DIE starts when decoding DIE information from the unit. Added a new function to DWARFDataExtractor to get the size of an offset: size_t DWARFDataExtractor::GetDWARFSizeOfOffset() const; Removed dead dumping and parsing code in the DWARFDebugInfo class. Inlined a bunch of calls in DWARFUnit for accessors that were just returning integer member variables. Renamed DWARFUnit::Size() to DWARFUnit::GetHeaderByteSize() as it clearly states what it is doing and makes more sense. Differential Revision: https://reviews.llvm.org/D46606 llvm-svn: 331892
This commit is contained in:
parent
e330071b43
commit
f56c30d13b
|
@ -76,6 +76,7 @@ class ConnectionFileDescriptor;
|
||||||
class ConstString;
|
class ConstString;
|
||||||
class CXXSyntheticChildren;
|
class CXXSyntheticChildren;
|
||||||
class DWARFCallFrameInfo;
|
class DWARFCallFrameInfo;
|
||||||
|
class DWARFDataExtractor;
|
||||||
class DWARFExpression;
|
class DWARFExpression;
|
||||||
class DataBuffer;
|
class DataBuffer;
|
||||||
class DataEncoder;
|
class DataEncoder;
|
||||||
|
|
|
@ -2868,8 +2868,7 @@ bool DWARFASTParserClang::ParseChildMembers(
|
||||||
if (form_value.BlockData()) {
|
if (form_value.BlockData()) {
|
||||||
Value initialValue(0);
|
Value initialValue(0);
|
||||||
Value memberOffset(0);
|
Value memberOffset(0);
|
||||||
const DWARFDataExtractor &debug_info_data =
|
const DWARFDataExtractor &debug_info_data = die.GetData();
|
||||||
die.GetDWARF()->get_debug_info_data();
|
|
||||||
uint32_t block_length = form_value.Unsigned();
|
uint32_t block_length = form_value.Unsigned();
|
||||||
uint32_t block_offset =
|
uint32_t block_offset =
|
||||||
form_value.BlockData() - debug_info_data.GetDataStart();
|
form_value.BlockData() - debug_info_data.GetDataStart();
|
||||||
|
@ -3330,8 +3329,7 @@ bool DWARFASTParserClang::ParseChildMembers(
|
||||||
if (form_value.BlockData()) {
|
if (form_value.BlockData()) {
|
||||||
Value initialValue(0);
|
Value initialValue(0);
|
||||||
Value memberOffset(0);
|
Value memberOffset(0);
|
||||||
const DWARFDataExtractor &debug_info_data =
|
const DWARFDataExtractor &debug_info_data = die.GetData();
|
||||||
die.GetDWARF()->get_debug_info_data();
|
|
||||||
uint32_t block_length = form_value.Unsigned();
|
uint32_t block_length = form_value.Unsigned();
|
||||||
uint32_t block_offset =
|
uint32_t block_offset =
|
||||||
form_value.BlockData() - debug_info_data.GetDataStart();
|
form_value.BlockData() - debug_info_data.GetDataStart();
|
||||||
|
|
|
@ -655,8 +655,7 @@ size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
|
||||||
if (form_value.BlockData()) {
|
if (form_value.BlockData()) {
|
||||||
Value initialValue(0);
|
Value initialValue(0);
|
||||||
Value memberOffset(0);
|
Value memberOffset(0);
|
||||||
const DWARFDataExtractor &debug_info_data =
|
const DWARFDataExtractor &debug_info_data = die.GetData();
|
||||||
die.GetDWARF()->get_debug_info_data();
|
|
||||||
uint32_t block_length = form_value.Unsigned();
|
uint32_t block_length = form_value.Unsigned();
|
||||||
uint32_t block_offset =
|
uint32_t block_offset =
|
||||||
form_value.BlockData() - debug_info_data.GetDataStart();
|
form_value.BlockData() - debug_info_data.GetDataStart();
|
||||||
|
|
|
@ -52,8 +52,7 @@ bool DWARFAttributes::ExtractFormValueAtIndex(
|
||||||
form_value.SetCompileUnit(cu);
|
form_value.SetCompileUnit(cu);
|
||||||
form_value.SetForm(FormAtIndex(i));
|
form_value.SetForm(FormAtIndex(i));
|
||||||
lldb::offset_t offset = DIEOffsetAtIndex(i);
|
lldb::offset_t offset = DIEOffsetAtIndex(i);
|
||||||
return form_value.ExtractValue(
|
return form_value.ExtractValue(cu->GetData(), &offset);
|
||||||
cu->GetSymbolFileDWARF()->get_debug_info_data(), &offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DWARFAttributes::FormValueAsUnsigned(dw_attr_t attr,
|
uint64_t DWARFAttributes::FormValueAsUnsigned(dw_attr_t attr,
|
||||||
|
|
|
@ -20,14 +20,10 @@ DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data)
|
||||||
: DWARFUnit(dwarf2Data) {}
|
: DWARFUnit(dwarf2Data) {}
|
||||||
|
|
||||||
DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
|
DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
|
||||||
lldb::offset_t *offset_ptr) {
|
const DWARFDataExtractor &debug_info,
|
||||||
|
lldb::offset_t *offset_ptr) {
|
||||||
// std::make_shared would require the ctor to be public.
|
// std::make_shared would require the ctor to be public.
|
||||||
std::shared_ptr<DWARFCompileUnit> cu_sp(new DWARFCompileUnit(dwarf2Data));
|
std::shared_ptr<DWARFCompileUnit> cu_sp(new DWARFCompileUnit(dwarf2Data));
|
||||||
// Out of memory?
|
|
||||||
if (cu_sp.get() == NULL)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
const DWARFDataExtractor &debug_info = dwarf2Data->get_debug_info_data();
|
|
||||||
|
|
||||||
cu_sp->m_offset = *offset_ptr;
|
cu_sp->m_offset = *offset_ptr;
|
||||||
|
|
||||||
|
@ -67,3 +63,8 @@ void DWARFCompileUnit::Dump(Stream *s) const {
|
||||||
m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size,
|
m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size,
|
||||||
GetNextCompileUnitOffset());
|
GetNextCompileUnitOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
|
||||||
|
return m_dwarf->get_debug_info_data();
|
||||||
|
}
|
||||||
|
|
|
@ -17,9 +17,30 @@ class DWARFCompileUnit : public DWARFUnit {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static DWARFUnitSP Extract(SymbolFileDWARF *dwarf2Data,
|
static DWARFUnitSP Extract(SymbolFileDWARF *dwarf2Data,
|
||||||
lldb::offset_t *offset_ptr);
|
const lldb_private::DWARFDataExtractor &debug_info,
|
||||||
|
lldb::offset_t *offset_ptr);
|
||||||
void Dump(lldb_private::Stream *s) const override;
|
void Dump(lldb_private::Stream *s) const override;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
/// Get the data that contains the DIE information for this unit.
|
||||||
|
///
|
||||||
|
/// @return
|
||||||
|
/// The correct data (.debug_types for DWARF 4 and earlier, and
|
||||||
|
/// .debug_info for DWARF 5 and later) for the DIE information in
|
||||||
|
/// this unit.
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
const lldb_private::DWARFDataExtractor &GetData() const override;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
/// Get the size in bytes of the header.
|
||||||
|
///
|
||||||
|
/// @return
|
||||||
|
/// Byte size of the compile unit header
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
uint32_t GetHeaderByteSize() const override {
|
||||||
|
return m_is_dwarf64 ? 23 : 11;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
|
DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
|
||||||
DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit);
|
DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit);
|
||||||
|
|
|
@ -460,3 +460,9 @@ bool operator==(const DWARFDIE &lhs, const DWARFDIE &rhs) {
|
||||||
bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs) {
|
bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs) {
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DWARFDataExtractor &DWARFDIE::GetData() const {
|
||||||
|
// Clients must check if this DIE is valid before calling this function.
|
||||||
|
assert(IsValid());
|
||||||
|
return m_cu->GetData();
|
||||||
|
}
|
||||||
|
|
|
@ -86,6 +86,16 @@ public:
|
||||||
DWARFDIE
|
DWARFDIE
|
||||||
GetContainingDWOModuleDIE() const;
|
GetContainingDWOModuleDIE() const;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Get the data that contains the attribute values for this DIE. Support
|
||||||
|
// for .debug_types means that any DIE can have its data either in the
|
||||||
|
// .debug_info or the .debug_types section; this method will return the
|
||||||
|
// correct section data.
|
||||||
|
//
|
||||||
|
// Clients must validate that this object is valid before calling this.
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
const lldb_private::DWARFDataExtractor &GetData() const;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Accessing information about a DIE
|
// Accessing information about a DIE
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
|
@ -22,6 +22,6 @@ DWARFDataExtractor::GetDWARFInitialLength(lldb::offset_t *offset_ptr) const {
|
||||||
|
|
||||||
dw_offset_t
|
dw_offset_t
|
||||||
DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const {
|
DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const {
|
||||||
return GetMaxU64(offset_ptr, m_is_dwarf64 ? 8 : 4);
|
return GetMaxU64(offset_ptr, GetDWARFSizeOfOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const;
|
dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const;
|
||||||
|
|
||||||
size_t GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; }
|
size_t GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; }
|
||||||
|
size_t GetDWARFSizeOfOffset() const { return m_is_dwarf64 ? 8 : 4; }
|
||||||
bool IsDWARF64() const { return m_is_dwarf64; }
|
bool IsDWARF64() const { return m_is_dwarf64; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -98,7 +98,9 @@ void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() {
|
||||||
if (m_dwarf2Data != NULL) {
|
if (m_dwarf2Data != NULL) {
|
||||||
lldb::offset_t offset = 0;
|
lldb::offset_t offset = 0;
|
||||||
DWARFUnitSP cu_sp;
|
DWARFUnitSP cu_sp;
|
||||||
while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, &offset))) {
|
const auto &debug_info_data = m_dwarf2Data->get_debug_info_data();
|
||||||
|
while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data,
|
||||||
|
&offset))) {
|
||||||
m_compile_units.push_back(cu_sp);
|
m_compile_units.push_back(cu_sp);
|
||||||
|
|
||||||
offset = cu_sp->GetNextCompileUnitOffset();
|
offset = cu_sp->GetNextCompileUnitOffset();
|
||||||
|
@ -224,268 +226,3 @@ DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
|
||||||
return DWARFDIE(); // Not found
|
return DWARFDIE(); // Not found
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// Parse
|
|
||||||
//
|
|
||||||
// Parses the .debug_info section and uses the .debug_abbrev section and
|
|
||||||
// various other sections in the SymbolFileDWARF class and calls the supplied
|
|
||||||
// callback function each time a compile unit header, or debug information
|
|
||||||
// entry is successfully parsed. This function can be used for different tasks
|
|
||||||
// such as parsing the file contents into a structured data, dumping, verifying
|
|
||||||
// and much more.
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback,
|
|
||||||
void *userData) {
|
|
||||||
if (dwarf2Data) {
|
|
||||||
lldb::offset_t offset = 0;
|
|
||||||
uint32_t depth = 0;
|
|
||||||
DWARFDebugInfoEntry die;
|
|
||||||
|
|
||||||
DWARFUnitSP cu;
|
|
||||||
while ((cu = DWARFCompileUnit::Extract(dwarf2Data, &offset))) {
|
|
||||||
const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();
|
|
||||||
|
|
||||||
depth = 0;
|
|
||||||
// Call the callback function with no DIE pointer for the compile unit
|
|
||||||
// and get the offset that we are to continue to parse from
|
|
||||||
offset = callback(dwarf2Data, cu.get(), NULL, offset, depth, userData);
|
|
||||||
|
|
||||||
// Make sure we are within our compile unit
|
|
||||||
if (offset < next_cu_offset) {
|
|
||||||
// We are in our compile unit, parse starting at the offset we were
|
|
||||||
// told to parse
|
|
||||||
bool done = false;
|
|
||||||
while (!done && die.Extract(dwarf2Data, cu.get(), &offset)) {
|
|
||||||
// Call the callback function with DIE pointer that falls within the
|
|
||||||
// compile unit
|
|
||||||
offset =
|
|
||||||
callback(dwarf2Data, cu.get(), &die, offset, depth, userData);
|
|
||||||
|
|
||||||
if (die.IsNULL()) {
|
|
||||||
if (depth)
|
|
||||||
--depth;
|
|
||||||
else
|
|
||||||
done = true; // We are done with this compile unit!
|
|
||||||
} else if (die.HasChildren())
|
|
||||||
++depth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the offset returned is valid, and if not stop parsing.
|
|
||||||
// Returning DW_INVALID_OFFSET from this callback is a good way to end
|
|
||||||
// all parsing
|
|
||||||
if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Make sure we start on a proper
|
|
||||||
offset = next_cu_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct DumpInfo {
|
|
||||||
DumpInfo(Stream *init_strm, uint32_t off, uint32_t depth)
|
|
||||||
: strm(init_strm), die_offset(off), recurse_depth(depth),
|
|
||||||
found_depth(UINT32_MAX), found_die(false), ancestors() {}
|
|
||||||
Stream *strm;
|
|
||||||
const uint32_t die_offset;
|
|
||||||
const uint32_t recurse_depth;
|
|
||||||
uint32_t found_depth;
|
|
||||||
bool found_die;
|
|
||||||
std::vector<DWARFDebugInfoEntry> ancestors;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(DumpInfo);
|
|
||||||
} DumpInfo;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// DumpCallback
|
|
||||||
//
|
|
||||||
// A callback function for the static DWARFDebugInfo::Parse() function
|
|
||||||
// that gets called each time a compile unit header or debug information entry
|
|
||||||
// is successfully parsed.
|
|
||||||
//
|
|
||||||
// This function dump DWARF information and obey recurse depth and whether a
|
|
||||||
// single DIE is to be dumped (or all of the data).
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
static dw_offset_t DumpCallback(SymbolFileDWARF *dwarf2Data,
|
|
||||||
DWARFUnit *cu, DWARFDebugInfoEntry *die,
|
|
||||||
const dw_offset_t next_offset,
|
|
||||||
const uint32_t curr_depth, void *userData) {
|
|
||||||
DumpInfo *dumpInfo = (DumpInfo *)userData;
|
|
||||||
Stream *s = dumpInfo->strm;
|
|
||||||
bool show_parents =
|
|
||||||
s->GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowAncestors);
|
|
||||||
|
|
||||||
if (die) {
|
|
||||||
// Are we dumping everything?
|
|
||||||
if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
|
|
||||||
// Yes we are dumping everything. Obey our recurse level though
|
|
||||||
if (curr_depth < dumpInfo->recurse_depth)
|
|
||||||
die->Dump(dwarf2Data, cu, *s, 0);
|
|
||||||
} else {
|
|
||||||
// We are dumping a specific DIE entry by offset
|
|
||||||
if (dumpInfo->die_offset == die->GetOffset()) {
|
|
||||||
// We found the DIE we were looking for, dump it!
|
|
||||||
if (show_parents) {
|
|
||||||
s->SetIndentLevel(0);
|
|
||||||
const uint32_t num_ancestors = dumpInfo->ancestors.size();
|
|
||||||
if (num_ancestors > 0) {
|
|
||||||
for (uint32_t i = 0; i < num_ancestors - 1; ++i) {
|
|
||||||
dumpInfo->ancestors[i].Dump(dwarf2Data, cu, *s, 0);
|
|
||||||
s->IndentMore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dumpInfo->found_depth = curr_depth;
|
|
||||||
|
|
||||||
die->Dump(dwarf2Data, cu, *s, 0);
|
|
||||||
|
|
||||||
// Note that we found the DIE we were looking for
|
|
||||||
dumpInfo->found_die = true;
|
|
||||||
|
|
||||||
// Since we are dumping a single DIE, if there are no children we are
|
|
||||||
// done!
|
|
||||||
if (!die->HasChildren() || dumpInfo->recurse_depth == 0)
|
|
||||||
return DW_INVALID_OFFSET; // Return an invalid address to end parsing
|
|
||||||
} else if (dumpInfo->found_die) {
|
|
||||||
// Are we done with all the children?
|
|
||||||
if (curr_depth <= dumpInfo->found_depth)
|
|
||||||
return DW_INVALID_OFFSET;
|
|
||||||
|
|
||||||
// We have already found our DIE and are printing it's children. Obey
|
|
||||||
// our recurse depth and return an invalid offset if we get done
|
|
||||||
// dumping all of the children
|
|
||||||
if (dumpInfo->recurse_depth == UINT32_MAX ||
|
|
||||||
curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth)
|
|
||||||
die->Dump(dwarf2Data, cu, *s, 0);
|
|
||||||
} else if (dumpInfo->die_offset > die->GetOffset()) {
|
|
||||||
if (show_parents)
|
|
||||||
dumpInfo->ancestors.back() = *die;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep up with our indent level
|
|
||||||
if (die->IsNULL()) {
|
|
||||||
if (show_parents)
|
|
||||||
dumpInfo->ancestors.pop_back();
|
|
||||||
|
|
||||||
if (curr_depth <= 1)
|
|
||||||
return cu->GetNextCompileUnitOffset();
|
|
||||||
else
|
|
||||||
s->IndentLess();
|
|
||||||
} else if (die->HasChildren()) {
|
|
||||||
if (show_parents) {
|
|
||||||
DWARFDebugInfoEntry null_die;
|
|
||||||
dumpInfo->ancestors.push_back(null_die);
|
|
||||||
}
|
|
||||||
s->IndentMore();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (cu == NULL)
|
|
||||||
s->PutCString("NULL - cu");
|
|
||||||
// We have a compile unit, reset our indent level to zero just in case
|
|
||||||
s->SetIndentLevel(0);
|
|
||||||
|
|
||||||
// See if we are dumping everything?
|
|
||||||
if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
|
|
||||||
// We are dumping everything
|
|
||||||
if (cu) {
|
|
||||||
cu->Dump(s);
|
|
||||||
return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this
|
|
||||||
// Compile Unit
|
|
||||||
} else {
|
|
||||||
return DW_INVALID_OFFSET;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (show_parents) {
|
|
||||||
dumpInfo->ancestors.clear();
|
|
||||||
dumpInfo->ancestors.resize(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are dumping only a single DIE possibly with it's children and we
|
|
||||||
// must find it's compile unit before we can dump it properly
|
|
||||||
if (cu && dumpInfo->die_offset < cu->GetFirstDIEOffset()) {
|
|
||||||
// Not found, maybe the DIE offset provided wasn't correct?
|
|
||||||
// *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << "
|
|
||||||
// was not found." << endl;
|
|
||||||
return DW_INVALID_OFFSET;
|
|
||||||
} else {
|
|
||||||
// See if the DIE is in this compile unit?
|
|
||||||
if (cu && dumpInfo->die_offset < cu->GetNextCompileUnitOffset()) {
|
|
||||||
return next_offset;
|
|
||||||
// // We found our compile unit that contains our DIE, just skip to
|
|
||||||
// dumping the requested DIE...
|
|
||||||
// return dumpInfo->die_offset;
|
|
||||||
} else {
|
|
||||||
// Skip to the next compile unit as the DIE isn't in the current one!
|
|
||||||
if (cu) {
|
|
||||||
return cu->GetNextCompileUnitOffset();
|
|
||||||
} else {
|
|
||||||
return DW_INVALID_OFFSET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just return the current offset to parse the next CU or DIE entry
|
|
||||||
return next_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// Dump
|
|
||||||
//
|
|
||||||
// Dump the information in the .debug_info section to the specified ostream. If
|
|
||||||
// die_offset is valid, a single DIE will be dumped. If the die_offset is
|
|
||||||
// invalid, all the DWARF information will be dumped. Both cases will obey a
|
|
||||||
// "recurse_depth" or how deep to traverse into the children of each DIE entry.
|
|
||||||
// A recurse_depth of zero will dump all compile unit headers. A recurse_depth
|
|
||||||
// of 1 will dump all compile unit headers and the DW_TAG_compile unit tags. A
|
|
||||||
// depth of 2 will also dump all types and functions.
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
void DWARFDebugInfo::Dump(Stream *s, SymbolFileDWARF *dwarf2Data,
|
|
||||||
const uint32_t die_offset,
|
|
||||||
const uint32_t recurse_depth) {
|
|
||||||
DumpInfo dumpInfo(s, die_offset, recurse_depth);
|
|
||||||
s->PutCString(".debug_info contents");
|
|
||||||
if (dwarf2Data->get_debug_info_data().GetByteSize() > 0) {
|
|
||||||
if (die_offset == DW_INVALID_OFFSET)
|
|
||||||
s->PutCString(":\n");
|
|
||||||
else {
|
|
||||||
s->Printf(" for DIE entry at .debug_info[0x%8.8x]", die_offset);
|
|
||||||
if (recurse_depth != UINT32_MAX)
|
|
||||||
s->Printf(" recursing %u levels deep.", recurse_depth);
|
|
||||||
s->EOL();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
s->PutCString(": < EMPTY >\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DWARFDebugInfo::Parse(dwarf2Data, DumpCallback, &dumpInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// Dump
|
|
||||||
//
|
|
||||||
// Dump the contents of this DWARFDebugInfo object as has been parsed and/or
|
|
||||||
// modified after it has been parsed.
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
void DWARFDebugInfo::Dump(Stream *s, const uint32_t die_offset,
|
|
||||||
const uint32_t recurse_depth) {
|
|
||||||
DumpInfo dumpInfo(s, die_offset, recurse_depth);
|
|
||||||
|
|
||||||
s->PutCString("Dumping .debug_info section from internal representation\n");
|
|
||||||
|
|
||||||
CompileUnitColl::const_iterator pos;
|
|
||||||
uint32_t curr_depth = 0;
|
|
||||||
ParseCompileUnitHeadersIfNeeded();
|
|
||||||
for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) {
|
|
||||||
DWARFUnit *cu = pos->get();
|
|
||||||
DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo);
|
|
||||||
|
|
||||||
const DWARFDIE die = cu->DIE();
|
|
||||||
if (die)
|
|
||||||
die.Dump(s, recurse_depth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -44,13 +44,6 @@ public:
|
||||||
DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset);
|
DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset);
|
||||||
DWARFDIE GetDIE(const DIERef &die_ref);
|
DWARFDIE GetDIE(const DIERef &die_ref);
|
||||||
|
|
||||||
void Dump(lldb_private::Stream *s, const uint32_t die_offset,
|
|
||||||
const uint32_t recurse_depth);
|
|
||||||
static void Parse(SymbolFileDWARF *parser, Callback callback, void *userData);
|
|
||||||
static void Verify(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data);
|
|
||||||
static void Dump(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data,
|
|
||||||
const uint32_t die_offset, const uint32_t recurse_depth);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
eDumpFlag_Verbose = (1 << 0), // Verbose dumping
|
eDumpFlag_Verbose = (1 << 0), // Verbose dumping
|
||||||
eDumpFlag_ShowForm = (1 << 1), // Show the DW_form type
|
eDumpFlag_ShowForm = (1 << 1), // Show the DW_form type
|
||||||
|
|
|
@ -196,7 +196,7 @@ bool DWARFDebugInfoEntry::FastExtract(
|
||||||
bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
|
bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
|
||||||
const DWARFUnit *cu,
|
const DWARFUnit *cu,
|
||||||
lldb::offset_t *offset_ptr) {
|
lldb::offset_t *offset_ptr) {
|
||||||
const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
|
const DWARFDataExtractor &debug_info_data = cu->GetData();
|
||||||
// const DWARFDataExtractor& debug_str_data =
|
// const DWARFDataExtractor& debug_str_data =
|
||||||
// dwarf2Data->get_debug_str_data();
|
// dwarf2Data->get_debug_str_data();
|
||||||
const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
|
const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
|
||||||
|
@ -403,8 +403,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
|
||||||
lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
|
lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
|
||||||
|
|
||||||
if (abbrevDecl) {
|
if (abbrevDecl) {
|
||||||
const DWARFDataExtractor &debug_info_data =
|
const DWARFDataExtractor &debug_info_data = cu->GetData();
|
||||||
dwarf2Data->get_debug_info_data();
|
|
||||||
|
|
||||||
if (!debug_info_data.ValidOffset(offset))
|
if (!debug_info_data.ValidOffset(offset))
|
||||||
return false;
|
return false;
|
||||||
|
@ -587,7 +586,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
|
||||||
void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
|
void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
|
||||||
const DWARFUnit *cu, Stream &s,
|
const DWARFUnit *cu, Stream &s,
|
||||||
uint32_t recurse_depth) const {
|
uint32_t recurse_depth) const {
|
||||||
const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
|
const DWARFDataExtractor &debug_info_data = cu->GetData();
|
||||||
lldb::offset_t offset = m_offset;
|
lldb::offset_t offset = m_offset;
|
||||||
|
|
||||||
if (debug_info_data.ValidOffset(offset)) {
|
if (debug_info_data.ValidOffset(offset)) {
|
||||||
|
@ -780,8 +779,7 @@ size_t DWARFDebugInfoEntry::GetAttributes(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abbrevDecl) {
|
if (abbrevDecl) {
|
||||||
const DWARFDataExtractor &debug_info_data =
|
const DWARFDataExtractor &debug_info_data = cu->GetData();
|
||||||
dwarf2Data->get_debug_info_data();
|
|
||||||
|
|
||||||
if (fixed_form_sizes.Empty())
|
if (fixed_form_sizes.Empty())
|
||||||
fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
|
fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
|
||||||
|
@ -863,8 +861,7 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
|
||||||
uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
|
uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
|
||||||
|
|
||||||
if (attr_idx != DW_INVALID_INDEX) {
|
if (attr_idx != DW_INVALID_INDEX) {
|
||||||
const DWARFDataExtractor &debug_info_data =
|
const DWARFDataExtractor &debug_info_data = cu->GetData();
|
||||||
dwarf2Data->get_debug_info_data();
|
|
||||||
|
|
||||||
uint32_t idx = 0;
|
uint32_t idx = 0;
|
||||||
while (idx < attr_idx)
|
while (idx < attr_idx)
|
||||||
|
@ -1789,8 +1786,7 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(
|
||||||
// Make sure the abbreviation code still matches. If it doesn't and the
|
// Make sure the abbreviation code still matches. If it doesn't and the
|
||||||
// DWARF data was mmap'ed, the backing file might have been modified
|
// DWARF data was mmap'ed, the backing file might have been modified
|
||||||
// which is bad news.
|
// which is bad news.
|
||||||
const uint64_t abbrev_code =
|
const uint64_t abbrev_code = cu->GetData().GetULEB128(&offset);
|
||||||
dwarf2Data->get_debug_info_data().GetULEB128(&offset);
|
|
||||||
|
|
||||||
if (abbrev_decl->Code() == abbrev_code)
|
if (abbrev_decl->Code() == abbrev_code)
|
||||||
return abbrev_decl;
|
return abbrev_decl;
|
||||||
|
|
|
@ -83,16 +83,16 @@ size_t DWARFUnit::ExtractDIEsIfNeeded(bool cu_die_only) {
|
||||||
uint32_t depth = 0;
|
uint32_t depth = 0;
|
||||||
// We are in our compile unit, parse starting at the offset we were told to
|
// We are in our compile unit, parse starting at the offset we were told to
|
||||||
// parse
|
// parse
|
||||||
const DWARFDataExtractor &debug_info_data = m_dwarf->get_debug_info_data();
|
const DWARFDataExtractor &data = GetData();
|
||||||
std::vector<uint32_t> die_index_stack;
|
std::vector<uint32_t> die_index_stack;
|
||||||
die_index_stack.reserve(32);
|
die_index_stack.reserve(32);
|
||||||
die_index_stack.push_back(0);
|
die_index_stack.push_back(0);
|
||||||
bool prev_die_had_children = false;
|
bool prev_die_had_children = false;
|
||||||
DWARFFormValue::FixedFormSizes fixed_form_sizes =
|
DWARFFormValue::FixedFormSizes fixed_form_sizes =
|
||||||
DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
|
DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(),
|
||||||
m_is_dwarf64);
|
IsDWARF64());
|
||||||
while (offset < next_cu_offset &&
|
while (offset < next_cu_offset &&
|
||||||
die.FastExtract(debug_info_data, this, fixed_form_sizes, &offset)) {
|
die.FastExtract(data, this, fixed_form_sizes, &offset)) {
|
||||||
// if (log)
|
// if (log)
|
||||||
// log->Printf("0x%8.8x: %*.*s%s%s",
|
// log->Printf("0x%8.8x: %*.*s%s%s",
|
||||||
// die.GetOffset(),
|
// die.GetOffset(),
|
||||||
|
@ -276,19 +276,14 @@ lldb::user_id_t DWARFUnit::GetID() const {
|
||||||
return local_id;
|
return local_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DWARFUnit::Size() const { return IsDWARF64() ? 23 : 11; }
|
|
||||||
|
|
||||||
dw_offset_t DWARFUnit::GetNextCompileUnitOffset() const {
|
dw_offset_t DWARFUnit::GetNextCompileUnitOffset() const {
|
||||||
return m_offset + (IsDWARF64() ? 12 : 4) + GetLength();
|
return m_offset + GetLengthByteSize() + GetLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DWARFUnit::GetDebugInfoSize() const {
|
size_t DWARFUnit::GetDebugInfoSize() const {
|
||||||
return (IsDWARF64() ? 12 : 4) + GetLength() - Size();
|
return GetLengthByteSize() + GetLength() - GetHeaderByteSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DWARFUnit::GetLength() const { return m_length; }
|
|
||||||
uint16_t DWARFUnit::GetVersion() const { return m_version; }
|
|
||||||
|
|
||||||
const DWARFAbbreviationDeclarationSet *DWARFUnit::GetAbbreviations() const {
|
const DWARFAbbreviationDeclarationSet *DWARFUnit::GetAbbreviations() const {
|
||||||
return m_abbrevs;
|
return m_abbrevs;
|
||||||
}
|
}
|
||||||
|
@ -297,14 +292,6 @@ dw_offset_t DWARFUnit::GetAbbrevOffset() const {
|
||||||
return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
|
return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t DWARFUnit::GetAddressByteSize() const { return m_addr_size; }
|
|
||||||
|
|
||||||
dw_addr_t DWARFUnit::GetBaseAddress() const { return m_base_addr; }
|
|
||||||
|
|
||||||
dw_addr_t DWARFUnit::GetAddrBase() const { return m_addr_base; }
|
|
||||||
|
|
||||||
dw_addr_t DWARFUnit::GetRangesBase() const { return m_ranges_base; }
|
|
||||||
|
|
||||||
void DWARFUnit::SetAddrBase(dw_addr_t addr_base,
|
void DWARFUnit::SetAddrBase(dw_addr_t addr_base,
|
||||||
dw_addr_t ranges_base,
|
dw_addr_t ranges_base,
|
||||||
dw_offset_t base_obj_offset) {
|
dw_offset_t base_obj_offset) {
|
||||||
|
@ -632,8 +619,6 @@ LanguageType DWARFUnit::GetLanguageType() {
|
||||||
return m_language_type;
|
return m_language_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DWARFUnit::IsDWARF64() const { return m_is_dwarf64; }
|
|
||||||
|
|
||||||
bool DWARFUnit::GetIsOptimized() {
|
bool DWARFUnit::GetIsOptimized() {
|
||||||
if (m_is_optimized == eLazyBoolCalculate) {
|
if (m_is_optimized == eLazyBoolCalculate) {
|
||||||
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
|
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
|
||||||
|
@ -1010,3 +995,4 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
|
||||||
}
|
}
|
||||||
return *m_func_aranges_ap.get();
|
return *m_func_aranges_ap.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,28 +44,57 @@ public:
|
||||||
uint32_t depth = UINT32_MAX) const;
|
uint32_t depth = UINT32_MAX) const;
|
||||||
bool Verify(lldb_private::Stream *s) const;
|
bool Verify(lldb_private::Stream *s) const;
|
||||||
virtual void Dump(lldb_private::Stream *s) const = 0;
|
virtual void Dump(lldb_private::Stream *s) const = 0;
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
/// Get the data that contains the DIE information for this unit.
|
||||||
|
///
|
||||||
|
/// This will return the correct bytes that contain the data for
|
||||||
|
/// this DWARFUnit. It could be .debug_info or .debug_types
|
||||||
|
/// depending on where the data for this unit originates.
|
||||||
|
///
|
||||||
|
/// @return
|
||||||
|
/// The correct data for the DIE information in this unit.
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
virtual const lldb_private::DWARFDataExtractor &GetData() const = 0;
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
/// Get the size in bytes of the compile unit header.
|
||||||
|
///
|
||||||
|
/// @return
|
||||||
|
/// Byte size of the compile unit header
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
virtual uint32_t GetHeaderByteSize() const = 0;
|
||||||
// Offset of the initial length field.
|
// Offset of the initial length field.
|
||||||
dw_offset_t GetOffset() const { return m_offset; }
|
dw_offset_t GetOffset() const { return m_offset; }
|
||||||
lldb::user_id_t GetID() const;
|
lldb::user_id_t GetID() const;
|
||||||
// Size in bytes of the initial length + compile unit header.
|
//------------------------------------------------------------------
|
||||||
uint32_t Size() const;
|
/// Get the size in bytes of the length field in the header.
|
||||||
|
///
|
||||||
|
/// In DWARF32 this is just 4 bytes, and DWARF64 it is 12 where 4
|
||||||
|
/// are 0xFFFFFFFF followed by the actual 64 bit length.
|
||||||
|
///
|
||||||
|
/// @return
|
||||||
|
/// Byte size of the compile unit header length field
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
size_t GetLengthByteSize() const { return IsDWARF64() ? 12 : 4; }
|
||||||
|
|
||||||
bool ContainsDIEOffset(dw_offset_t die_offset) const {
|
bool ContainsDIEOffset(dw_offset_t die_offset) const {
|
||||||
return die_offset >= GetFirstDIEOffset() &&
|
return die_offset >= GetFirstDIEOffset() &&
|
||||||
die_offset < GetNextCompileUnitOffset();
|
die_offset < GetNextCompileUnitOffset();
|
||||||
}
|
}
|
||||||
dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
|
dw_offset_t GetFirstDIEOffset() const {
|
||||||
|
return m_offset + GetHeaderByteSize();
|
||||||
|
}
|
||||||
dw_offset_t GetNextCompileUnitOffset() const;
|
dw_offset_t GetNextCompileUnitOffset() const;
|
||||||
// Size of the CU data (without initial length and without header).
|
// Size of the CU data (without initial length and without header).
|
||||||
size_t GetDebugInfoSize() const;
|
size_t GetDebugInfoSize() const;
|
||||||
// Size of the CU data incl. header but without initial length.
|
// Size of the CU data incl. header but without initial length.
|
||||||
uint32_t GetLength() const;
|
uint32_t GetLength() const { return m_length; }
|
||||||
uint16_t GetVersion() const;
|
uint16_t GetVersion() const { return m_version; }
|
||||||
const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
|
const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
|
||||||
dw_offset_t GetAbbrevOffset() const;
|
dw_offset_t GetAbbrevOffset() const;
|
||||||
uint8_t GetAddressByteSize() const;
|
uint8_t GetAddressByteSize() const { return m_addr_size; }
|
||||||
dw_addr_t GetBaseAddress() const;
|
dw_addr_t GetBaseAddress() const { return m_base_addr; }
|
||||||
dw_addr_t GetAddrBase() const;
|
dw_addr_t GetAddrBase() const { return m_addr_base; }
|
||||||
dw_addr_t GetRangesBase() const;
|
dw_addr_t GetRangesBase() const { return m_ranges_base; }
|
||||||
void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base,
|
void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base,
|
||||||
dw_offset_t base_obj_offset);
|
dw_offset_t base_obj_offset);
|
||||||
void ClearDIEs(bool keep_compile_unit_die);
|
void ClearDIEs(bool keep_compile_unit_die);
|
||||||
|
@ -125,7 +154,7 @@ public:
|
||||||
|
|
||||||
lldb::LanguageType GetLanguageType();
|
lldb::LanguageType GetLanguageType();
|
||||||
|
|
||||||
bool IsDWARF64() const;
|
bool IsDWARF64() const { return m_is_dwarf64; }
|
||||||
|
|
||||||
bool GetIsOptimized();
|
bool GetIsOptimized();
|
||||||
|
|
||||||
|
|
|
@ -3758,7 +3758,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
|
||||||
location_is_const_value_data = true;
|
location_is_const_value_data = true;
|
||||||
// The constant value will be either a block, a data value or a
|
// The constant value will be either a block, a data value or a
|
||||||
// string.
|
// string.
|
||||||
const DWARFDataExtractor &debug_info_data = get_debug_info_data();
|
auto debug_info_data = die.GetData();
|
||||||
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
|
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
|
||||||
// Retrieve the value as a block expression.
|
// Retrieve the value as a block expression.
|
||||||
uint32_t block_offset =
|
uint32_t block_offset =
|
||||||
|
@ -3815,13 +3815,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
|
||||||
location_is_const_value_data = false;
|
location_is_const_value_data = false;
|
||||||
has_explicit_location = true;
|
has_explicit_location = true;
|
||||||
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
|
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
|
||||||
const DWARFDataExtractor &debug_info_data = get_debug_info_data();
|
auto data = die.GetData();
|
||||||
|
|
||||||
uint32_t block_offset =
|
uint32_t block_offset =
|
||||||
form_value.BlockData() - debug_info_data.GetDataStart();
|
form_value.BlockData() - data.GetDataStart();
|
||||||
uint32_t block_length = form_value.Unsigned();
|
uint32_t block_length = form_value.Unsigned();
|
||||||
location.CopyOpcodeData(module, get_debug_info_data(),
|
location.CopyOpcodeData(module, data, block_offset, block_length);
|
||||||
block_offset, block_length);
|
|
||||||
} else {
|
} else {
|
||||||
const DWARFDataExtractor &debug_loc_data = get_debug_loc_data();
|
const DWARFDataExtractor &debug_loc_data = get_debug_loc_data();
|
||||||
const dw_offset_t debug_loc_offset = form_value.Unsigned();
|
const dw_offset_t debug_loc_offset = form_value.Unsigned();
|
||||||
|
|
Loading…
Reference in New Issue