1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01: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.

llvm-svn: 207579
This commit is contained in:
Alexey Samsonov 2014-04-29 21:28:13 +00:00
parent b4468db535
commit 7815beb44c
3 changed files with 119 additions and 98 deletions

View File

@ -142,7 +142,7 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
savedAddressByteSize);
DWARFDebugLine::DumpingState state(OS);
while (DWARFDebugLine::parsePrologue(lineData, &stmtOffset, &state.Prologue))
while (state.Prologue.parse(lineData, &stmtOffset))
state.finalize();
}

View File

@ -16,6 +16,19 @@
using namespace llvm;
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 {
OS << "Line table prologue:\n"
<< 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() {
BasicBlock = false;
PrologueEnd = false;
@ -82,6 +156,22 @@ void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
<< '\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 {
Prologue.dump(OS);
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() {}
void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) {
@ -165,64 +261,6 @@ DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
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,
const RelocAddrMap *RMap,
uint32_t *offset_ptr, State &state) {
@ -230,7 +268,7 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
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!
*offset_ptr = debug_line_offset;
return false;
@ -486,8 +524,7 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
return end_offset;
}
uint32_t
DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
uint32_t unknown_index = UINT32_MAX;
if (Sequences.empty())
return unknown_index;
@ -532,10 +569,8 @@ DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
return index;
}
bool
DWARFDebugLine::LineTable::lookupAddressRange(uint64_t address,
uint64_t size,
std::vector<uint32_t>& result) const {
bool DWARFDebugLine::LineTable::lookupAddressRange(
uint64_t address, uint64_t size, std::vector<uint32_t> &result) const {
if (Sequences.empty())
return false;
uint64_t end_addr = address + size;

View File

@ -33,10 +33,7 @@ public:
};
struct Prologue {
Prologue()
: TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0),
MaxOpsPerInst(0), DefaultIsStmt(0), LineBase(0), LineRange(0),
OpcodeBase(0) {}
Prologue();
// The size in bytes of the statement information for this compilation unit
// (not including the total_length field itself).
@ -77,19 +74,16 @@ public:
int32_t getMaxLineIncrementForSpecialOpcode() const {
return LineBase + (int8_t)LineRange - 1;
}
void clear();
void dump(raw_ostream &OS) const;
void clear() {
TotalLength = Version = PrologueLength = 0;
MinInstLength = LineBase = LineRange = OpcodeBase = 0;
StandardOpcodeLengths.clear();
IncludeDirectories.clear();
FileNames.clear();
}
bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr);
};
// Standard .debug_line state machine structure.
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.
void postAppend();
void reset(bool default_is_stmt);
@ -151,14 +145,9 @@ public:
unsigned LastRowIndex;
bool Empty;
Sequence() { reset(); }
void reset() {
LowPC = 0;
HighPC = 0;
FirstRowIndex = 0;
LastRowIndex = 0;
Empty = true;
}
Sequence();
void reset();
static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) {
return LHS.LowPC < RHS.LowPC;
}
@ -171,23 +160,21 @@ public:
};
struct LineTable {
void appendRow(const DWARFDebugLine::Row &state) { Rows.push_back(state); }
void appendSequence(const DWARFDebugLine::Sequence &sequence) {
Sequences.push_back(sequence);
LineTable();
void appendRow(const DWARFDebugLine::Row &R) {
Rows.push_back(R);
}
void clear() {
Prologue.clear();
Rows.clear();
Sequences.clear();
void appendSequence(const DWARFDebugLine::Sequence &S) {
Sequences.push_back(S);
}
// Returns the index of the row with file/line info for a given address,
// or -1 if there is no such row.
uint32_t lookupAddress(uint64_t address) const;
bool lookupAddressRange(uint64_t address,
uint64_t size,
std::vector<uint32_t>& result) const;
bool lookupAddressRange(uint64_t address, uint64_t size,
std::vector<uint32_t> &result) const;
// Extracts filename by its index in filename table in prologue.
// Returns true on success.
@ -196,6 +183,7 @@ public:
std::string &Result) const;
void dump(raw_ostream &OS) const;
void clear();
struct Prologue Prologue;
typedef std::vector<Row> RowVector;
@ -236,8 +224,6 @@ public:
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).
static bool parseStatementTable(DataExtractor debug_line_data,
const RelocAddrMap *RMap,