forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			224 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef SymbolFileDWARF_DWARFDebugLine_h_
 | |
| #define SymbolFileDWARF_DWARFDebugLine_h_
 | |
| 
 | |
| #include <map>
 | |
| #include <vector>
 | |
| #include <string>
 | |
| 
 | |
| #include "lldb/lldb-private.h"
 | |
| 
 | |
| #include "DWARFDataExtractor.h"
 | |
| #include "DWARFDefines.h"
 | |
| 
 | |
| class SymbolFileDWARF;
 | |
| class DWARFDebugInfoEntry;
 | |
| 
 | |
| //----------------------------------------------------------------------
 | |
| // DWARFDebugLine
 | |
| //----------------------------------------------------------------------
 | |
| class DWARFDebugLine
 | |
| {
 | |
| public:
 | |
|     //------------------------------------------------------------------
 | |
|     // FileNameEntry
 | |
|     //------------------------------------------------------------------
 | |
|     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;
 | |
| 
 | |
|     };
 | |
| 
 | |
|     //------------------------------------------------------------------
 | |
|     // 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.
 | |
|         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<std::string>        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, std::string& file, std::string& dir) 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);
 | |
|         static void Dump(lldb_private::Log *log, const Row::collection& state_coll);
 | |
| 
 | |
|         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;
 | |
|         void Dump(lldb_private::Log *log) 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 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
 | |
|     static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET);  // If line_offset is invalid, dump everything
 | |
|     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);
 | |
|     static bool ParsePrologue(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue);
 | |
|     static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, State::Callback callback, void* userData);
 | |
|     static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DWARFDataExtractor& debug_line_data, const dw_offset_t line_offset);
 | |
|     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);
 | |
|     static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table);
 | |
|     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_
 |