243 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			243 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 <string>
 | 
						|
#include <vector>
 | 
						|
 | 
						|
#include "lldb/lldb-private.h"
 | 
						|
 | 
						|
#include "DWARFDataExtractor.h"
 | 
						|
#include "DWARFDefines.h"
 | 
						|
 | 
						|
class SymbolFileDWARF;
 | 
						|
 | 
						|
//----------------------------------------------------------------------
 | 
						|
// DWARFDebugLine
 | 
						|
//----------------------------------------------------------------------
 | 
						|
class DWARFDebugLine {
 | 
						|
public:
 | 
						|
  //------------------------------------------------------------------
 | 
						|
  // FileNameEntry
 | 
						|
  //------------------------------------------------------------------
 | 
						|
  struct FileNameEntry {
 | 
						|
    FileNameEntry() : name(nullptr), dir_idx(0), mod_time(0), length(0) {}
 | 
						|
 | 
						|
    const char *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<const char *> 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, const char *comp_dir,
 | 
						|
                 lldb_private::FileSpec &file) 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_
 |