mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
[DWARF parser] Cleanup code in DWARFDebugLine.
Streamline parsing and dumping line tables: Prefer composition to multiple inheritance in DWARFDebugLine::ParsingState. Get rid of the weird concept of "DumpingState" structure. was: DWARFDebugLine::DumpingState state(OS); DWARFDebugLine::parseStatementTable(..., state); now: DWARFDebugLine::LineTable LineTable; LineTable.parse(...); LineTable.dump(OS); No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207599 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -130,8 +130,9 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
|
|||||||
if (stmtOffset != -1U) {
|
if (stmtOffset != -1U) {
|
||||||
DataExtractor lineData(getLineSection().Data, isLittleEndian(),
|
DataExtractor lineData(getLineSection().Data, isLittleEndian(),
|
||||||
savedAddressByteSize);
|
savedAddressByteSize);
|
||||||
DWARFDebugLine::DumpingState state(OS);
|
DWARFDebugLine::LineTable LineTable;
|
||||||
DWARFDebugLine::parseStatementTable(lineData, &getLineSection().Relocs, &stmtOffset, state);
|
LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
|
||||||
|
LineTable.dump(OS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,9 +142,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
|
|||||||
unsigned stmtOffset = 0;
|
unsigned stmtOffset = 0;
|
||||||
DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
|
DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
|
||||||
savedAddressByteSize);
|
savedAddressByteSize);
|
||||||
DWARFDebugLine::DumpingState state(OS);
|
DWARFDebugLine::LineTable LineTable;
|
||||||
while (state.Prologue.parse(lineData, &stmtOffset))
|
while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
|
||||||
state.finalize();
|
LineTable.dump(OS);
|
||||||
|
LineTable.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DumpType == DIDT_All || DumpType == DIDT_Str) {
|
if (DumpType == DIDT_All || DumpType == DIDT_Str) {
|
||||||
|
@@ -192,50 +192,34 @@ void DWARFDebugLine::LineTable::clear() {
|
|||||||
Sequences.clear();
|
Sequences.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
DWARFDebugLine::State::~State() {}
|
DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT)
|
||||||
|
: LineTable(LT), RowNumber(0) {
|
||||||
|
resetRowAndSequence();
|
||||||
|
}
|
||||||
|
|
||||||
void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) {
|
void DWARFDebugLine::ParsingState::resetRowAndSequence() {
|
||||||
if (Sequence::Empty) {
|
Row.reset(LineTable->Prologue.DefaultIsStmt);
|
||||||
|
Sequence.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t offset) {
|
||||||
|
if (Sequence.Empty) {
|
||||||
// Record the beginning of instruction sequence.
|
// Record the beginning of instruction sequence.
|
||||||
Sequence::Empty = false;
|
Sequence.Empty = false;
|
||||||
Sequence::LowPC = Address;
|
Sequence.LowPC = Row.Address;
|
||||||
Sequence::FirstRowIndex = row;
|
Sequence.FirstRowIndex = RowNumber;
|
||||||
}
|
}
|
||||||
++row; // Increase the row number.
|
++RowNumber;
|
||||||
LineTable::appendRow(*this);
|
LineTable->appendRow(Row);
|
||||||
if (EndSequence) {
|
if (Row.EndSequence) {
|
||||||
// Record the end of instruction sequence.
|
// Record the end of instruction sequence.
|
||||||
Sequence::HighPC = Address;
|
Sequence.HighPC = Row.Address;
|
||||||
Sequence::LastRowIndex = row;
|
Sequence.LastRowIndex = RowNumber;
|
||||||
if (Sequence::isValid())
|
if (Sequence.isValid())
|
||||||
LineTable::appendSequence(*this);
|
LineTable->appendSequence(Sequence);
|
||||||
Sequence::reset();
|
Sequence.reset();
|
||||||
}
|
}
|
||||||
Row::postAppend();
|
Row.postAppend();
|
||||||
}
|
|
||||||
|
|
||||||
void DWARFDebugLine::State::finalize() {
|
|
||||||
row = DoneParsingLineTable;
|
|
||||||
if (!Sequence::Empty) {
|
|
||||||
fprintf(stderr, "warning: last sequence in debug line table is not"
|
|
||||||
"terminated!\n");
|
|
||||||
}
|
|
||||||
// Sort all sequences so that address lookup will work faster.
|
|
||||||
if (!Sequences.empty()) {
|
|
||||||
std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
|
|
||||||
// Note: actually, instruction address ranges of sequences should not
|
|
||||||
// overlap (in shared objects and executables). If they do, the address
|
|
||||||
// lookup would still work, though, but result would be ambiguous.
|
|
||||||
// We don't report warning in this case. For example,
|
|
||||||
// sometimes .so compiled from multiple object files contains a few
|
|
||||||
// rudimentary sequences for address ranges [0x0, 0xsomething).
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWARFDebugLine::DumpingState::~DumpingState() {}
|
|
||||||
|
|
||||||
void DWARFDebugLine::DumpingState::finalize() {
|
|
||||||
LineTable::dump(OS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DWARFDebugLine::LineTable *
|
const DWARFDebugLine::LineTable *
|
||||||
@@ -251,33 +235,31 @@ DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
|
|||||||
uint32_t offset) {
|
uint32_t offset) {
|
||||||
std::pair<LineTableIter, bool> pos =
|
std::pair<LineTableIter, bool> pos =
|
||||||
LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable()));
|
LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable()));
|
||||||
|
LineTable *LT = &pos.first->second;
|
||||||
if (pos.second) {
|
if (pos.second) {
|
||||||
// Parse and cache the line table for at this offset.
|
if (!LT->parse(debug_line_data, RelocMap, &offset))
|
||||||
State state;
|
|
||||||
if (!parseStatementTable(debug_line_data, RelocMap, &offset, state))
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
pos.first->second = state;
|
|
||||||
}
|
}
|
||||||
return &pos.first->second;
|
return LT;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
|
||||||
const RelocAddrMap *RMap,
|
const RelocAddrMap *RMap,
|
||||||
uint32_t *offset_ptr, State &state) {
|
uint32_t *offset_ptr) {
|
||||||
const uint32_t debug_line_offset = *offset_ptr;
|
const uint32_t debug_line_offset = *offset_ptr;
|
||||||
|
|
||||||
Prologue *prologue = &state.Prologue;
|
clear();
|
||||||
|
|
||||||
if (!prologue->parse(debug_line_data, offset_ptr)) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t end_offset = debug_line_offset + prologue->TotalLength +
|
const uint32_t end_offset = debug_line_offset + Prologue.TotalLength +
|
||||||
sizeof(prologue->TotalLength);
|
sizeof(Prologue.TotalLength);
|
||||||
|
|
||||||
state.reset();
|
ParsingState State(this);
|
||||||
|
|
||||||
while (*offset_ptr < end_offset) {
|
while (*offset_ptr < end_offset) {
|
||||||
uint8_t opcode = debug_line_data.getU8(offset_ptr);
|
uint8_t opcode = debug_line_data.getU8(offset_ptr);
|
||||||
@@ -299,9 +281,9 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
// with a DW_LNE_end_sequence instruction which creates a row whose
|
// with a DW_LNE_end_sequence instruction which creates a row whose
|
||||||
// address is that of the byte after the last target machine instruction
|
// address is that of the byte after the last target machine instruction
|
||||||
// of the sequence.
|
// of the sequence.
|
||||||
state.EndSequence = true;
|
State.Row.EndSequence = true;
|
||||||
state.appendRowToMatrix(*offset_ptr);
|
State.appendRowToMatrix(*offset_ptr);
|
||||||
state.reset();
|
State.resetRowAndSequence();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNE_set_address:
|
case DW_LNE_set_address:
|
||||||
@@ -316,9 +298,10 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr);
|
RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr);
|
||||||
if (AI != RMap->end()) {
|
if (AI != RMap->end()) {
|
||||||
const std::pair<uint8_t, int64_t> &R = AI->second;
|
const std::pair<uint8_t, int64_t> &R = AI->second;
|
||||||
state.Address = debug_line_data.getAddress(offset_ptr) + R.second;
|
State.Row.Address =
|
||||||
|
debug_line_data.getAddress(offset_ptr) + R.second;
|
||||||
} else
|
} else
|
||||||
state.Address = debug_line_data.getAddress(offset_ptr);
|
State.Row.Address = debug_line_data.getAddress(offset_ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -349,12 +332,12 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
|
fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
|
||||||
fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
|
fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
|
||||||
fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
|
fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
|
||||||
prologue->FileNames.push_back(fileEntry);
|
Prologue.FileNames.push_back(fileEntry);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNE_set_discriminator:
|
case DW_LNE_set_discriminator:
|
||||||
state.Discriminator = debug_line_data.getULEB128(offset_ptr);
|
State.Row.Discriminator = debug_line_data.getULEB128(offset_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -363,52 +346,52 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
(*offset_ptr) += arg_size;
|
(*offset_ptr) += arg_size;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (opcode < prologue->OpcodeBase) {
|
} else if (opcode < Prologue.OpcodeBase) {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
// Standard Opcodes
|
// Standard Opcodes
|
||||||
case DW_LNS_copy:
|
case DW_LNS_copy:
|
||||||
// Takes no arguments. Append a row to the matrix using the
|
// Takes no arguments. Append a row to the matrix using the
|
||||||
// current values of the state-machine registers. Then set
|
// current values of the state-machine registers. Then set
|
||||||
// the basic_block register to false.
|
// the basic_block register to false.
|
||||||
state.appendRowToMatrix(*offset_ptr);
|
State.appendRowToMatrix(*offset_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_advance_pc:
|
case DW_LNS_advance_pc:
|
||||||
// Takes a single unsigned LEB128 operand, multiplies it by the
|
// Takes a single unsigned LEB128 operand, multiplies it by the
|
||||||
// min_inst_length field of the prologue, and adds the
|
// min_inst_length field of the prologue, and adds the
|
||||||
// result to the address register of the state machine.
|
// result to the address register of the state machine.
|
||||||
state.Address += debug_line_data.getULEB128(offset_ptr) *
|
State.Row.Address +=
|
||||||
prologue->MinInstLength;
|
debug_line_data.getULEB128(offset_ptr) * Prologue.MinInstLength;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_advance_line:
|
case DW_LNS_advance_line:
|
||||||
// Takes a single signed LEB128 operand and adds that value to
|
// Takes a single signed LEB128 operand and adds that value to
|
||||||
// the line register of the state machine.
|
// the line register of the state machine.
|
||||||
state.Line += debug_line_data.getSLEB128(offset_ptr);
|
State.Row.Line += debug_line_data.getSLEB128(offset_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_set_file:
|
case DW_LNS_set_file:
|
||||||
// Takes a single unsigned LEB128 operand and stores it in the file
|
// Takes a single unsigned LEB128 operand and stores it in the file
|
||||||
// register of the state machine.
|
// register of the state machine.
|
||||||
state.File = debug_line_data.getULEB128(offset_ptr);
|
State.Row.File = debug_line_data.getULEB128(offset_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_set_column:
|
case DW_LNS_set_column:
|
||||||
// Takes a single unsigned LEB128 operand and stores it in the
|
// Takes a single unsigned LEB128 operand and stores it in the
|
||||||
// column register of the state machine.
|
// column register of the state machine.
|
||||||
state.Column = debug_line_data.getULEB128(offset_ptr);
|
State.Row.Column = debug_line_data.getULEB128(offset_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_negate_stmt:
|
case DW_LNS_negate_stmt:
|
||||||
// Takes no arguments. Set the is_stmt register of the state
|
// Takes no arguments. Set the is_stmt register of the state
|
||||||
// machine to the logical negation of its current value.
|
// machine to the logical negation of its current value.
|
||||||
state.IsStmt = !state.IsStmt;
|
State.Row.IsStmt = !State.Row.IsStmt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_set_basic_block:
|
case DW_LNS_set_basic_block:
|
||||||
// Takes no arguments. Set the basic_block register of the
|
// Takes no arguments. Set the basic_block register of the
|
||||||
// state machine to true
|
// state machine to true
|
||||||
state.BasicBlock = true;
|
State.Row.BasicBlock = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_const_add_pc:
|
case DW_LNS_const_add_pc:
|
||||||
@@ -424,10 +407,10 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
// than twice that range will it need to use both DW_LNS_advance_pc
|
// than twice that range will it need to use both DW_LNS_advance_pc
|
||||||
// and a special opcode, requiring three or more bytes.
|
// and a special opcode, requiring three or more bytes.
|
||||||
{
|
{
|
||||||
uint8_t adjust_opcode = 255 - prologue->OpcodeBase;
|
uint8_t adjust_opcode = 255 - Prologue.OpcodeBase;
|
||||||
uint64_t addr_offset = (adjust_opcode / prologue->LineRange) *
|
uint64_t addr_offset =
|
||||||
prologue->MinInstLength;
|
(adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
|
||||||
state.Address += addr_offset;
|
State.Row.Address += addr_offset;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -441,25 +424,25 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
// judge when the computation of a special opcode overflows and
|
// judge when the computation of a special opcode overflows and
|
||||||
// requires the use of DW_LNS_advance_pc. Such assemblers, however,
|
// requires the use of DW_LNS_advance_pc. Such assemblers, however,
|
||||||
// can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
|
// can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
|
||||||
state.Address += debug_line_data.getU16(offset_ptr);
|
State.Row.Address += debug_line_data.getU16(offset_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_set_prologue_end:
|
case DW_LNS_set_prologue_end:
|
||||||
// Takes no arguments. Set the prologue_end register of the
|
// Takes no arguments. Set the prologue_end register of the
|
||||||
// state machine to true
|
// state machine to true
|
||||||
state.PrologueEnd = true;
|
State.Row.PrologueEnd = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_set_epilogue_begin:
|
case DW_LNS_set_epilogue_begin:
|
||||||
// Takes no arguments. Set the basic_block register of the
|
// Takes no arguments. Set the basic_block register of the
|
||||||
// state machine to true
|
// state machine to true
|
||||||
state.EpilogueBegin = true;
|
State.Row.EpilogueBegin = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_LNS_set_isa:
|
case DW_LNS_set_isa:
|
||||||
// Takes a single unsigned LEB128 operand and stores it in the
|
// Takes a single unsigned LEB128 operand and stores it in the
|
||||||
// column register of the state machine.
|
// column register of the state machine.
|
||||||
state.Isa = debug_line_data.getULEB128(offset_ptr);
|
State.Row.Isa = debug_line_data.getULEB128(offset_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -467,9 +450,9 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
// of such opcodes because they are specified in the prologue
|
// of such opcodes because they are specified in the prologue
|
||||||
// as a multiple of LEB128 operands for each opcode.
|
// as a multiple of LEB128 operands for each opcode.
|
||||||
{
|
{
|
||||||
assert(opcode - 1U < prologue->StandardOpcodeLengths.size());
|
assert(opcode - 1U < Prologue.StandardOpcodeLengths.size());
|
||||||
uint8_t opcode_length = prologue->StandardOpcodeLengths[opcode - 1];
|
uint8_t opcode_length = Prologue.StandardOpcodeLengths[opcode - 1];
|
||||||
for (uint8_t i=0; i<opcode_length; ++i)
|
for (uint8_t i = 0; i < opcode_length; ++i)
|
||||||
debug_line_data.getULEB128(offset_ptr);
|
debug_line_data.getULEB128(offset_ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -508,18 +491,32 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
|||||||
//
|
//
|
||||||
// line increment = line_base + (adjusted opcode % line_range)
|
// line increment = line_base + (adjusted opcode % line_range)
|
||||||
|
|
||||||
uint8_t adjust_opcode = opcode - prologue->OpcodeBase;
|
uint8_t adjust_opcode = opcode - Prologue.OpcodeBase;
|
||||||
uint64_t addr_offset = (adjust_opcode / prologue->LineRange) *
|
uint64_t addr_offset =
|
||||||
prologue->MinInstLength;
|
(adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
|
||||||
int32_t line_offset = prologue->LineBase +
|
int32_t line_offset =
|
||||||
(adjust_opcode % prologue->LineRange);
|
Prologue.LineBase + (adjust_opcode % Prologue.LineRange);
|
||||||
state.Line += line_offset;
|
State.Row.Line += line_offset;
|
||||||
state.Address += addr_offset;
|
State.Row.Address += addr_offset;
|
||||||
state.appendRowToMatrix(*offset_ptr);
|
State.appendRowToMatrix(*offset_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.finalize();
|
if (!State.Sequence.Empty) {
|
||||||
|
fprintf(stderr, "warning: last sequence in debug line table is not"
|
||||||
|
"terminated!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort all sequences so that address lookup will work faster.
|
||||||
|
if (!Sequences.empty()) {
|
||||||
|
std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
|
||||||
|
// Note: actually, instruction address ranges of sequences should not
|
||||||
|
// overlap (in shared objects and executables). If they do, the address
|
||||||
|
// lookup would still work, though, but result would be ambiguous.
|
||||||
|
// We don't report warning in this case. For example,
|
||||||
|
// sometimes .so compiled from multiple object files contains a few
|
||||||
|
// rudimentary sequences for address ranges [0x0, 0xsomething).
|
||||||
|
}
|
||||||
|
|
||||||
return end_offset;
|
return end_offset;
|
||||||
}
|
}
|
||||||
|
@@ -185,6 +185,10 @@ public:
|
|||||||
void dump(raw_ostream &OS) const;
|
void dump(raw_ostream &OS) const;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
/// Parse prologue and all rows.
|
||||||
|
bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap,
|
||||||
|
uint32_t *offset_ptr);
|
||||||
|
|
||||||
struct Prologue Prologue;
|
struct Prologue Prologue;
|
||||||
typedef std::vector<Row> RowVector;
|
typedef std::vector<Row> RowVector;
|
||||||
typedef RowVector::const_iterator RowIter;
|
typedef RowVector::const_iterator RowIter;
|
||||||
@@ -194,46 +198,26 @@ public:
|
|||||||
SequenceVector Sequences;
|
SequenceVector Sequences;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct State : public Row, public Sequence, public LineTable {
|
|
||||||
// Special row codes.
|
|
||||||
enum {
|
|
||||||
StartParsingLineTable = 0,
|
|
||||||
DoneParsingLineTable = -1
|
|
||||||
};
|
|
||||||
|
|
||||||
State() : row(StartParsingLineTable) {}
|
|
||||||
virtual ~State();
|
|
||||||
|
|
||||||
virtual void appendRowToMatrix(uint32_t offset);
|
|
||||||
virtual void finalize();
|
|
||||||
virtual void reset() {
|
|
||||||
Row::reset(Prologue.DefaultIsStmt);
|
|
||||||
Sequence::reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The row number that starts at zero for the prologue, and increases for
|
|
||||||
// each row added to the matrix.
|
|
||||||
unsigned row;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DumpingState : public State {
|
|
||||||
DumpingState(raw_ostream &OS) : OS(OS) {}
|
|
||||||
virtual ~DumpingState();
|
|
||||||
void finalize() override;
|
|
||||||
private:
|
|
||||||
raw_ostream &OS;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Parse a single line table (prologue and all rows).
|
|
||||||
static bool parseStatementTable(DataExtractor debug_line_data,
|
|
||||||
const RelocAddrMap *RMap,
|
|
||||||
uint32_t *offset_ptr, State &state);
|
|
||||||
|
|
||||||
const LineTable *getLineTable(uint32_t offset) const;
|
const LineTable *getLineTable(uint32_t offset) const;
|
||||||
const LineTable *getOrParseLineTable(DataExtractor debug_line_data,
|
const LineTable *getOrParseLineTable(DataExtractor debug_line_data,
|
||||||
uint32_t offset);
|
uint32_t offset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct ParsingState {
|
||||||
|
ParsingState(struct LineTable *LT);
|
||||||
|
|
||||||
|
void resetRowAndSequence();
|
||||||
|
void appendRowToMatrix(uint32_t offset);
|
||||||
|
|
||||||
|
// Line table we're currently parsing.
|
||||||
|
struct LineTable *LineTable;
|
||||||
|
// The row number that starts at zero for the prologue, and increases for
|
||||||
|
// each row added to the matrix.
|
||||||
|
unsigned RowNumber;
|
||||||
|
struct Row Row;
|
||||||
|
struct Sequence Sequence;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::map<uint32_t, LineTable> LineTableMapTy;
|
typedef std::map<uint32_t, LineTable> LineTableMapTy;
|
||||||
typedef LineTableMapTy::iterator LineTableIter;
|
typedef LineTableMapTy::iterator LineTableIter;
|
||||||
typedef LineTableMapTy::const_iterator LineTableConstIter;
|
typedef LineTableMapTy::const_iterator LineTableConstIter;
|
||||||
|
Reference in New Issue
Block a user