Home | History | Annotate | Download | only in DWARF
      1 //===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef SymbolFileDWARF_DWARFDebugLine_h_
     11 #define SymbolFileDWARF_DWARFDebugLine_h_
     12 
     13 #include <map>
     14 #include <vector>
     15 #include <string>
     16 
     17 #include "lldb/lldb-private.h"
     18 
     19 #include "DWARFDefines.h"
     20 
     21 class SymbolFileDWARF;
     22 class DWARFDebugInfoEntry;
     23 
     24 //----------------------------------------------------------------------
     25 // DWARFDebugLine
     26 //----------------------------------------------------------------------
     27 class DWARFDebugLine
     28 {
     29 public:
     30     //------------------------------------------------------------------
     31     // FileNameEntry
     32     //------------------------------------------------------------------
     33     struct FileNameEntry
     34     {
     35         FileNameEntry() :
     36             name(),
     37             dir_idx(0),
     38             mod_time(0),
     39             length(0)
     40         {
     41         }
     42 
     43         std::string     name;
     44         dw_sleb128_t    dir_idx;
     45         dw_sleb128_t    mod_time;
     46         dw_sleb128_t    length;
     47 
     48     };
     49 
     50     //------------------------------------------------------------------
     51     // Prologue
     52     //------------------------------------------------------------------
     53     struct Prologue
     54     {
     55 
     56         Prologue() :
     57             total_length(0),
     58             version(0),
     59             prologue_length(0),
     60             min_inst_length(0),
     61             default_is_stmt(0),
     62             line_base(0),
     63             line_range(0),
     64             opcode_base(0),
     65             standard_opcode_lengths(),
     66             include_directories(),
     67             file_names()
     68         {
     69         }
     70 
     71         typedef std::shared_ptr<Prologue> shared_ptr;
     72 
     73         uint32_t    total_length;   // The size in bytes of the statement information for this compilation unit (not including the total_length field itself).
     74         uint16_t    version;        // Version identifier for the statement information format.
     75         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.
     76         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.
     77         uint8_t     default_is_stmt;// The initial value of theis_stmtregister.
     78         int8_t      line_base;      // This parameter affects the meaning of the special opcodes. See below.
     79         uint8_t     line_range;     // This parameter affects the meaning of the special opcodes. See below.
     80         uint8_t     opcode_base;    // The number assigned to the first special opcode.
     81         std::vector<uint8_t>            standard_opcode_lengths;
     82         std::vector<std::string>        include_directories;
     83         std::vector<FileNameEntry>      file_names;
     84 
     85         // Length of the prologue in bytes
     86         uint32_t Length() const { return prologue_length + sizeof(total_length) + sizeof(version) + sizeof(prologue_length); }
     87         // Length of the line table data in bytes (not including the prologue)
     88         uint32_t StatementTableLength() const { return total_length + sizeof(total_length) - Length(); }
     89         int32_t MaxLineIncrementForSpecialOpcode() const { return line_base + (int8_t)line_range - 1; }
     90         bool IsValid() const;
     91 //      void Append(BinaryStreamBuf& buff) const;
     92         void Dump (lldb_private::Log *log);
     93         void Clear()
     94         {
     95             total_length = version = prologue_length = min_inst_length = line_base = line_range = opcode_base = 0;
     96             line_base = 0;
     97             standard_opcode_lengths.clear();
     98             include_directories.clear();
     99             file_names.clear();
    100         }
    101         bool GetFile(uint32_t file_idx, std::string& file, std::string& dir) const;
    102 
    103     };
    104 
    105     // Standard .debug_line state machine structure
    106     struct Row
    107     {
    108         typedef std::vector<Row>            collection;
    109         typedef collection::iterator        iterator;
    110         typedef collection::const_iterator  const_iterator;
    111 
    112         Row(bool default_is_stmt = false);
    113         Row(const Row& rhs) :
    114             address(rhs.address),
    115             line(rhs.line),
    116             column(rhs.column),
    117             file(rhs.file),
    118             is_stmt(rhs.is_stmt),
    119             basic_block(rhs.basic_block),
    120             end_sequence(rhs.end_sequence),
    121             prologue_end(rhs.prologue_end),
    122             epilogue_begin(rhs.epilogue_begin),
    123             isa(rhs.isa)
    124         {}
    125         Row& operator =(const Row& rhs)
    126         {
    127             if (&rhs == this)
    128                 return *this;
    129 
    130             address = rhs.address;
    131             line = rhs.line;
    132             column = rhs.column;
    133             file = rhs.file;
    134             is_stmt = rhs.is_stmt;
    135             basic_block = rhs.basic_block;
    136             end_sequence = rhs.end_sequence;
    137             prologue_end = rhs.prologue_end;
    138             epilogue_begin = rhs.epilogue_begin;
    139             isa = rhs.isa;
    140             return *this;
    141         }
    142         virtual ~Row() {}
    143         void PostAppend ();
    144         void Reset(bool default_is_stmt);
    145         void Dump(lldb_private::Log *log) const;
    146         static void Insert(Row::collection& state_coll, const Row& state);
    147         static void Dump(lldb_private::Log *log, const Row::collection& state_coll);
    148 
    149         dw_addr_t   address;        // The program-counter value corresponding to a machine instruction generated by the compiler.
    150         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.
    151         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.
    152         uint16_t    file;           // An unsigned integer indicating the identity of the source file corresponding to a machine instruction.
    153         uint8_t     is_stmt:1,      // A boolean indicating that the current instruction is the beginning of a statement.
    154                     basic_block:1,  // A boolean indicating that the current instruction is the beginning of a basic block.
    155                     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.
    156                     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.
    157                     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.
    158         uint32_t    isa;            // An unsigned integer whose value encodes the applicable instruction set architecture for the current instruction.
    159     };
    160 
    161 
    162     //------------------------------------------------------------------
    163     // LineTable
    164     //------------------------------------------------------------------
    165     struct LineTable
    166     {
    167         typedef std::shared_ptr<LineTable> shared_ptr;
    168 
    169         LineTable() :
    170             prologue(),
    171             rows()
    172         {
    173         }
    174 
    175         void AppendRow(const DWARFDebugLine::Row& state);
    176         void Clear()
    177         {
    178             prologue.reset();
    179             rows.clear();
    180         }
    181 
    182         uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
    183         void Dump(lldb_private::Log *log) const;
    184 
    185         Prologue::shared_ptr prologue;
    186         Row::collection rows;
    187     };
    188 
    189     //------------------------------------------------------------------
    190     // State
    191     //------------------------------------------------------------------
    192     struct State : public Row
    193     {
    194         typedef void (*Callback)(dw_offset_t offset, const State& state, void* userData);
    195 
    196         // Special row codes used when calling the callback
    197         enum
    198         {
    199             StartParsingLineTable = 0,
    200             DoneParsingLineTable = -1
    201         };
    202 
    203         State (Prologue::shared_ptr& prologue_sp,
    204                lldb_private::Log *log,
    205                Callback callback,
    206                void* userData);
    207 
    208         void
    209         AppendRowToMatrix (dw_offset_t offset);
    210 
    211         void
    212         Finalize (dw_offset_t offset);
    213 
    214         void
    215         Reset ();
    216 
    217         Prologue::shared_ptr prologue;
    218         lldb_private::Log *log;
    219         Callback callback; // Callback function that gets called each time an entry is to be added to the matrix
    220         void* callbackUserData;
    221         int row; // The row number that starts at zero for the prologue, and increases for each row added to the matrix
    222     private:
    223         DISALLOW_COPY_AND_ASSIGN (State);
    224     };
    225 
    226     static bool DumpOpcodes(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET, uint32_t dump_flags = 0);   // If line_offset is invalid, dump everything
    227     static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET);  // If line_offset is invalid, dump everything
    228     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);
    229     static bool ParsePrologue(const lldb_private::DataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue);
    230     static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, lldb::offset_t* offset_ptr, State::Callback callback, void* userData);
    231     static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DataExtractor& debug_line_data, const dw_offset_t line_offset);
    232     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);
    233     static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table);
    234     static void Parse(const lldb_private::DataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData);
    235 //  static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, const DWARFDebugLine::Row::collection& state_coll, const uint32_t addr_size, BinaryStreamBuf &debug_line_data);
    236 
    237     DWARFDebugLine() :
    238         m_lineTableMap()
    239     {
    240     }
    241 
    242     void Parse(const lldb_private::DataExtractor& debug_line_data);
    243     void ParseIfNeeded(const lldb_private::DataExtractor& debug_line_data);
    244     LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
    245 
    246 protected:
    247     typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
    248     typedef LineTableMap::iterator LineTableIter;
    249     typedef LineTableMap::const_iterator LineTableConstIter;
    250 
    251     LineTableMap m_lineTableMap;
    252 };
    253 
    254 #endif  // SymbolFileDWARF_DWARFDebugLine_h_
    255