mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
DWARF: Put all the pieces we have together and provide a single accessor to DIContext that provides line information when given an address.
llvm-svn: 139836
This commit is contained in:
parent
5307d9c91a
commit
a2833ff7e0
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user