mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
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:
parent
c26ed9b47f
commit
101b1c5ff1
@ -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.
|
// debug information data.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -21,6 +21,20 @@ namespace llvm {
|
|||||||
|
|
||||||
class raw_ostream;
|
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 {
|
class DIContext {
|
||||||
public:
|
public:
|
||||||
virtual ~DIContext();
|
virtual ~DIContext();
|
||||||
@ -34,6 +48,8 @@ public:
|
|||||||
StringRef stringSection = StringRef());
|
StringRef stringSection = StringRef());
|
||||||
|
|
||||||
virtual void dump(raw_ostream &OS) = 0;
|
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/Dwarf.h"
|
||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include <algorithm>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace dwarf;
|
using namespace dwarf;
|
||||||
|
|
||||||
@ -112,3 +113,51 @@ void DWARFContext::parseCompileUnits() {
|
|||||||
offset = CUs.back().getNextCompileUnitOffset();
|
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 &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.
|
/// Get a pointer to the parsed DebugAbbrev object.
|
||||||
const DWARFDebugAbbrev *getDebugAbbrev();
|
const DWARFDebugAbbrev *getDebugAbbrev();
|
||||||
|
|
||||||
@ -63,6 +66,8 @@ public:
|
|||||||
const DWARFDebugLine::LineTable *
|
const DWARFDebugLine::LineTable *
|
||||||
getLineTableForCompileUnit(DWARFCompileUnit *cu);
|
getLineTableForCompileUnit(DWARFCompileUnit *cu);
|
||||||
|
|
||||||
|
virtual DILineInfo getLineInfoForAddress(uint64_t address);
|
||||||
|
|
||||||
bool isLittleEndian() const { return IsLittleEndian; }
|
bool isLittleEndian() const { return IsLittleEndian; }
|
||||||
|
|
||||||
virtual StringRef getInfoSection() = 0;
|
virtual StringRef getInfoSection() = 0;
|
||||||
|
@ -122,7 +122,9 @@ DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
|
|||||||
State state;
|
State state;
|
||||||
if (!parseStatementTable(debug_line_data, &offset, state))
|
if (!parseStatementTable(debug_line_data, &offset, state))
|
||||||
return 0;
|
return 0;
|
||||||
pos->second = state;
|
// FIXME: double lookup.
|
||||||
|
LineTableMap[offset] = state;
|
||||||
|
return &LineTableMap[offset];
|
||||||
}
|
}
|
||||||
return &pos->second;
|
return &pos->second;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user