A lot of comments in LLDB are surrounded by an ASCII line to delimit the begging and end of the comment. Its use is not really consistent across the code base, sometimes the lines are longer, sometimes they are shorter and sometimes they are omitted. Furthermore, it looks kind of weird with the 80 column limit, where the comment actually extends past the line, but not by much. Furthermore, when /// is used for Doxygen comments, it looks particularly odd. And when // is used, it incorrectly gives the impression that it's actually a Doxygen comment. I assume these lines were added to improve distinguishing between comments and code. However, given that todays editors and IDEs do a great job at highlighting comments, I think it's worth to drop this for the sake of consistency. The alternative is fixing all the inconsistencies, which would create a lot more churn. Differential revision: https://reviews.llvm.org/D60508 llvm-svn: 358135
227 lines
9.1 KiB
C++
227 lines
9.1 KiB
C++
//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SymbolFileDWARF_DWARFDebugLine_h_
|
|
#define SymbolFileDWARF_DWARFDebugLine_h_
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "lldb/Utility/FileSpec.h"
|
|
#include "lldb/lldb-private.h"
|
|
|
|
#include "DWARFDataExtractor.h"
|
|
#include "DWARFDefines.h"
|
|
|
|
#include "llvm/Support/MD5.h"
|
|
|
|
class DWARFUnit;
|
|
class SymbolFileDWARF;
|
|
|
|
// DWARFDebugLine
|
|
class DWARFDebugLine {
|
|
public:
|
|
// FileNameEntry
|
|
struct FileNameEntry {
|
|
FileNameEntry() : name(nullptr), dir_idx(0), mod_time(0), length(0) {}
|
|
|
|
const char *name;
|
|
dw_sleb128_t dir_idx;
|
|
dw_sleb128_t mod_time;
|
|
dw_sleb128_t length;
|
|
llvm::MD5::MD5Result checksum;
|
|
};
|
|
|
|
// Prologue
|
|
struct Prologue {
|
|
|
|
Prologue()
|
|
: total_length(0), version(0), prologue_length(0), min_inst_length(0),
|
|
default_is_stmt(0), line_base(0), line_range(0), opcode_base(0),
|
|
standard_opcode_lengths(), include_directories(), file_names() {}
|
|
|
|
typedef std::shared_ptr<Prologue> shared_ptr;
|
|
|
|
uint32_t total_length; // The size in bytes of the statement information for
|
|
// this compilation unit (not including the
|
|
// total_length field itself).
|
|
uint16_t
|
|
version; // Version identifier for the statement information format.
|
|
|
|
uint8_t address_size;
|
|
uint8_t segment_selector_size;
|
|
|
|
uint32_t prologue_length; // The number of bytes following the
|
|
// prologue_length field to the beginning of the
|
|
// first byte of the statement program itself.
|
|
uint8_t min_inst_length; // 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 maximum_operations_per_instruction; // New in DWARF4. The maximum
|
|
// number of individual
|
|
// operations that may be
|
|
// encoded in an instruction.
|
|
uint8_t default_is_stmt; // The initial value of theis_stmtregister.
|
|
int8_t line_base; // This parameter affects the meaning of the special
|
|
// opcodes. See below.
|
|
uint8_t line_range; // This parameter affects the meaning of the special
|
|
// opcodes. See below.
|
|
uint8_t opcode_base; // The number assigned to the first special opcode.
|
|
std::vector<uint8_t> standard_opcode_lengths;
|
|
std::vector<const char *> include_directories;
|
|
std::vector<FileNameEntry> file_names;
|
|
|
|
int32_t MaxLineIncrementForSpecialOpcode() const {
|
|
return line_base + (int8_t)line_range - 1;
|
|
}
|
|
bool IsValid() const;
|
|
// void Append(BinaryStreamBuf& buff) const;
|
|
void Dump(lldb_private::Log *log);
|
|
void Clear() {
|
|
total_length = version = prologue_length = min_inst_length = line_base =
|
|
line_range = opcode_base = 0;
|
|
line_base = 0;
|
|
standard_opcode_lengths.clear();
|
|
include_directories.clear();
|
|
file_names.clear();
|
|
}
|
|
bool GetFile(uint32_t file_idx, const lldb_private::FileSpec &cu_comp_dir,
|
|
lldb_private::FileSpec::Style style,
|
|
lldb_private::FileSpec &file) const;
|
|
};
|
|
|
|
// Standard .debug_line state machine structure
|
|
struct Row {
|
|
typedef std::vector<Row> collection;
|
|
typedef collection::iterator iterator;
|
|
typedef collection::const_iterator const_iterator;
|
|
|
|
Row(bool default_is_stmt = false);
|
|
virtual ~Row() {}
|
|
void PostAppend();
|
|
void Reset(bool default_is_stmt);
|
|
void Dump(lldb_private::Log *log) const;
|
|
static void Insert(Row::collection &state_coll, const Row &state);
|
|
|
|
dw_addr_t address; // The program-counter value corresponding to a machine
|
|
// instruction generated by the compiler.
|
|
uint32_t 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.
|
|
uint16_t column; // 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 file; // An unsigned integer indicating the identity of the source
|
|
// file corresponding to a machine instruction.
|
|
uint8_t is_stmt : 1, // A boolean indicating that the current instruction is
|
|
// the beginning of a statement.
|
|
basic_block : 1, // A boolean indicating that the current instruction is
|
|
// the beginning of a basic block.
|
|
end_sequence : 1, // A boolean indicating that the current address is
|
|
// that of the first byte after the end of a sequence
|
|
// of target machine instructions.
|
|
prologue_end : 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.
|
|
epilogue_begin : 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.
|
|
uint32_t isa; // An unsigned integer whose value encodes the applicable
|
|
// instruction set architecture for the current instruction.
|
|
};
|
|
|
|
// LineTable
|
|
struct LineTable {
|
|
typedef std::shared_ptr<LineTable> shared_ptr;
|
|
|
|
LineTable() : prologue(), rows() {}
|
|
|
|
void AppendRow(const DWARFDebugLine::Row &state);
|
|
void Clear() {
|
|
prologue.reset();
|
|
rows.clear();
|
|
}
|
|
|
|
uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
|
|
|
|
Prologue::shared_ptr prologue;
|
|
Row::collection rows;
|
|
};
|
|
|
|
// State
|
|
struct State : public Row {
|
|
typedef void (*Callback)(dw_offset_t offset, const State &state,
|
|
void *userData);
|
|
|
|
// Special row codes used when calling the callback
|
|
enum { StartParsingLineTable = 0, DoneParsingLineTable = -1 };
|
|
|
|
State(Prologue::shared_ptr &prologue_sp, lldb_private::Log *log,
|
|
Callback callback, void *userData);
|
|
|
|
void AppendRowToMatrix(dw_offset_t offset);
|
|
|
|
void Finalize(dw_offset_t offset);
|
|
|
|
void Reset();
|
|
|
|
Prologue::shared_ptr prologue;
|
|
lldb_private::Log *log;
|
|
Callback callback; // Callback function that gets called each time an entry
|
|
// is to be added to the matrix
|
|
void *callbackUserData;
|
|
int row; // The row number that starts at zero for the prologue, and
|
|
// increases for each row added to the matrix
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(State);
|
|
};
|
|
|
|
static bool
|
|
ParseSupportFiles(const lldb::ModuleSP &module_sp,
|
|
const lldb_private::DWARFDataExtractor &debug_line_data,
|
|
dw_offset_t stmt_list,
|
|
lldb_private::FileSpecList &support_files,
|
|
DWARFUnit *dwarf_cu);
|
|
static bool
|
|
ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
|
|
lldb::offset_t *offset_ptr, Prologue *prologue,
|
|
DWARFUnit *dwarf_cu = nullptr);
|
|
static bool
|
|
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
|
|
lldb::offset_t *offset_ptr, State::Callback callback,
|
|
void *userData, DWARFUnit *dwarf_cu);
|
|
static bool
|
|
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
|
|
lldb::offset_t *offset_ptr, LineTable *line_table,
|
|
DWARFUnit *dwarf_cu);
|
|
static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
|
|
DWARFDebugLine::State::Callback callback, void *userData);
|
|
// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
|
|
// const DWARFDebugLine::Row::collection& state_coll, const uint32_t
|
|
// addr_size, BinaryStreamBuf &debug_line_data);
|
|
|
|
DWARFDebugLine() : m_lineTableMap() {}
|
|
|
|
void Parse(const lldb_private::DWARFDataExtractor &debug_line_data);
|
|
void ParseIfNeeded(const lldb_private::DWARFDataExtractor &debug_line_data);
|
|
LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
|
|
|
|
protected:
|
|
typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
|
|
typedef LineTableMap::iterator LineTableIter;
|
|
typedef LineTableMap::const_iterator LineTableConstIter;
|
|
|
|
LineTableMap m_lineTableMap;
|
|
};
|
|
|
|
#endif // SymbolFileDWARF_DWARFDebugLine_h_
|