//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H
-#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H
+#include "DWARFRelocMap.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/Support/DataExtractor.h"
#include <map>
#include <string>
class DWARFDebugLine {
public:
+ DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {}
struct FileNameEntry {
- FileNameEntry() : DirIdx(0), ModTime(0), Length(0) {}
+ FileNameEntry() : Name(nullptr), DirIdx(0), ModTime(0), Length(0) {}
- std::string Name;
+ const char *Name;
uint64_t DirIdx;
uint64_t ModTime;
uint64_t Length;
};
struct Prologue {
- Prologue()
- : TotalLength(0), Version(0), PrologueLength(0), MinInstLength(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).
// 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.
+ uint8_t MaxOpsPerInst;
// The initial value of theis_stmtregister.
uint8_t DefaultIsStmt;
// This parameter affects the meaning of the special opcodes. See below.
// The number assigned to the first special opcode.
uint8_t OpcodeBase;
std::vector<uint8_t> StandardOpcodeLengths;
- std::vector<std::string> IncludeDirectories;
+ std::vector<const char*> IncludeDirectories;
std::vector<FileNameEntry> FileNames;
// Length of the prologue in bytes.
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);
void dump(raw_ostream &OS) const;
+ 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.
uint64_t Address;
// An unsigned integer whose value encodes the applicable instruction set
// architecture for the current instruction.
uint8_t Isa;
+ // An unsigned integer representing the DWARF path discriminator value
+ // for this location.
+ uint32_t Discriminator;
// A boolean indicating that the current instruction is the beginning of a
// statement.
uint8_t IsStmt:1,
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.
+ struct Sequence {
+ // 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;
+ unsigned LastRowIndex;
+ bool Empty;
+
+ Sequence();
+ void reset();
+
+ static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) {
+ return LHS.LowPC < RHS.LowPC;
+ }
+ bool isValid() const {
+ return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex);
+ }
+ bool containsPC(uint64_t pc) const {
+ return (LowPC <= pc && pc < HighPC);
+ }
+ };
+
struct LineTable {
- void appendRow(const DWARFDebugLine::Row &state) { Rows.push_back(state); }
- void clear() {
- Prologue.clear();
- Rows.clear();
+ LineTable();
+
+ void appendRow(const DWARFDebugLine::Row &R) {
+ Rows.push_back(R);
+ }
+ void appendSequence(const DWARFDebugLine::Sequence &S) {
+ Sequences.push_back(S);
}
- uint32_t lookupAddress(uint64_t address, uint64_t cu_high_pc) const;
+ // 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;
+
+ // Extracts filename by its index in filename table in prologue.
+ // Returns true on success.
+ bool getFileNameByIndex(uint64_t FileIndex,
+ DILineInfoSpecifier::FileLineInfoKind Kind,
+ std::string &Result) const;
+
void dump(raw_ostream &OS) const;
+ void clear();
+
+ /// Parse prologue and all rows.
+ bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap,
+ uint32_t *offset_ptr);
struct Prologue Prologue;
- std::vector<Row> Rows;
+ typedef std::vector<Row> RowVector;
+ typedef RowVector::const_iterator RowIter;
+ typedef std::vector<Sequence> SequenceVector;
+ typedef SequenceVector::const_iterator SequenceIter;
+ RowVector Rows;
+ SequenceVector Sequences;
};
- struct State : public Row, public LineTable {
- // Special row codes.
- enum {
- StartParsingLineTable = 0,
- DoneParsingLineTable = -1
- };
+ const LineTable *getLineTable(uint32_t offset) const;
+ const LineTable *getOrParseLineTable(DataExtractor debug_line_data,
+ uint32_t offset);
- State() : row(0) {}
- virtual ~State();
+private:
+ struct ParsingState {
+ ParsingState(struct LineTable *LT);
- virtual void appendRowToMatrix(uint32_t offset);
- virtual void finalize(uint32_t offset) { row = DoneParsingLineTable; }
- virtual void reset() { Row::reset(Prologue.DefaultIsStmt); }
+ 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 row;
+ unsigned RowNumber;
+ struct Row Row;
+ struct Sequence Sequence;
};
- struct DumpingState : public State {
- DumpingState(raw_ostream &OS) : OS(OS) {}
- virtual ~DumpingState();
- virtual void finalize(uint32_t offset);
- private:
- 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,
- uint32_t *offset_ptr, State &state);
-
- /// Parse all information in the debug_line_data into an internal
- /// representation.
- void parse(DataExtractor debug_line_data);
- void parseIfNeeded(DataExtractor debug_line_data) {
- if (LineTableMap.empty())
- parse(debug_line_data);
- }
- static void dump(DataExtractor debug_line_data, raw_ostream &OS);
- const LineTable *getLineTable(uint32_t offset) const;
-
-private:
typedef std::map<uint32_t, LineTable> LineTableMapTy;
typedef LineTableMapTy::iterator LineTableIter;
typedef LineTableMapTy::const_iterator LineTableConstIter;
+ const RelocAddrMap *RelocMap;
LineTableMapTy LineTableMap;
};