#ifndef SymbolFileDWARF_DWARFDebugLine_h_
#define SymbolFileDWARF_DWARFDebugLine_h_
#include <map>
#include <vector>
#include <string>
#include "lldb/lldb-private.h"
#include "DWARFDefines.h"
class SymbolFileDWARF;
class DWARFDebugInfoEntry;
class DWARFDebugLine
{
public:
struct FileNameEntry
{
FileNameEntry() :
name(),
dir_idx(0),
mod_time(0),
length(0)
{
}
std::string name;
dw_sleb128_t dir_idx;
dw_sleb128_t mod_time;
dw_sleb128_t length;
};
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; uint16_t version; uint32_t prologue_length; uint8_t min_inst_length; uint8_t default_is_stmt; int8_t line_base; uint8_t line_range; uint8_t opcode_base; std::vector<uint8_t> standard_opcode_lengths;
std::vector<std::string> include_directories;
std::vector<FileNameEntry> file_names;
uint32_t Length() const { return prologue_length + sizeof(total_length) + sizeof(version) + sizeof(prologue_length); }
uint32_t StatementTableLength() const { return total_length + sizeof(total_length) - Length(); }
int32_t MaxLineIncrementForSpecialOpcode() const { return line_base + (int8_t)line_range - 1; }
bool IsValid() 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, std::string& file, std::string& dir) const;
};
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);
static void Dump(lldb_private::Log *log, const Row::collection& state_coll);
dw_addr_t address; uint32_t line; uint16_t column; uint16_t file; uint8_t is_stmt:1, basic_block:1, end_sequence:1, prologue_end:1, epilogue_begin:1; uint32_t isa; };
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;
void Dump(lldb_private::Log *log) const;
Prologue::shared_ptr prologue;
Row::collection rows;
};
struct State : public Row
{
typedef void (*Callback)(dw_offset_t offset, const State& state, void* userData);
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; void* callbackUserData;
int row; private:
DISALLOW_COPY_AND_ASSIGN (State);
};
static bool DumpOpcodes(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET, uint32_t dump_flags = 0); static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET); static bool ParseSupportFiles(const lldb::ModuleSP &module_sp, const lldb_private::DataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, lldb_private::FileSpecList &support_files);
static bool ParsePrologue(const lldb_private::DataExtractor& debug_line_data, dw_offset_t* offset_ptr, Prologue* prologue);
static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, dw_offset_t* offset_ptr, State::Callback callback, void* userData);
static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DataExtractor& debug_line_data, const dw_offset_t line_offset);
static dw_offset_t DumpStatementOpcodes(lldb_private::Log *log, const lldb_private::DataExtractor& debug_line_data, const dw_offset_t line_offset, uint32_t flags);
static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, uint32_t* offset_ptr, LineTable* line_table);
static void Parse(const lldb_private::DataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData);
DWARFDebugLine() :
m_lineTableMap()
{
}
void Parse(const lldb_private::DataExtractor& debug_line_data);
void ParseIfNeeded(const lldb_private::DataExtractor& 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_