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