summaryrefslogtreecommitdiff
path: root/lib/DebugInfo
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/DWARFContext.cpp28
-rw-r--r--lib/DebugInfo/DWARFContext.h5
-rw-r--r--lib/DebugInfo/DWARFDebugLine.cpp52
-rw-r--r--lib/DebugInfo/DWARFDebugLine.h12
4 files changed, 39 insertions, 58 deletions
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index 184a8b595c..36c6d98ac6 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -77,15 +77,25 @@ const DWARFDebugAranges *DWARFContext::getDebugAranges() {
return Aranges.get();
}
-const DWARFDebugLine *DWARFContext::getDebugLine() {
- if (Line)
- return Line.get();
-
- DataExtractor lineData(getLineSection(), isLittleEndian(), 0);
-
- Line.reset(new DWARFDebugLine());
- Line->parse(lineData);
- return Line.get();
+const DWARFDebugLine::LineTable *
+DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
+ if (!Line)
+ Line.reset(new DWARFDebugLine());
+
+ unsigned stmtOffset =
+ cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
+ -1U);
+ if (stmtOffset == -1U)
+ return 0; // No line table for this compile unit.
+
+ // See if the line table is cached.
+ if (const DWARFDebugLine::LineTable *lt = Line->getLineTable(stmtOffset))
+ return lt;
+
+ // We have to parse it first.
+ DataExtractor lineData(getLineSection(), isLittleEndian(),
+ cu->getAddressByteSize());
+ return Line->getOrParseLineTable(lineData, stmtOffset);
}
void DWARFContext::parseCompileUnits() {
diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h
index ead169ea7e..687e5facfe 100644
--- a/lib/DebugInfo/DWARFContext.h
+++ b/lib/DebugInfo/DWARFContext.h
@@ -59,8 +59,9 @@ public:
/// Get a pointer to the parsed DebugAranges object.
const DWARFDebugAranges *getDebugAranges();
- /// Get a pointer to the parsed DWARFDebugLine object.
- const DWARFDebugLine *getDebugLine();
+ /// Get a pointer to a parsed line table corresponding to a compile unit.
+ const DWARFDebugLine::LineTable *
+ getLineTableForCompileUnit(DWARFCompileUnit *cu);
bool isLittleEndian() const { return IsLittleEndian; }
diff --git a/lib/DebugInfo/DWARFDebugLine.cpp b/lib/DebugInfo/DWARFDebugLine.cpp
index c2fb111ebc..941d8813d5 100644
--- a/lib/DebugInfo/DWARFDebugLine.cpp
+++ b/lib/DebugInfo/DWARFDebugLine.cpp
@@ -99,50 +99,12 @@ void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) {
Row::postAppend();
}
-void DWARFDebugLine::parse(const DataExtractor debug_line_data) {
- LineTableMap.clear();
- uint32_t offset = 0;
- State state;
- while (debug_line_data.isValidOffset(offset)) {
- const uint32_t debug_line_offset = offset;
-
- if (parseStatementTable(debug_line_data, &offset, state)) {
- // Make sure we don't don't loop infinitely
- if (offset <= debug_line_offset)
- break;
-
- LineTableMap[debug_line_offset] = state;
- state.reset();
- }
- else
- ++offset; // Try next byte in line table
- }
-}
-
DWARFDebugLine::DumpingState::~DumpingState() {}
void DWARFDebugLine::DumpingState::finalize(uint32_t offset) {
LineTable::dump(OS);
}
-void DWARFDebugLine::dump(const DataExtractor debug_line_data, raw_ostream &OS){
- uint32_t offset = 0;
- DumpingState state(OS);
- while (debug_line_data.isValidOffset(offset)) {
- const uint32_t debug_line_offset = offset;
-
- if (parseStatementTable(debug_line_data, &offset, state)) {
- // Make sure we don't don't loop infinitely
- if (offset <= debug_line_offset)
- break;
-
- state.reset();
- }
- else
- ++offset; // Try next byte in line table
- }
-}
-
const DWARFDebugLine::LineTable *
DWARFDebugLine::getLineTable(uint32_t offset) const {
LineTableConstIter pos = LineTableMap.find(offset);
@@ -151,6 +113,20 @@ DWARFDebugLine::getLineTable(uint32_t offset) const {
return 0;
}
+const DWARFDebugLine::LineTable *
+DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
+ uint32_t offset) {
+ LineTableIter pos = LineTableMap.find(offset);
+ if (pos == LineTableMap.end()) {
+ // Parse and cache the line table for at this offset.
+ State state;
+ if (!parseStatementTable(debug_line_data, &offset, state))
+ return 0;
+ pos->second = state;
+ }
+ return &pos->second;
+}
+
bool
DWARFDebugLine::parsePrologue(DataExtractor debug_line_data,
uint32_t *offset_ptr, Prologue *prologue) {
diff --git a/lib/DebugInfo/DWARFDebugLine.h b/lib/DebugInfo/DWARFDebugLine.h
index e50c4a9e74..bc6a70b111 100644
--- a/lib/DebugInfo/DWARFDebugLine.h
+++ b/lib/DebugInfo/DWARFDebugLine.h
@@ -147,7 +147,7 @@ public:
DoneParsingLineTable = -1
};
- State() : row(0) {}
+ State() : row(StartParsingLineTable) {}
virtual ~State();
virtual void appendRowToMatrix(uint32_t offset);
@@ -173,15 +173,9 @@ public:
static bool parseStatementTable(DataExtractor debug_line_data,
uint32_t *offset_ptr, State &state);
- /// Parse all information in the debug_line_data into an internal
- /// representation.
- void parse(DataExtractor debug_line_data);
- void parseIfNeeded(DataExtractor debug_line_data) {
- if (LineTableMap.empty())
- parse(debug_line_data);
- }
- static void dump(DataExtractor debug_line_data, raw_ostream &OS);
const LineTable *getLineTable(uint32_t offset) const;
+ const LineTable *getOrParseLineTable(DataExtractor debug_line_data,
+ uint32_t offset);
private:
typedef std::map<uint32_t, LineTable> LineTableMapTy;