[llvm-commits] [llvm] r139732 - in /llvm/trunk/lib/DebugInfo: DWARFCompileUnit.cpp DWARFCompileUnit.h DWARFContext.cpp DWARFDebugAranges.cpp DWARFDebugAranges.h DWARFDebugInfoEntry.cpp DWARFDebugInfoEntry.h
Benjamin Kramer
benny.kra at googlemail.com
Wed Sep 14 13:52:27 PDT 2011
Author: d0k
Date: Wed Sep 14 15:52:27 2011
New Revision: 139732
URL: http://llvm.org/viewvc/llvm-project?rev=139732&view=rev
Log:
DWARF: Generate the address lookup table from the DIE tree if .debug_aranges is not available.
Ported from LLDB.
Modified:
llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp
llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h
llvm/trunk/lib/DebugInfo/DWARFContext.cpp
llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h
llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h
Modified: llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp?rev=139732&r1=139731&r2=139732&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp Wed Sep 14 15:52:27 2011
@@ -200,3 +200,40 @@
setDIERelations();
return DieArray.size();
}
+
+void DWARFCompileUnit::clearDIEs(bool keep_compile_unit_die) {
+ if (DieArray.size() > 1) {
+ // std::vectors never get any smaller when resized to a smaller size,
+ // or when clear() or erase() are called, the size will report that it
+ // is smaller, but the memory allocated remains intact (call capacity()
+ // to see this). So we need to create a temporary vector and swap the
+ // contents which will cause just the internal pointers to be swapped
+ // so that when "tmp_array" goes out of scope, it will destroy the
+ // contents.
+
+ // Save at least the compile unit DIE
+ std::vector<DWARFDebugInfoEntryMinimal> tmpArray;
+ DieArray.swap(tmpArray);
+ if (keep_compile_unit_die)
+ DieArray.push_back(tmpArray.front());
+ }
+}
+
+void
+DWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
+ bool clear_dies_if_already_not_parsed){
+ // This function is usually called if there in no .debug_aranges section
+ // in order to produce a compile unit level set of address ranges that
+ // is accurate. If the DIEs weren't parsed, then we don't want all dies for
+ // all compile units to stay loaded when they weren't needed. So we can end
+ // up parsing the DWARF and then throwing them all away to keep memory usage
+ // down.
+ const bool clear_dies = extractDIEsIfNeeded(false) > 1;
+
+ DieArray[0].buildAddressRangeTable(this, debug_aranges);
+
+ // Keep memory down by clearing DIEs if this generate function
+ // caused them to be parsed.
+ if (clear_dies)
+ clearDIEs(true);
+}
Modified: llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h?rev=139732&r1=139731&r2=139732&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h Wed Sep 14 15:52:27 2011
@@ -91,6 +91,11 @@
DieArray.reserve(getDebugInfoSize() / 14);
DieArray.push_back(die);
}
+
+ void clearDIEs(bool keep_compile_unit_die);
+
+ void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
+ bool clear_dies_if_already_not_parsed);
};
}
Modified: llvm/trunk/lib/DebugInfo/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.cpp?rev=139732&r1=139731&r2=139732&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFContext.cpp Wed Sep 14 15:52:27 2011
@@ -46,6 +46,8 @@
Aranges.reset(new DWARFDebugAranges());
Aranges->extract(arangesData);
+ if (Aranges->isEmpty()) // No aranges in file, generate them from the DIEs.
+ Aranges->generate(this);
return Aranges.get();
}
Modified: llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp?rev=139732&r1=139731&r2=139732&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp Wed Sep 14 15:52:27 2011
@@ -83,6 +83,19 @@
return false;
}
+bool DWARFDebugAranges::generate(DWARFContext *ctx) {
+ clear();
+ if (ctx) {
+ const uint32_t num_compile_units = ctx->getNumCompileUnits();
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ DWARFCompileUnit *cu = ctx->getCompileUnitAtIndex(cu_idx);
+ if (cu)
+ cu->buildAddressRangeTable(this, true);
+ }
+ }
+ return !isEmpty();
+}
+
void DWARFDebugAranges::dump(raw_ostream &OS) const {
const uint32_t num_ranges = getNumRanges();
for (uint32_t i = 0; i < num_ranges; ++i) {
Modified: llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h?rev=139732&r1=139731&r2=139732&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h Wed Sep 14 15:52:27 2011
@@ -64,6 +64,7 @@
bool allRangesAreContiguous(uint64_t& LoPC, uint64_t& HiPC) const;
bool getMaxRange(uint64_t& LoPC, uint64_t& HiPC) const;
bool extract(DataExtractor debug_aranges_data);
+ bool generate(DWARFContext *ctx);
// Use append range multiple times and then call sort
void appendRange(uint32_t cu_offset, uint64_t low_pc, uint64_t high_pc);
Modified: llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp?rev=139732&r1=139731&r2=139732&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp Wed Sep 14 15:52:27 2011
@@ -397,7 +397,8 @@
}
uint64_t
-DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(const DWARFCompileUnit* cu,
+DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
+ const DWARFCompileUnit* cu,
const uint16_t attr,
uint64_t fail_value) const {
DWARFFormValue form_value;
@@ -405,3 +406,26 @@
return form_value.getReference(cu);
return fail_value;
}
+
+void
+DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges)
+ const {
+ if (AbbrevDecl) {
+ uint16_t tag = AbbrevDecl->getTag();
+ if (tag == DW_TAG_subprogram) {
+ uint64_t hi_pc = -1ULL;
+ uint64_t lo_pc = getAttributeValueAsUnsigned(cu, DW_AT_low_pc, -1ULL);
+ if (lo_pc != -1ULL)
+ hi_pc = getAttributeValueAsUnsigned(cu, DW_AT_high_pc, -1ULL);
+ if (hi_pc != -1ULL)
+ debug_aranges->appendRange(cu->getOffset(), lo_pc, hi_pc);
+ }
+
+ const DWARFDebugInfoEntryMinimal *child = getFirstChild();
+ while (child) {
+ child->buildAddressRangeTable(cu, debug_aranges);
+ child = child->getSibling();
+ }
+ }
+}
Modified: llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h?rev=139732&r1=139731&r2=139732&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h Wed Sep 14 15:52:27 2011
@@ -15,6 +15,7 @@
namespace llvm {
+class DWARFDebugAranges;
class DWARFCompileUnit;
class DWARFContext;
class DWARFFormValue;
@@ -124,6 +125,9 @@
int64_t getAttributeValueAsSigned(const DWARFCompileUnit* cu,
const uint16_t attr,
int64_t fail_value) const;
+
+ void buildAddressRangeTable(const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges) const;
};
}
More information about the llvm-commits
mailing list