DWARF: Put all the pieces we have together and provide a single accessor to DIContext that provides line information when given an address.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139836 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2011-09-15 20:43:22 +00:00
parent c26ed9b47f
commit 101b1c5ff1
4 changed files with 74 additions and 2 deletions

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines DIContext, and abstract data structure that holds
// This file defines DIContext, an abstract data structure that holds
// debug information data.
//
//===----------------------------------------------------------------------===//
@ -21,6 +21,20 @@ namespace llvm {
class raw_ostream;
/// DILineInfo - a format-neutral container for source line information.
class DILineInfo {
const char *FileName;
uint32_t Line;
uint32_t Column;
public:
DILineInfo(const char *fileName, uint32_t line, uint32_t column)
: FileName(fileName), Line(line), Column(column) {}
const char *getFileName() const { return FileName; }
uint32_t getLine() const { return Line; }
uint32_t getColumn() const { return Column; }
};
class DIContext {
public:
virtual ~DIContext();
@ -34,6 +48,8 @@ public:
StringRef stringSection = StringRef());
virtual void dump(raw_ostream &OS) = 0;
virtual DILineInfo getLineInfoForAddress(uint64_t address) = 0;
};
}

View File

@ -11,6 +11,7 @@
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
using namespace dwarf;
@ -112,3 +113,51 @@ void DWARFContext::parseCompileUnits() {
offset = CUs.back().getNextCompileUnitOffset();
}
}
namespace {
struct OffsetComparator {
bool operator()(const DWARFCompileUnit &LHS,
const DWARFCompileUnit &RHS) const {
return LHS.getOffset() < RHS.getOffset();
}
bool operator()(const DWARFCompileUnit &LHS, uint32_t RHS) const {
return LHS.getOffset() < RHS;
}
bool operator()(uint32_t LHS, const DWARFCompileUnit &RHS) const {
return LHS < RHS.getOffset();
}
};
}
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t offset) {
if (CUs.empty())
parseCompileUnits();
DWARFCompileUnit *i = std::lower_bound(CUs.begin(), CUs.end(), offset,
OffsetComparator());
if (i != CUs.end())
return &*i;
return 0;
}
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address) {
// First, get the index for the arange.
uint32_t arangeIndex = getDebugAranges()->findAddress(address);
// From there, get the offset of the compile unit.
uint32_t cuOffset = getDebugAranges()->offsetAtIndex(arangeIndex);
// Retrieve the compile unit.
DWARFCompileUnit *cu = getCompileUnitForOffset(cuOffset);
// Get the line table for this compile unit.
const DWARFDebugLine::LineTable *lineTable = getLineTableForCompileUnit(cu);
// Get the index of the row we're looking for in the line table.
uint64_t hiPC =
cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_high_pc,
-1ULL);
uint32_t rowIndex = lineTable->lookupAddress(address, hiPC);
// From here, contruct the DILineInfo.
const DWARFDebugLine::Row &row = lineTable->Rows[rowIndex];
const std::string &fileName = lineTable->Prologue.FileNames[row.File-1].Name;
return DILineInfo(fileName.c_str(), row.Line, row.Column);
}

View File

@ -53,6 +53,9 @@ public:
return &CUs[index];
}
/// Return the compile unit that includes an offset (relative to .debug_info).
DWARFCompileUnit *getCompileUnitForOffset(uint32_t offset);
/// Get a pointer to the parsed DebugAbbrev object.
const DWARFDebugAbbrev *getDebugAbbrev();
@ -63,6 +66,8 @@ public:
const DWARFDebugLine::LineTable *
getLineTableForCompileUnit(DWARFCompileUnit *cu);
virtual DILineInfo getLineInfoForAddress(uint64_t address);
bool isLittleEndian() const { return IsLittleEndian; }
virtual StringRef getInfoSection() = 0;

View File

@ -122,7 +122,9 @@ DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
State state;
if (!parseStatementTable(debug_line_data, &offset, state))
return 0;
pos->second = state;
// FIXME: double lookup.
LineTableMap[offset] = state;
return &LineTableMap[offset];
}
return &pos->second;
}