1254721Semaste//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#ifndef SymbolFileDWARF_DWARFDebugLine_h_
11254721Semaste#define SymbolFileDWARF_DWARFDebugLine_h_
12254721Semaste
13254721Semaste#include <map>
14254721Semaste#include <vector>
15254721Semaste#include <string>
16254721Semaste
17254721Semaste#include "lldb/lldb-private.h"
18254721Semaste
19263363Semaste#include "DWARFDataExtractor.h"
20254721Semaste#include "DWARFDefines.h"
21254721Semaste
22254721Semasteclass SymbolFileDWARF;
23254721Semasteclass DWARFDebugInfoEntry;
24254721Semaste
25254721Semaste//----------------------------------------------------------------------
26254721Semaste// DWARFDebugLine
27254721Semaste//----------------------------------------------------------------------
28254721Semasteclass DWARFDebugLine
29254721Semaste{
30254721Semastepublic:
31254721Semaste    //------------------------------------------------------------------
32254721Semaste    // FileNameEntry
33254721Semaste    //------------------------------------------------------------------
34254721Semaste    struct FileNameEntry
35254721Semaste    {
36254721Semaste        FileNameEntry() :
37254721Semaste            name(),
38254721Semaste            dir_idx(0),
39254721Semaste            mod_time(0),
40254721Semaste            length(0)
41254721Semaste        {
42254721Semaste        }
43254721Semaste
44254721Semaste        std::string     name;
45254721Semaste        dw_sleb128_t    dir_idx;
46254721Semaste        dw_sleb128_t    mod_time;
47254721Semaste        dw_sleb128_t    length;
48254721Semaste
49254721Semaste    };
50254721Semaste
51254721Semaste    //------------------------------------------------------------------
52254721Semaste    // Prologue
53254721Semaste    //------------------------------------------------------------------
54254721Semaste    struct Prologue
55254721Semaste    {
56254721Semaste
57254721Semaste        Prologue() :
58254721Semaste            total_length(0),
59254721Semaste            version(0),
60254721Semaste            prologue_length(0),
61254721Semaste            min_inst_length(0),
62254721Semaste            default_is_stmt(0),
63254721Semaste            line_base(0),
64254721Semaste            line_range(0),
65254721Semaste            opcode_base(0),
66254721Semaste            standard_opcode_lengths(),
67254721Semaste            include_directories(),
68254721Semaste            file_names()
69254721Semaste        {
70254721Semaste        }
71254721Semaste
72254721Semaste        typedef std::shared_ptr<Prologue> shared_ptr;
73254721Semaste
74254721Semaste        uint32_t    total_length;   // The size in bytes of the statement information for this compilation unit (not including the total_length field itself).
75254721Semaste        uint16_t    version;        // Version identifier for the statement information format.
76254721Semaste        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.
77254721Semaste        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.
78254721Semaste        uint8_t     default_is_stmt;// The initial value of theis_stmtregister.
79254721Semaste        int8_t      line_base;      // This parameter affects the meaning of the special opcodes. See below.
80254721Semaste        uint8_t     line_range;     // This parameter affects the meaning of the special opcodes. See below.
81254721Semaste        uint8_t     opcode_base;    // The number assigned to the first special opcode.
82254721Semaste        std::vector<uint8_t>            standard_opcode_lengths;
83254721Semaste        std::vector<std::string>        include_directories;
84254721Semaste        std::vector<FileNameEntry>      file_names;
85254721Semaste
86254721Semaste        int32_t MaxLineIncrementForSpecialOpcode() const { return line_base + (int8_t)line_range - 1; }
87254721Semaste        bool IsValid() const;
88254721Semaste//      void Append(BinaryStreamBuf& buff) const;
89254721Semaste        void Dump (lldb_private::Log *log);
90254721Semaste        void Clear()
91254721Semaste        {
92254721Semaste            total_length = version = prologue_length = min_inst_length = line_base = line_range = opcode_base = 0;
93254721Semaste            line_base = 0;
94254721Semaste            standard_opcode_lengths.clear();
95254721Semaste            include_directories.clear();
96254721Semaste            file_names.clear();
97254721Semaste        }
98254721Semaste        bool GetFile(uint32_t file_idx, std::string& file, std::string& dir) const;
99254721Semaste
100254721Semaste    };
101254721Semaste
102254721Semaste    // Standard .debug_line state machine structure
103254721Semaste    struct Row
104254721Semaste    {
105254721Semaste        typedef std::vector<Row>            collection;
106254721Semaste        typedef collection::iterator        iterator;
107254721Semaste        typedef collection::const_iterator  const_iterator;
108254721Semaste
109254721Semaste        Row(bool default_is_stmt = false);
110254721Semaste        virtual ~Row() {}
111254721Semaste        void PostAppend ();
112254721Semaste        void Reset(bool default_is_stmt);
113254721Semaste        void Dump(lldb_private::Log *log) const;
114254721Semaste        static void Insert(Row::collection& state_coll, const Row& state);
115254721Semaste        static void Dump(lldb_private::Log *log, const Row::collection& state_coll);
116254721Semaste
117254721Semaste        dw_addr_t   address;        // The program-counter value corresponding to a machine instruction generated by the compiler.
118254721Semaste        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.
119254721Semaste        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.
120254721Semaste        uint16_t    file;           // An unsigned integer indicating the identity of the source file corresponding to a machine instruction.
121254721Semaste        uint8_t     is_stmt:1,      // A boolean indicating that the current instruction is the beginning of a statement.
122254721Semaste                    basic_block:1,  // A boolean indicating that the current instruction is the beginning of a basic block.
123254721Semaste                    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.
124254721Semaste                    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.
125254721Semaste                    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.
126254721Semaste        uint32_t    isa;            // An unsigned integer whose value encodes the applicable instruction set architecture for the current instruction.
127254721Semaste    };
128254721Semaste
129254721Semaste
130254721Semaste    //------------------------------------------------------------------
131254721Semaste    // LineTable
132254721Semaste    //------------------------------------------------------------------
133254721Semaste    struct LineTable
134254721Semaste    {
135254721Semaste        typedef std::shared_ptr<LineTable> shared_ptr;
136254721Semaste
137254721Semaste        LineTable() :
138254721Semaste            prologue(),
139254721Semaste            rows()
140254721Semaste        {
141254721Semaste        }
142254721Semaste
143254721Semaste        void AppendRow(const DWARFDebugLine::Row& state);
144254721Semaste        void Clear()
145254721Semaste        {
146254721Semaste            prologue.reset();
147254721Semaste            rows.clear();
148254721Semaste        }
149254721Semaste
150254721Semaste        uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
151254721Semaste        void Dump(lldb_private::Log *log) const;
152254721Semaste
153254721Semaste        Prologue::shared_ptr prologue;
154254721Semaste        Row::collection rows;
155254721Semaste    };
156254721Semaste
157254721Semaste    //------------------------------------------------------------------
158254721Semaste    // State
159254721Semaste    //------------------------------------------------------------------
160254721Semaste    struct State : public Row
161254721Semaste    {
162254721Semaste        typedef void (*Callback)(dw_offset_t offset, const State& state, void* userData);
163254721Semaste
164254721Semaste        // Special row codes used when calling the callback
165254721Semaste        enum
166254721Semaste        {
167254721Semaste            StartParsingLineTable = 0,
168254721Semaste            DoneParsingLineTable = -1
169254721Semaste        };
170254721Semaste
171254721Semaste        State (Prologue::shared_ptr& prologue_sp,
172254721Semaste               lldb_private::Log *log,
173254721Semaste               Callback callback,
174254721Semaste               void* userData);
175254721Semaste
176254721Semaste        void
177254721Semaste        AppendRowToMatrix (dw_offset_t offset);
178254721Semaste
179254721Semaste        void
180254721Semaste        Finalize (dw_offset_t offset);
181254721Semaste
182254721Semaste        void
183254721Semaste        Reset ();
184254721Semaste
185254721Semaste        Prologue::shared_ptr prologue;
186254721Semaste        lldb_private::Log *log;
187254721Semaste        Callback callback; // Callback function that gets called each time an entry is to be added to the matrix
188254721Semaste        void* callbackUserData;
189254721Semaste        int row; // The row number that starts at zero for the prologue, and increases for each row added to the matrix
190254721Semaste    private:
191254721Semaste        DISALLOW_COPY_AND_ASSIGN (State);
192254721Semaste    };
193254721Semaste
194254721Semaste    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
195254721Semaste    static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET);  // If line_offset is invalid, dump everything
196263363Semaste    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);
197263363Semaste    static bool ParsePrologue(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue);
198263363Semaste    static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, State::Callback callback, void* userData);
199263363Semaste    static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DWARFDataExtractor& debug_line_data, const dw_offset_t line_offset);
200263363Semaste    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);
201263363Semaste    static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table);
202263363Semaste    static void Parse(const lldb_private::DWARFDataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData);
203254721Semaste//  static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, const DWARFDebugLine::Row::collection& state_coll, const uint32_t addr_size, BinaryStreamBuf &debug_line_data);
204254721Semaste
205254721Semaste    DWARFDebugLine() :
206254721Semaste        m_lineTableMap()
207254721Semaste    {
208254721Semaste    }
209254721Semaste
210263363Semaste    void Parse(const lldb_private::DWARFDataExtractor& debug_line_data);
211263363Semaste    void ParseIfNeeded(const lldb_private::DWARFDataExtractor& debug_line_data);
212254721Semaste    LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
213254721Semaste
214254721Semasteprotected:
215254721Semaste    typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
216254721Semaste    typedef LineTableMap::iterator LineTableIter;
217254721Semaste    typedef LineTableMap::const_iterator LineTableConstIter;
218254721Semaste
219254721Semaste    LineTableMap m_lineTableMap;
220254721Semaste};
221254721Semaste
222254721Semaste#endif  // SymbolFileDWARF_DWARFDebugLine_h_
223