mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-26 07:34:14 +00:00
[DWARF parser] Cleanup code in DWARFDebugLine.
Move several function definitions into .cpp, unify constructors and clear() methods (fixing a couple of latent bugs from copy-paste), turn static function parsePrologue() into Prologue::parse(). More work needed here to untangle weird multiple inheritance in table parsing and dumping. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207579 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8263bafd17
commit
2387e9ecb1
@ -142,7 +142,7 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
|
|||||||
DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
|
DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
|
||||||
savedAddressByteSize);
|
savedAddressByteSize);
|
||||||
DWARFDebugLine::DumpingState state(OS);
|
DWARFDebugLine::DumpingState state(OS);
|
||||||
while (DWARFDebugLine::parsePrologue(lineData, &stmtOffset, &state.Prologue))
|
while (state.Prologue.parse(lineData, &stmtOffset))
|
||||||
state.finalize();
|
state.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,19 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace dwarf;
|
using namespace dwarf;
|
||||||
|
|
||||||
|
DWARFDebugLine::Prologue::Prologue() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWARFDebugLine::Prologue::clear() {
|
||||||
|
TotalLength = Version = PrologueLength = 0;
|
||||||
|
MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
|
||||||
|
OpcodeBase = 0;
|
||||||
|
StandardOpcodeLengths.clear();
|
||||||
|
IncludeDirectories.clear();
|
||||||
|
FileNames.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
|
void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
|
||||||
OS << "Line table prologue:\n"
|
OS << "Line table prologue:\n"
|
||||||
<< format(" total_length: 0x%8.8x\n", TotalLength)
|
<< format(" total_length: 0x%8.8x\n", TotalLength)
|
||||||
@ -51,6 +64,67 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data,
|
||||||
|
uint32_t *offset_ptr) {
|
||||||
|
const uint32_t prologue_offset = *offset_ptr;
|
||||||
|
|
||||||
|
clear();
|
||||||
|
TotalLength = debug_line_data.getU32(offset_ptr);
|
||||||
|
Version = debug_line_data.getU16(offset_ptr);
|
||||||
|
if (Version < 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PrologueLength = debug_line_data.getU32(offset_ptr);
|
||||||
|
const uint32_t end_prologue_offset = PrologueLength + *offset_ptr;
|
||||||
|
MinInstLength = debug_line_data.getU8(offset_ptr);
|
||||||
|
if (Version >= 4)
|
||||||
|
MaxOpsPerInst = debug_line_data.getU8(offset_ptr);
|
||||||
|
DefaultIsStmt = debug_line_data.getU8(offset_ptr);
|
||||||
|
LineBase = debug_line_data.getU8(offset_ptr);
|
||||||
|
LineRange = debug_line_data.getU8(offset_ptr);
|
||||||
|
OpcodeBase = debug_line_data.getU8(offset_ptr);
|
||||||
|
|
||||||
|
StandardOpcodeLengths.reserve(OpcodeBase - 1);
|
||||||
|
for (uint32_t i = 1; i < OpcodeBase; ++i) {
|
||||||
|
uint8_t op_len = debug_line_data.getU8(offset_ptr);
|
||||||
|
StandardOpcodeLengths.push_back(op_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*offset_ptr < end_prologue_offset) {
|
||||||
|
const char *s = debug_line_data.getCStr(offset_ptr);
|
||||||
|
if (s && s[0])
|
||||||
|
IncludeDirectories.push_back(s);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*offset_ptr < end_prologue_offset) {
|
||||||
|
const char *name = debug_line_data.getCStr(offset_ptr);
|
||||||
|
if (name && name[0]) {
|
||||||
|
FileNameEntry fileEntry;
|
||||||
|
fileEntry.Name = name;
|
||||||
|
fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
|
||||||
|
fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
|
||||||
|
fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
|
||||||
|
FileNames.push_back(fileEntry);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*offset_ptr != end_prologue_offset) {
|
||||||
|
fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should"
|
||||||
|
" have ended at 0x%8.8x but it ended at 0x%8.8x\n",
|
||||||
|
prologue_offset, end_prologue_offset, *offset_ptr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWARFDebugLine::Row::Row(bool default_is_stmt) {
|
||||||
|
reset(default_is_stmt);
|
||||||
|
}
|
||||||
|
|
||||||
void DWARFDebugLine::Row::postAppend() {
|
void DWARFDebugLine::Row::postAppend() {
|
||||||
BasicBlock = false;
|
BasicBlock = false;
|
||||||
PrologueEnd = false;
|
PrologueEnd = false;
|
||||||
@ -82,6 +156,22 @@ void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
|
|||||||
<< '\n';
|
<< '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWARFDebugLine::Sequence::Sequence() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWARFDebugLine::Sequence::reset() {
|
||||||
|
LowPC = 0;
|
||||||
|
HighPC = 0;
|
||||||
|
FirstRowIndex = 0;
|
||||||
|
LastRowIndex = 0;
|
||||||
|
Empty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWARFDebugLine::LineTable::LineTable() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
|
void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
|
||||||
Prologue.dump(OS);
|
Prologue.dump(OS);
|
||||||
OS << '\n';
|
OS << '\n';
|
||||||
@ -96,6 +186,12 @@ void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DWARFDebugLine::LineTable::clear() {
|
||||||
|
Prologue.clear();
|
||||||
|
Rows.clear();
|
||||||
|
Sequences.clear();
|
||||||
|
}
|
||||||
|
|
||||||
DWARFDebugLine::State::~State() {}
|
DWARFDebugLine::State::~State() {}
|
||||||
|
|
||||||
void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) {
|
void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) {
|
||||||
@ -165,64 +261,6 @@ DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
|
|||||||
return &pos.first->second;
|
return &pos.first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
DWARFDebugLine::parsePrologue(DataExtractor debug_line_data,
|
|
||||||
uint32_t *offset_ptr, Prologue *prologue) {
|
|
||||||
const uint32_t prologue_offset = *offset_ptr;
|
|
||||||
|
|
||||||
prologue->clear();
|
|
||||||
prologue->TotalLength = debug_line_data.getU32(offset_ptr);
|
|
||||||
prologue->Version = debug_line_data.getU16(offset_ptr);
|
|
||||||
if (prologue->Version < 2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
prologue->PrologueLength = debug_line_data.getU32(offset_ptr);
|
|
||||||
const uint32_t end_prologue_offset = prologue->PrologueLength + *offset_ptr;
|
|
||||||
prologue->MinInstLength = debug_line_data.getU8(offset_ptr);
|
|
||||||
if (prologue->Version >= 4)
|
|
||||||
prologue->MaxOpsPerInst = debug_line_data.getU8(offset_ptr);
|
|
||||||
prologue->DefaultIsStmt = debug_line_data.getU8(offset_ptr);
|
|
||||||
prologue->LineBase = debug_line_data.getU8(offset_ptr);
|
|
||||||
prologue->LineRange = debug_line_data.getU8(offset_ptr);
|
|
||||||
prologue->OpcodeBase = debug_line_data.getU8(offset_ptr);
|
|
||||||
|
|
||||||
prologue->StandardOpcodeLengths.reserve(prologue->OpcodeBase-1);
|
|
||||||
for (uint32_t i = 1; i < prologue->OpcodeBase; ++i) {
|
|
||||||
uint8_t op_len = debug_line_data.getU8(offset_ptr);
|
|
||||||
prologue->StandardOpcodeLengths.push_back(op_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (*offset_ptr < end_prologue_offset) {
|
|
||||||
const char *s = debug_line_data.getCStr(offset_ptr);
|
|
||||||
if (s && s[0])
|
|
||||||
prologue->IncludeDirectories.push_back(s);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (*offset_ptr < end_prologue_offset) {
|
|
||||||
const char *name = debug_line_data.getCStr(offset_ptr);
|
|
||||||
if (name && name[0]) {
|
|
||||||
FileNameEntry fileEntry;
|
|
||||||
fileEntry.Name = name;
|
|
||||||
fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
|
|
||||||
fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
|
|
||||||
fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
|
|
||||||
prologue->FileNames.push_back(fileEntry);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*offset_ptr != end_prologue_offset) {
|
|
||||||
fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should"
|
|
||||||
" have ended at 0x%8.8x but it ended at 0x%8.8x\n",
|
|
||||||
prologue_offset, end_prologue_offset, *offset_ptr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
||||||
const RelocAddrMap *RMap,
|
const RelocAddrMap *RMap,
|
||||||
uint32_t *offset_ptr, State &state) {
|
uint32_t *offset_ptr, State &state) {
|
||||||
@ -230,7 +268,7 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
|
|
||||||
Prologue *prologue = &state.Prologue;
|
Prologue *prologue = &state.Prologue;
|
||||||
|
|
||||||
if (!parsePrologue(debug_line_data, offset_ptr, prologue)) {
|
if (!prologue->parse(debug_line_data, offset_ptr)) {
|
||||||
// Restore our offset and return false to indicate failure!
|
// Restore our offset and return false to indicate failure!
|
||||||
*offset_ptr = debug_line_offset;
|
*offset_ptr = debug_line_offset;
|
||||||
return false;
|
return false;
|
||||||
@ -486,8 +524,7 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
return end_offset;
|
return end_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
|
||||||
DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
|
|
||||||
uint32_t unknown_index = UINT32_MAX;
|
uint32_t unknown_index = UINT32_MAX;
|
||||||
if (Sequences.empty())
|
if (Sequences.empty())
|
||||||
return unknown_index;
|
return unknown_index;
|
||||||
@ -532,10 +569,8 @@ DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool DWARFDebugLine::LineTable::lookupAddressRange(
|
||||||
DWARFDebugLine::LineTable::lookupAddressRange(uint64_t address,
|
uint64_t address, uint64_t size, std::vector<uint32_t> &result) const {
|
||||||
uint64_t size,
|
|
||||||
std::vector<uint32_t>& result) const {
|
|
||||||
if (Sequences.empty())
|
if (Sequences.empty())
|
||||||
return false;
|
return false;
|
||||||
uint64_t end_addr = address + size;
|
uint64_t end_addr = address + size;
|
||||||
|
@ -33,10 +33,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Prologue {
|
struct Prologue {
|
||||||
Prologue()
|
Prologue();
|
||||||
: TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0),
|
|
||||||
MaxOpsPerInst(0), DefaultIsStmt(0), LineBase(0), LineRange(0),
|
|
||||||
OpcodeBase(0) {}
|
|
||||||
|
|
||||||
// The size in bytes of the statement information for this compilation unit
|
// The size in bytes of the statement information for this compilation unit
|
||||||
// (not including the total_length field itself).
|
// (not including the total_length field itself).
|
||||||
@ -77,19 +74,16 @@ public:
|
|||||||
int32_t getMaxLineIncrementForSpecialOpcode() const {
|
int32_t getMaxLineIncrementForSpecialOpcode() const {
|
||||||
return LineBase + (int8_t)LineRange - 1;
|
return LineBase + (int8_t)LineRange - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear();
|
||||||
void dump(raw_ostream &OS) const;
|
void dump(raw_ostream &OS) const;
|
||||||
void clear() {
|
bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr);
|
||||||
TotalLength = Version = PrologueLength = 0;
|
|
||||||
MinInstLength = LineBase = LineRange = OpcodeBase = 0;
|
|
||||||
StandardOpcodeLengths.clear();
|
|
||||||
IncludeDirectories.clear();
|
|
||||||
FileNames.clear();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Standard .debug_line state machine structure.
|
// Standard .debug_line state machine structure.
|
||||||
struct Row {
|
struct Row {
|
||||||
Row(bool default_is_stmt = false) { reset(default_is_stmt); }
|
explicit Row(bool default_is_stmt = false);
|
||||||
|
|
||||||
/// Called after a row is appended to the matrix.
|
/// Called after a row is appended to the matrix.
|
||||||
void postAppend();
|
void postAppend();
|
||||||
void reset(bool default_is_stmt);
|
void reset(bool default_is_stmt);
|
||||||
@ -151,14 +145,9 @@ public:
|
|||||||
unsigned LastRowIndex;
|
unsigned LastRowIndex;
|
||||||
bool Empty;
|
bool Empty;
|
||||||
|
|
||||||
Sequence() { reset(); }
|
Sequence();
|
||||||
void reset() {
|
void reset();
|
||||||
LowPC = 0;
|
|
||||||
HighPC = 0;
|
|
||||||
FirstRowIndex = 0;
|
|
||||||
LastRowIndex = 0;
|
|
||||||
Empty = true;
|
|
||||||
}
|
|
||||||
static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) {
|
static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) {
|
||||||
return LHS.LowPC < RHS.LowPC;
|
return LHS.LowPC < RHS.LowPC;
|
||||||
}
|
}
|
||||||
@ -171,23 +160,21 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct LineTable {
|
struct LineTable {
|
||||||
void appendRow(const DWARFDebugLine::Row &state) { Rows.push_back(state); }
|
LineTable();
|
||||||
void appendSequence(const DWARFDebugLine::Sequence &sequence) {
|
|
||||||
Sequences.push_back(sequence);
|
void appendRow(const DWARFDebugLine::Row &R) {
|
||||||
|
Rows.push_back(R);
|
||||||
}
|
}
|
||||||
void clear() {
|
void appendSequence(const DWARFDebugLine::Sequence &S) {
|
||||||
Prologue.clear();
|
Sequences.push_back(S);
|
||||||
Rows.clear();
|
|
||||||
Sequences.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the index of the row with file/line info for a given address,
|
// Returns the index of the row with file/line info for a given address,
|
||||||
// or -1 if there is no such row.
|
// or -1 if there is no such row.
|
||||||
uint32_t lookupAddress(uint64_t address) const;
|
uint32_t lookupAddress(uint64_t address) const;
|
||||||
|
|
||||||
bool lookupAddressRange(uint64_t address,
|
bool lookupAddressRange(uint64_t address, uint64_t size,
|
||||||
uint64_t size,
|
std::vector<uint32_t> &result) const;
|
||||||
std::vector<uint32_t>& result) const;
|
|
||||||
|
|
||||||
// Extracts filename by its index in filename table in prologue.
|
// Extracts filename by its index in filename table in prologue.
|
||||||
// Returns true on success.
|
// Returns true on success.
|
||||||
@ -196,6 +183,7 @@ public:
|
|||||||
std::string &Result) const;
|
std::string &Result) const;
|
||||||
|
|
||||||
void dump(raw_ostream &OS) const;
|
void dump(raw_ostream &OS) const;
|
||||||
|
void clear();
|
||||||
|
|
||||||
struct Prologue Prologue;
|
struct Prologue Prologue;
|
||||||
typedef std::vector<Row> RowVector;
|
typedef std::vector<Row> RowVector;
|
||||||
@ -236,8 +224,6 @@ public:
|
|||||||
raw_ostream &OS;
|
raw_ostream &OS;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool parsePrologue(DataExtractor debug_line_data, uint32_t *offset_ptr,
|
|
||||||
Prologue *prologue);
|
|
||||||
/// Parse a single line table (prologue and all rows).
|
/// Parse a single line table (prologue and all rows).
|
||||||
static bool parseStatementTable(DataExtractor debug_line_data,
|
static bool parseStatementTable(DataExtractor debug_line_data,
|
||||||
const RelocAddrMap *RMap,
|
const RelocAddrMap *RMap,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user