1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

Stylistic makeover of DWARFDebugLine before working on it. NFC

Rename parameters and locals to CamelCase, doxygenize the header, and
run clang-format on the whole thing.

llvm-svn: 301883
This commit is contained in:
Paul Robinson 2017-05-01 23:27:55 +00:00
parent 6a54e5a010
commit d2e03bb3b5
2 changed files with 264 additions and 274 deletions

View File

@ -24,7 +24,8 @@ class raw_ostream;
class DWARFDebugLine {
public:
DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {}
DWARFDebugLine(const RelocAddrMap *LineInfoRelocMap)
: RelocMap(LineInfoRelocMap) {}
struct FileNameEntry {
FileNameEntry() = default;
@ -38,50 +39,46 @@ public:
struct Prologue {
Prologue();
// The size in bytes of the statement information for this compilation unit
// (not including the total_length field itself).
/// The size in bytes of the statement information for this compilation unit
/// (not including the total_length field itself).
uint64_t TotalLength;
// Version identifier for the statement information format.
/// Version identifier for the statement information format.
uint16_t Version;
// The number of bytes following the prologue_length field to the beginning
// of the first byte of the statement program itself.
/// The number of bytes following the prologue_length field to the beginning
/// of the first byte of the statement program itself.
uint64_t PrologueLength;
// The size in bytes of the smallest target machine instruction. Statement
// program opcodes that alter the address register first multiply their
// operands by this value.
/// The size in bytes of the smallest target machine instruction. Statement
/// program opcodes that alter the address register first multiply their
/// operands by this value.
uint8_t MinInstLength;
// The maximum number of individual operations that may be encoded in an
// instruction.
/// The maximum number of individual operations that may be encoded in an
/// instruction.
uint8_t MaxOpsPerInst;
// The initial value of theis_stmtregister.
/// The initial value of theis_stmtregister.
uint8_t DefaultIsStmt;
// This parameter affects the meaning of the special opcodes. See below.
/// This parameter affects the meaning of the special opcodes. See below.
int8_t LineBase;
// This parameter affects the meaning of the special opcodes. See below.
/// This parameter affects the meaning of the special opcodes. See below.
uint8_t LineRange;
// The number assigned to the first special opcode.
/// The number assigned to the first special opcode.
uint8_t OpcodeBase;
std::vector<uint8_t> StandardOpcodeLengths;
std::vector<const char*> IncludeDirectories;
std::vector<const char *> IncludeDirectories;
std::vector<FileNameEntry> FileNames;
bool IsDWARF64;
uint32_t sizeofTotalLength() const {
return IsDWARF64 ? 12 : 4;
}
uint32_t sizeofTotalLength() const { return IsDWARF64 ? 12 : 4; }
uint32_t sizeofPrologueLength() const {
return IsDWARF64 ? 8 : 4;
}
uint32_t sizeofPrologueLength() const { return IsDWARF64 ? 8 : 4; }
// Length of the prologue in bytes.
/// Length of the prologue in bytes.
uint32_t getLength() const {
return PrologueLength + sizeofTotalLength() + sizeof(Version) +
sizeofPrologueLength();
}
// Length of the line table data in bytes (not including the prologue).
/// Length of the line table data in bytes (not including the prologue).
uint32_t getStatementTableLength() const {
return TotalLength + sizeofTotalLength() - getLength();
}
@ -92,70 +89,70 @@ public:
void clear();
void dump(raw_ostream &OS) const;
bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr);
bool parse(DataExtractor DebugLineData, uint32_t *OffsetPtr);
};
// Standard .debug_line state machine structure.
/// Standard .debug_line state machine structure.
struct Row {
explicit Row(bool default_is_stmt = false);
explicit Row(bool DefaultIsStmt = false);
/// Called after a row is appended to the matrix.
void postAppend();
void reset(bool default_is_stmt);
void reset(bool DefaultIsStmt);
void dump(raw_ostream &OS) const;
static bool orderByAddress(const Row& LHS, const Row& RHS) {
static bool orderByAddress(const Row &LHS, const Row &RHS) {
return LHS.Address < RHS.Address;
}
// The program-counter value corresponding to a machine instruction
// generated by the compiler.
/// The program-counter value corresponding to a machine instruction
/// generated by the compiler.
uint64_t Address;
// An unsigned integer indicating a source line number. Lines are numbered
// beginning at 1. The compiler may emit the value 0 in cases where an
// instruction cannot be attributed to any source line.
/// An unsigned integer indicating a source line number. Lines are numbered
/// beginning at 1. The compiler may emit the value 0 in cases where an
/// instruction cannot be attributed to any source line.
uint32_t Line;
// An unsigned integer indicating a column number within a source line.
// Columns are numbered beginning at 1. The value 0 is reserved to indicate
// that a statement begins at the 'left edge' of the line.
/// An unsigned integer indicating a column number within a source line.
/// Columns are numbered beginning at 1. The value 0 is reserved to indicate
/// that a statement begins at the 'left edge' of the line.
uint16_t Column;
// An unsigned integer indicating the identity of the source file
// corresponding to a machine instruction.
/// An unsigned integer indicating the identity of the source file
/// corresponding to a machine instruction.
uint16_t File;
// An unsigned integer representing the DWARF path discriminator value
// for this location.
/// An unsigned integer representing the DWARF path discriminator value
/// for this location.
uint32_t Discriminator;
// An unsigned integer whose value encodes the applicable instruction set
// architecture for the current instruction.
/// An unsigned integer whose value encodes the applicable instruction set
/// architecture for the current instruction.
uint8_t Isa;
// A boolean indicating that the current instruction is the beginning of a
// statement.
uint8_t IsStmt:1,
// A boolean indicating that the current instruction is the
// beginning of a basic block.
BasicBlock:1,
// A boolean indicating that the current address is that of the
// first byte after the end of a sequence of target machine
// instructions.
EndSequence:1,
// A boolean indicating that the current address is one (of possibly
// many) where execution should be suspended for an entry breakpoint
// of a function.
PrologueEnd:1,
// A boolean indicating that the current address is one (of possibly
// many) where execution should be suspended for an exit breakpoint
// of a function.
EpilogueBegin:1;
/// A boolean indicating that the current instruction is the beginning of a
/// statement.
uint8_t IsStmt : 1,
/// A boolean indicating that the current instruction is the
/// beginning of a basic block.
BasicBlock : 1,
/// A boolean indicating that the current address is that of the
/// first byte after the end of a sequence of target machine
/// instructions.
EndSequence : 1,
/// A boolean indicating that the current address is one (of possibly
/// many) where execution should be suspended for an entry breakpoint
/// of a function.
PrologueEnd : 1,
/// A boolean indicating that the current address is one (of possibly
/// many) where execution should be suspended for an exit breakpoint
/// of a function.
EpilogueBegin : 1;
};
// Represents a series of contiguous machine instructions. Line table for each
// compilation unit may consist of multiple sequences, which are not
// guaranteed to be in the order of ascending instruction address.
/// Represents a series of contiguous machine instructions. Line table for
/// each compilation unit may consist of multiple sequences, which are not
/// guaranteed to be in the order of ascending instruction address.
struct Sequence {
Sequence();
// Sequence describes instructions at address range [LowPC, HighPC)
// and is described by line table rows [FirstRowIndex, LastRowIndex).
/// Sequence describes instructions at address range [LowPC, HighPC)
/// and is described by line table rows [FirstRowIndex, LastRowIndex).
uint64_t LowPC;
uint64_t HighPC;
unsigned FirstRowIndex;
@ -164,7 +161,7 @@ public:
void reset();
static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) {
static bool orderByLowPC(const Sequence &LHS, const Sequence &RHS) {
return LHS.LowPC < RHS.LowPC;
}
@ -172,42 +169,38 @@ public:
return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex);
}
bool containsPC(uint64_t pc) const {
return (LowPC <= pc && pc < HighPC);
}
bool containsPC(uint64_t PC) const { return (LowPC <= PC && PC < HighPC); }
};
struct LineTable {
LineTable();
// Represents an invalid row
/// Represents an invalid row
const uint32_t UnknownRowIndex = UINT32_MAX;
void appendRow(const DWARFDebugLine::Row &R) {
Rows.push_back(R);
}
void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); }
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 UnknownRowIndex if there is no such row.
uint32_t lookupAddress(uint64_t address) const;
/// Returns the index of the row with file/line info for a given address,
/// or UnknownRowIndex 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;
bool hasFileAtIndex(uint64_t FileIndex) const;
// Extracts filename by its index in filename table in prologue.
// Returns true on success.
/// Extracts filename by its index in filename table in prologue.
/// Returns true on success.
bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir,
DILineInfoSpecifier::FileLineInfoKind Kind,
std::string &Result) const;
// Fills the Result argument with the file and line information
// corresponding to Address. Returns true on success.
/// Fills the Result argument with the file and line information
/// corresponding to Address. Returns true on success.
bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir,
DILineInfoSpecifier::FileLineInfoKind Kind,
DILineInfo &Result) const;
@ -216,8 +209,8 @@ public:
void clear();
/// Parse prologue and all rows.
bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap,
uint32_t *offset_ptr);
bool parse(DataExtractor DebugLineData, const RelocAddrMap *RMap,
uint32_t *OffsetPtr);
struct Prologue Prologue;
typedef std::vector<Row> RowVector;
@ -228,25 +221,25 @@ public:
SequenceVector Sequences;
private:
uint32_t findRowInSeq(const DWARFDebugLine::Sequence &seq,
uint64_t address) const;
uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq,
uint64_t Address) const;
};
const LineTable *getLineTable(uint32_t offset) const;
const LineTable *getOrParseLineTable(DataExtractor debug_line_data,
uint32_t offset);
const LineTable *getLineTable(uint32_t Offset) const;
const LineTable *getOrParseLineTable(DataExtractor DebugLineData,
uint32_t Offset);
private:
struct ParsingState {
ParsingState(struct LineTable *LT);
void resetRowAndSequence();
void appendRowToMatrix(uint32_t offset);
void appendRowToMatrix(uint32_t Offset);
// Line table we're currently parsing.
/// 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.
/// 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;

View File

@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
@ -51,95 +51,95 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
<< format(" line_range: %u\n", LineRange)
<< format(" opcode_base: %u\n", OpcodeBase);
for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i)
for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I)
OS << format("standard_opcode_lengths[%s] = %u\n",
LNStandardString(i + 1).data(), StandardOpcodeLengths[i]);
LNStandardString(I + 1).data(), StandardOpcodeLengths[I]);
if (!IncludeDirectories.empty())
for (uint32_t i = 0; i < IncludeDirectories.size(); ++i)
OS << format("include_directories[%3u] = '", i + 1)
<< IncludeDirectories[i] << "'\n";
for (uint32_t I = 0; I != IncludeDirectories.size(); ++I)
OS << format("include_directories[%3u] = '", I + 1)
<< IncludeDirectories[I] << "'\n";
if (!FileNames.empty()) {
OS << " Dir Mod Time File Len File Name\n"
<< " ---- ---------- ---------- -----------"
"----------------\n";
for (uint32_t i = 0; i < FileNames.size(); ++i) {
const FileNameEntry &fileEntry = FileNames[i];
OS << format("file_names[%3u] %4" PRIu64 " ", i + 1, fileEntry.DirIdx)
<< format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", fileEntry.ModTime,
fileEntry.Length)
<< fileEntry.Name << '\n';
for (uint32_t I = 0; I != FileNames.size(); ++I) {
const FileNameEntry &FileEntry = FileNames[I];
OS << format("file_names[%3u] %4" PRIu64 " ", I + 1, FileEntry.DirIdx)
<< format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", FileEntry.ModTime,
FileEntry.Length)
<< FileEntry.Name << '\n';
}
}
}
bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data,
uint32_t *offset_ptr) {
const uint64_t prologue_offset = *offset_ptr;
bool DWARFDebugLine::Prologue::parse(DataExtractor DebugLineData,
uint32_t *OffsetPtr) {
const uint64_t PrologueOffset = *OffsetPtr;
clear();
TotalLength = debug_line_data.getU32(offset_ptr);
TotalLength = DebugLineData.getU32(OffsetPtr);
if (TotalLength == UINT32_MAX) {
IsDWARF64 = true;
TotalLength = debug_line_data.getU64(offset_ptr);
TotalLength = DebugLineData.getU64(OffsetPtr);
} else if (TotalLength > 0xffffff00) {
return false;
}
Version = debug_line_data.getU16(offset_ptr);
Version = DebugLineData.getU16(OffsetPtr);
if (Version < 2)
return false;
PrologueLength =
debug_line_data.getUnsigned(offset_ptr, sizeofPrologueLength());
const uint64_t end_prologue_offset = PrologueLength + *offset_ptr;
MinInstLength = debug_line_data.getU8(offset_ptr);
PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength());
const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
MinInstLength = DebugLineData.getU8(OffsetPtr);
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);
MaxOpsPerInst = DebugLineData.getU8(OffsetPtr);
DefaultIsStmt = DebugLineData.getU8(OffsetPtr);
LineBase = DebugLineData.getU8(OffsetPtr);
LineRange = DebugLineData.getU8(OffsetPtr);
OpcodeBase = DebugLineData.getU8(OffsetPtr);
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);
for (uint32_t I = 1; I < OpcodeBase; ++I) {
uint8_t OpLen = DebugLineData.getU8(OffsetPtr);
StandardOpcodeLengths.push_back(OpLen);
}
while (*offset_ptr < end_prologue_offset) {
const char *s = debug_line_data.getCStr(offset_ptr);
if (s && s[0])
IncludeDirectories.push_back(s);
while (*OffsetPtr < EndPrologueOffset) {
const char *S = DebugLineData.getCStr(OffsetPtr);
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);
while (*OffsetPtr < EndPrologueOffset) {
const char *Name = DebugLineData.getCStr(OffsetPtr);
if (Name && Name[0]) {
FileNameEntry FileEntry;
FileEntry.Name = Name;
FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
FileNames.push_back(FileEntry);
} else {
break;
}
}
if (*offset_ptr != end_prologue_offset) {
fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64
" should have ended at 0x%8.8" PRIx64
" but it ended at 0x%8.8" PRIx64 "\n",
prologue_offset, end_prologue_offset, (uint64_t)*offset_ptr);
if (*OffsetPtr != EndPrologueOffset) {
fprintf(stderr,
"warning: parsing line table prologue at 0x%8.8" PRIx64
" should have ended at 0x%8.8" PRIx64
" but it ended at 0x%8.8" PRIx64 "\n",
PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
return false;
}
return true;
}
DWARFDebugLine::Row::Row(bool default_is_stmt) { reset(default_is_stmt); }
DWARFDebugLine::Row::Row(bool DefaultIsStmt) { reset(DefaultIsStmt); }
void DWARFDebugLine::Row::postAppend() {
BasicBlock = false;
@ -147,14 +147,14 @@ void DWARFDebugLine::Row::postAppend() {
EpilogueBegin = false;
}
void DWARFDebugLine::Row::reset(bool default_is_stmt) {
void DWARFDebugLine::Row::reset(bool DefaultIsStmt) {
Address = 0;
Line = 1;
Column = 0;
File = 1;
Isa = 0;
Discriminator = 0;
IsStmt = default_is_stmt;
IsStmt = DefaultIsStmt;
BasicBlock = false;
EndSequence = false;
PrologueEnd = false;
@ -212,7 +212,7 @@ void DWARFDebugLine::ParsingState::resetRowAndSequence() {
Sequence.reset();
}
void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t offset) {
void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t Offset) {
if (Sequence.Empty) {
// Record the beginning of instruction sequence.
Sequence.Empty = false;
@ -233,56 +233,56 @@ void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t offset) {
}
const DWARFDebugLine::LineTable *
DWARFDebugLine::getLineTable(uint32_t offset) const {
LineTableConstIter pos = LineTableMap.find(offset);
if (pos != LineTableMap.end())
return &pos->second;
DWARFDebugLine::getLineTable(uint32_t Offset) const {
LineTableConstIter Pos = LineTableMap.find(Offset);
if (Pos != LineTableMap.end())
return &Pos->second;
return nullptr;
}
const DWARFDebugLine::LineTable *
DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
uint32_t offset) {
std::pair<LineTableIter, bool> pos =
LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable()));
LineTable *LT = &pos.first->second;
if (pos.second) {
if (!LT->parse(debug_line_data, RelocMap, &offset))
DWARFDebugLine::getOrParseLineTable(DataExtractor DebugLineData,
uint32_t Offset) {
std::pair<LineTableIter, bool> Pos =
LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
LineTable *LT = &Pos.first->second;
if (Pos.second) {
if (!LT->parse(DebugLineData, RelocMap, &Offset))
return nullptr;
}
return LT;
}
bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
bool DWARFDebugLine::LineTable::parse(DataExtractor DebugLineData,
const RelocAddrMap *RMap,
uint32_t *offset_ptr) {
const uint32_t debug_line_offset = *offset_ptr;
uint32_t *OffsetPtr) {
const uint32_t DebugLineOffset = *OffsetPtr;
clear();
if (!Prologue.parse(debug_line_data, offset_ptr)) {
if (!Prologue.parse(DebugLineData, OffsetPtr)) {
// Restore our offset and return false to indicate failure!
*offset_ptr = debug_line_offset;
*OffsetPtr = DebugLineOffset;
return false;
}
const uint32_t end_offset =
debug_line_offset + Prologue.TotalLength + Prologue.sizeofTotalLength();
const uint32_t EndOffset =
DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength();
ParsingState State(this);
while (*offset_ptr < end_offset) {
uint8_t opcode = debug_line_data.getU8(offset_ptr);
while (*OffsetPtr < EndOffset) {
uint8_t Opcode = DebugLineData.getU8(OffsetPtr);
if (opcode == 0) {
if (Opcode == 0) {
// Extended Opcodes always start with a zero opcode followed by
// a uleb128 length so you can skip ones you don't know about
uint32_t ext_offset = *offset_ptr;
uint64_t len = debug_line_data.getULEB128(offset_ptr);
uint32_t arg_size = len - (*offset_ptr - ext_offset);
uint32_t ExtOffset = *OffsetPtr;
uint64_t Len = DebugLineData.getULEB128(OffsetPtr);
uint32_t ArgSize = Len - (*OffsetPtr - ExtOffset);
uint8_t sub_opcode = debug_line_data.getU8(offset_ptr);
switch (sub_opcode) {
uint8_t SubOpcode = DebugLineData.getU8(OffsetPtr);
switch (SubOpcode) {
case DW_LNE_end_sequence:
// Set the end_sequence register of the state machine to true and
// append a row to the matrix using the current values of the
@ -292,7 +292,7 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// address is that of the byte after the last target machine instruction
// of the sequence.
State.Row.EndSequence = true;
State.appendRowToMatrix(*offset_ptr);
State.appendRowToMatrix(*OffsetPtr);
State.resetRowAndSequence();
break;
@ -303,9 +303,8 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// relocatable address. All of the other statement program opcodes
// that affect the address register add a delta to it. This instruction
// stores a relocatable value into it instead.
State.Row.Address =
getRelocatedValue(debug_line_data, debug_line_data.getAddressSize(),
offset_ptr, RMap);
State.Row.Address = getRelocatedValue(
DebugLineData, DebugLineData.getAddressSize(), OffsetPtr, RMap);
break;
case DW_LNE_define_file:
@ -330,33 +329,33 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// the DW_LNE_define_file instruction. These numbers are used in the
// the file register of the state machine.
{
FileNameEntry fileEntry;
fileEntry.Name = debug_line_data.getCStr(offset_ptr);
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);
FileNameEntry FileEntry;
FileEntry.Name = DebugLineData.getCStr(OffsetPtr);
FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
Prologue.FileNames.push_back(FileEntry);
}
break;
case DW_LNE_set_discriminator:
State.Row.Discriminator = debug_line_data.getULEB128(offset_ptr);
State.Row.Discriminator = DebugLineData.getULEB128(OffsetPtr);
break;
default:
// Length doesn't include the zero opcode byte or the length itself, but
// it does include the sub_opcode, so we have to adjust for that below
(*offset_ptr) += arg_size;
(*OffsetPtr) += ArgSize;
break;
}
} else if (opcode < Prologue.OpcodeBase) {
switch (opcode) {
} else if (Opcode < Prologue.OpcodeBase) {
switch (Opcode) {
// Standard Opcodes
case DW_LNS_copy:
// Takes no arguments. Append a row to the matrix using the
// current values of the state-machine registers. Then set
// the basic_block register to false.
State.appendRowToMatrix(*offset_ptr);
State.appendRowToMatrix(*OffsetPtr);
break;
case DW_LNS_advance_pc:
@ -364,25 +363,25 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// min_inst_length field of the prologue, and adds the
// result to the address register of the state machine.
State.Row.Address +=
debug_line_data.getULEB128(offset_ptr) * Prologue.MinInstLength;
DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength;
break;
case DW_LNS_advance_line:
// Takes a single signed LEB128 operand and adds that value to
// the line register of the state machine.
State.Row.Line += debug_line_data.getSLEB128(offset_ptr);
State.Row.Line += DebugLineData.getSLEB128(OffsetPtr);
break;
case DW_LNS_set_file:
// Takes a single unsigned LEB128 operand and stores it in the file
// register of the state machine.
State.Row.File = debug_line_data.getULEB128(offset_ptr);
State.Row.File = DebugLineData.getULEB128(OffsetPtr);
break;
case DW_LNS_set_column:
// Takes a single unsigned LEB128 operand and stores it in the
// column register of the state machine.
State.Row.Column = debug_line_data.getULEB128(offset_ptr);
State.Row.Column = DebugLineData.getULEB128(OffsetPtr);
break;
case DW_LNS_negate_stmt:
@ -410,10 +409,10 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// than twice that range will it need to use both DW_LNS_advance_pc
// and a special opcode, requiring three or more bytes.
{
uint8_t adjust_opcode = 255 - Prologue.OpcodeBase;
uint64_t addr_offset =
(adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
State.Row.Address += addr_offset;
uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase;
uint64_t AddrOffset =
(AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
State.Row.Address += AddrOffset;
}
break;
@ -427,7 +426,7 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// judge when the computation of a special opcode overflows and
// requires the use of DW_LNS_advance_pc. Such assemblers, however,
// can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
State.Row.Address += debug_line_data.getU16(offset_ptr);
State.Row.Address += DebugLineData.getU16(OffsetPtr);
break;
case DW_LNS_set_prologue_end:
@ -445,7 +444,7 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
case DW_LNS_set_isa:
// Takes a single unsigned LEB128 operand and stores it in the
// column register of the state machine.
State.Row.Isa = debug_line_data.getULEB128(offset_ptr);
State.Row.Isa = DebugLineData.getULEB128(OffsetPtr);
break;
default:
@ -453,10 +452,10 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// of such opcodes because they are specified in the prologue
// as a multiple of LEB128 operands for each opcode.
{
assert(opcode - 1U < Prologue.StandardOpcodeLengths.size());
uint8_t opcode_length = Prologue.StandardOpcodeLengths[opcode - 1];
for (uint8_t i = 0; i < opcode_length; ++i)
debug_line_data.getULEB128(offset_ptr);
assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
for (uint8_t I = 0; I < OpcodeLength; ++I)
DebugLineData.getULEB128(OffsetPtr);
}
break;
}
@ -494,14 +493,14 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
//
// line increment = line_base + (adjusted opcode % line_range)
uint8_t adjust_opcode = opcode - Prologue.OpcodeBase;
uint64_t addr_offset =
(adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
int32_t line_offset =
Prologue.LineBase + (adjust_opcode % Prologue.LineRange);
State.Row.Line += line_offset;
State.Row.Address += addr_offset;
State.appendRowToMatrix(*offset_ptr);
uint8_t AdjustOpcode = Opcode - Prologue.OpcodeBase;
uint64_t AddrOffset =
(AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
int32_t LineOffset =
Prologue.LineBase + (AdjustOpcode % Prologue.LineRange);
State.Row.Line += LineOffset;
State.Row.Address += AddrOffset;
State.appendRowToMatrix(*OffsetPtr);
// Reset discriminator to 0.
State.Row.Discriminator = 0;
}
@ -523,120 +522,118 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// rudimentary sequences for address ranges [0x0, 0xsomething).
}
return end_offset;
return EndOffset;
}
uint32_t
DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &seq,
uint64_t address) const {
if (!seq.containsPC(address))
DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq,
uint64_t Address) const {
if (!Seq.containsPC(Address))
return UnknownRowIndex;
// Search for instruction address in the rows describing the sequence.
// Rows are stored in a vector, so we may use arithmetical operations with
// iterators.
DWARFDebugLine::Row row;
row.Address = address;
RowIter first_row = Rows.begin() + seq.FirstRowIndex;
RowIter last_row = Rows.begin() + seq.LastRowIndex;
LineTable::RowIter row_pos = std::lower_bound(
first_row, last_row, row, DWARFDebugLine::Row::orderByAddress);
if (row_pos == last_row) {
return seq.LastRowIndex - 1;
DWARFDebugLine::Row Row;
Row.Address = Address;
RowIter FirstRow = Rows.begin() + Seq.FirstRowIndex;
RowIter LastRow = Rows.begin() + Seq.LastRowIndex;
LineTable::RowIter RowPos = std::lower_bound(
FirstRow, LastRow, Row, DWARFDebugLine::Row::orderByAddress);
if (RowPos == LastRow) {
return Seq.LastRowIndex - 1;
}
uint32_t index = seq.FirstRowIndex + (row_pos - first_row);
if (row_pos->Address > address) {
if (row_pos == first_row)
uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow);
if (RowPos->Address > Address) {
if (RowPos == FirstRow)
return UnknownRowIndex;
else
index--;
Index--;
}
return index;
return Index;
}
uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const {
if (Sequences.empty())
return UnknownRowIndex;
// First, find an instruction sequence containing the given address.
DWARFDebugLine::Sequence sequence;
sequence.LowPC = address;
SequenceIter first_seq = Sequences.begin();
SequenceIter last_seq = Sequences.end();
SequenceIter seq_pos = std::lower_bound(
first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC);
DWARFDebugLine::Sequence found_seq;
if (seq_pos == last_seq) {
found_seq = Sequences.back();
} else if (seq_pos->LowPC == address) {
found_seq = *seq_pos;
DWARFDebugLine::Sequence Sequence;
Sequence.LowPC = Address;
SequenceIter FirstSeq = Sequences.begin();
SequenceIter LastSeq = Sequences.end();
SequenceIter SeqPos = std::lower_bound(
FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
DWARFDebugLine::Sequence FoundSeq;
if (SeqPos == LastSeq) {
FoundSeq = Sequences.back();
} else if (SeqPos->LowPC == Address) {
FoundSeq = *SeqPos;
} else {
if (seq_pos == first_seq)
if (SeqPos == FirstSeq)
return UnknownRowIndex;
found_seq = *(seq_pos - 1);
FoundSeq = *(SeqPos - 1);
}
return findRowInSeq(found_seq, address);
return findRowInSeq(FoundSeq, Address);
}
bool DWARFDebugLine::LineTable::lookupAddressRange(
uint64_t address, uint64_t size, std::vector<uint32_t> &result) const {
uint64_t Address, uint64_t Size, std::vector<uint32_t> &Result) const {
if (Sequences.empty())
return false;
uint64_t end_addr = address + size;
uint64_t EndAddr = Address + Size;
// First, find an instruction sequence containing the given address.
DWARFDebugLine::Sequence sequence;
sequence.LowPC = address;
SequenceIter first_seq = Sequences.begin();
SequenceIter last_seq = Sequences.end();
SequenceIter seq_pos = std::lower_bound(
first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC);
if (seq_pos == last_seq || seq_pos->LowPC != address) {
if (seq_pos == first_seq)
DWARFDebugLine::Sequence Sequence;
Sequence.LowPC = Address;
SequenceIter FirstSeq = Sequences.begin();
SequenceIter LastSeq = Sequences.end();
SequenceIter SeqPos = std::lower_bound(
FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
if (SeqPos == LastSeq || SeqPos->LowPC != Address) {
if (SeqPos == FirstSeq)
return false;
seq_pos--;
SeqPos--;
}
if (!seq_pos->containsPC(address))
if (!SeqPos->containsPC(Address))
return false;
SequenceIter start_pos = seq_pos;
SequenceIter StartPos = SeqPos;
// Add the rows from the first sequence to the vector, starting with the
// index we just calculated
while (seq_pos != last_seq && seq_pos->LowPC < end_addr) {
const DWARFDebugLine::Sequence &cur_seq = *seq_pos;
while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
const DWARFDebugLine::Sequence &CurSeq = *SeqPos;
// For the first sequence, we need to find which row in the sequence is the
// first in our range.
uint32_t first_row_index = cur_seq.FirstRowIndex;
if (seq_pos == start_pos)
first_row_index = findRowInSeq(cur_seq, address);
uint32_t FirstRowIndex = CurSeq.FirstRowIndex;
if (SeqPos == StartPos)
FirstRowIndex = findRowInSeq(CurSeq, Address);
// Figure out the last row in the range.
uint32_t last_row_index = findRowInSeq(cur_seq, end_addr - 1);
if (last_row_index == UnknownRowIndex)
last_row_index = cur_seq.LastRowIndex - 1;
uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1);
if (LastRowIndex == UnknownRowIndex)
LastRowIndex = CurSeq.LastRowIndex - 1;
assert(first_row_index != UnknownRowIndex);
assert(last_row_index != UnknownRowIndex);
assert(FirstRowIndex != UnknownRowIndex);
assert(LastRowIndex != UnknownRowIndex);
for (uint32_t i = first_row_index; i <= last_row_index; ++i) {
result.push_back(i);
for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) {
Result.push_back(I);
}
++seq_pos;
++SeqPos;
}
return true;
}
bool
DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const {
bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const {
return FileIndex != 0 && FileIndex <= Prologue.FileNames.size();
}
bool
DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
const char *CompDir,
FileLineInfoKind Kind,
std::string &Result) const {
bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
const char *CompDir,
FileLineInfoKind Kind,
std::string &Result) const {
if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
return false;
const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];