⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dwarfutils.pas

📁 一个不出名的GBA模拟器
💻 PAS
📖 第 1 页 / 共 4 页
字号:
//////////////////////////////////////////////////////////////////////
//                                                                  //
// dwarfUtils.pas: DWARF debugging backend support                  //
//                                                                  //
// The contents of this file are subject to the Bottled Light       //
// Public License Version 1.0 (the "License"); you may not use this //
// file except in compliance with the License. You may obtain a     //
// copy of the License at http://www.bottledlight.com/BLPL/         //
//                                                                  //
// Software distributed under the License is distributed on an      //
// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or   //
// implied. See the License for the specific language governing     //
// rights and limitations under the License.                        //
//                                                                  //
// The Original Code is the Mappy VM User Interface, released       //
// April 1st, 2003. The Initial Developer of the Original Code is   //
// Bottled Light, Inc. Portions created by Bottled Light, Inc. are  //
// Copyright (C) 2001-2003 Bottled Light, Inc. All Rights Reserved. //
//                                                                  //
// Author(s):                                                       //
//   Michael Noland (joat), michael@bottledlight.com                //
//                                                                  //
// Changelog:                                                       //
//   1.0: First public release (April 1st, 2003)                    //
//                                                                  //
// Notes:                                                           //
//   Welcome to hell my friends.  For more info, see the DWARF 2    //
//   specification PDF.                                             //
//                                                                  //
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
unit dwarfUtils; /////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
interface ////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

uses
  Classes, SysUtils, Contnrs, Math, elfUtils,
  nexus, console, AddressSpace;

//////////////////////////////////////////////////////////////////////

function DwarfFormToString(form: uint32): string;
function DwarfAttributeToString(attrib: uint32): string;
function DwarfTagToString(tag: uint32): string;
function dwarfLookupVal(cmd: string): string;

//////////////////////////////////////////////////////////////////////

const
  // DWARF Attribute Tags
  DW_TAG_null = $00;
  DW_TAG_array_type = $01;
  DW_TAG_class_type = $02;
  DW_TAG_entry_point = $03;
  DW_TAG_enumeration_type = $04;
  DW_TAG_formal_parameter = $05;
  DW_TAG_imported_declaration = $08;
  DW_TAG_label = $0A;
  DW_TAG_lexical_block = $0B;
  DW_TAG_member = $0D;
  DW_TAG_pointer_type = $0F;
  DW_TAG_reference_type = $10;
  DW_TAG_compile_unit = $11;
  DW_TAG_string_type = $12;
  DW_TAG_structure_type = $13;
  DW_TAG_subroutine_type = $15;
  DW_TAG_typedef = $16;
  DW_TAG_union_type = $17;
  DW_TAG_unspecified_parameters = $18;
  DW_TAG_variant = $19;
  DW_TAG_common_block = $1A;
  DW_TAG_common_inclusion = $1B;
  DW_TAG_inheritance = $1C;
  DW_TAG_inlined_subroutine = $1D;
  DW_TAG_module = $1E;
  DW_TAG_ptr_to_member_type = $1F;
  DW_TAG_set_type = $20;
  DW_TAG_subrange_type = $21;
  DW_TAG_with_stmt = $22;
  DW_TAG_access_declaration = $23;
  DW_TAG_base_type = $24;
  DW_TAG_catch_block = $25;
  DW_TAG_const_type = $26;
  DW_TAG_constant = $27;
  DW_TAG_enumerator = $28;
  DW_TAG_file_type = $29;
  DW_TAG_friend = $2A;
  DW_TAG_namelist = $2B;
  DW_TAG_namelist_item = $2C;
  DW_TAG_packed_type = $2D;
  DW_TAG_subprogram = $2E;
  DW_TAG_template_type_param = $2F;
  DW_TAG_template_value_param = $30;
  DW_TAG_thrown_type = $31;
  DW_TAG_try_block = $32;
  DW_TAG_variant_part = $33;
  DW_TAG_variable = $34;
  DW_TAG_volatile_type = $35;
  DW_TAG_lo_user = $4080;
  DW_TAG_hi_user = $FFFF;

  //
  DW_CHILDREN_no = 0;
  DW_CHILDREN_yes = 1;

  DW_AT_sibling = $01;               // reference
  DW_AT_location = $02;              // block, constant
  DW_AT_name = $03;                  // string
  DW_AT_ordering = $09;              // constant
  DW_AT_byte_size = $0B;             // constant
  DW_AT_bit_offset = $0C;            // constant
  DW_AT_bit_size = $0D;              // constant
  DW_AT_stmt_list = $10;             // constant
  DW_AT_low_pc = $11;                // address
  DW_AT_high_pc = $12;               // address
  DW_AT_language = $13;              // constant
  DW_AT_discr = $15;                 // reference
  DW_AT_discr_value = $16;           // constant
  DW_AT_visibility = $17;            // constant
  DW_AT_import = $18;                // reference
  DW_AT_string_length = $19;         // block, constant
  DW_AT_common_reference = $1A;      // reference
  DW_AT_comp_dir = $1B;              // string
  DW_AT_const_value = $1C;           // string, constant, block
  DW_AT_containing_type = $1D;       // reference
  DW_AT_default_value = $1E;         // reference
  DW_AT_inline = $20;                // constant
  DW_AT_is_optional = $21;           // flag
  DW_AT_lower_bound = $22;           // constant, reference
  DW_AT_producer = $25;              // string
  DW_AT_prototyped = $27;            // flag
  DW_AT_return_addr = $2A;           // block, constant
  DW_AT_start_scope = $2C;           // constant
  DW_AT_stride_size = $2E;           // constant
  DW_AT_upper_bound = $2F;           // constant, reference
  DW_AT_abstract_origin = $31;       // reference
  DW_AT_accessibility = $32;         // constant
  DW_AT_address_class = $33;         // constant
  DW_AT_artificial = $34;            // flag
  DW_AT_base_types = $35;            // reference
  DW_AT_calling_convention = $36;    // constant
  DW_AT_count = $37;                 // constant, reference
  DW_AT_data_member_location = $38;  // block, reference
  DW_AT_decl_column = $39;           // constant
  DW_AT_decl_file = $3A;             // constant
  DW_AT_decl_line = $3B;             // constant
  DW_AT_declaration = $3C;           // flag
  DW_AT_discr_list = $3D;            // block
  DW_AT_encoding = $3E;              // constant
  DW_AT_external = $3F;              // flag
  DW_AT_frame_base = $40;            // block, constant
  DW_AT_friend = $41;                // reference
  DW_AT_identifier_case = $42;       // constant
  DW_AT_macro_info = $43;            // constant
  DW_AT_namelist_item = $44;         // block
  DW_AT_priority = $45;              // reference
  DW_AT_segment = $46;               // block, constant
  DW_AT_specification = $47;         // reference
  DW_AT_static_link = $48;           // block, constant
  DW_AT_type = $49;                  // reference
  DW_AT_use_location = $4A;          // block, constant
  DW_AT_variable_parameter = $4B;    // flag
  DW_AT_virtuality = $4C;            // constant
  DW_AT_vtable_elem_location = $4D;  // block, reference

  // ARM Compiler extensions
  DW_AT_proc_body = $2000;
  DW_AT_save_offset = $2001;
  DW_AT_codeseg_base = $2002;

  // MIPS extensions
  DW_AT_MIPS_linkage_name = $2007;

  DW_AT_lo_user = $2000;
  DW_AT_hi_user = $3FFF;

  // DWARF data attribute formats
  DW_FORM_addr = $01;       // address
  DW_FORM_block2 = $03;     // block
  DW_FORM_block4 = $04;     // block
  DW_FORM_data2 = $05;      // constant
  DW_FORM_data4 = $06;      // constant
  DW_FORM_data8 = $07;      // constant
  DW_FORM_string = $08;     // string (null term string)
  DW_FORM_block = $09;      // block
  DW_FORM_block1 = $0A;     // block
  DW_FORM_data1 = $0B;      // constant
  DW_FORM_flag = $0C;       // flag
  DW_FORM_sdata = $0D;      // constant
  DW_FORM_strp = $0E;       // string (offset into .debug_str)
  DW_FORM_udata = $0F;      // constant
  DW_FORM_ref_addr = $10;   // reference
  DW_FORM_ref1 = $11;       // reference
  DW_FORM_ref2 = $12;       // reference
  DW_FORM_ref4 = $13;       // reference
  DW_FORM_ref8 = $14;       // reference
  DW_FORM_ref_udata = $15;  // reference
  DW_FORM_indirect = $16;   // (see section 7.5.3)

  // DWARF location stack machine opcodes (the comments indicate operands)
  DW_OP_addr = $03;         // constant address (size target specific)
  DW_OP_deref = $06;
  DW_OP_const1u = $08;      // 1-byte constant
  DW_OP_const1s = $09;      // 1-byte constant
  DW_OP_const2u = $0A;      // 2-byte constant
  DW_OP_const2s = $0B;      // 2-byte constant
  DW_OP_const4u = $0C;      // 4-byte constant
  DW_OP_const4s = $0D;      // 4-byte constant
  DW_OP_const8u = $0E;      // 8-byte constant
  DW_OP_const8s = $0F;      // 8-byte constant
  DW_OP_constu = $10;       // ULEB128 constant
  DW_OP_consts = $11;       // SLEB128 constant
  DW_OP_dup = $12;
  DW_OP_drop = $13;
  DW_OP_over = $14;
  DW_OP_pick = $15;         // 1 1-byte stack index
  DW_OP_swap = $16;
  DW_OP_rot = $17;
  DW_OP_xderef = $18;
  DW_OP_abs = $19;
  DW_OP_and = $1A;
  DW_OP_div = $1B;
  DW_OP_minus = $1C;
  DW_OP_mod = $1D;
  DW_OP_mul = $1E;
  DW_OP_neg = $1F;
  DW_OP_not = $20;
  DW_OP_or = $21;
  DW_OP_plus = $22;
  DW_OP_plus_uconst = $23;  // ULEB128 addend
  DW_OP_shl = $24;
  DW_OP_shr = $25;
  DW_OP_shra = $26;
  DW_OP_xor = $27;
  DW_OP_bra = $28;          // signed 2-byte constant
  DW_OP_eq = $29;
  DW_OP_ge = $2A;
  DW_OP_gt = $2B;
  DW_OP_le = $2C;
  DW_OP_lt = $2D;
  DW_OP_ne = $2E;
  DW_OP_skip = $2F;         // signed 2-byte constant
  DW_OP_lit0 = $30;
  DW_OP_lit31 = $4F;
  DW_OP_reg0 = $50;
  DW_OP_reg31 = $6F;
  DW_OP_breg0 = $70;        // SLEB128 offset
  DW_OP_breg31 = $8F;
  DW_OP_regx = $90;         // ULEB128 register
  DW_OP_fbreg = $91;        // SLEB128 offset
  DW_OP_bregx = $92;        // ULEB128 register followed by SLEB128 offset
  DW_OP_piece = $93;        // ULEB128 size of piece addressed
  DW_OP_deref_size = $94;   // 1-byte size of data retrieved
  DW_OP_xderef_size = $95;  // 1-byte size of data retrieved
  DW_OP_nop = $96;
  DW_OP_lo_user = $E0;
  DW_OP_hi_user = $FF;

  // DWARF simple types
  DW_ATE_address = $1;
  DW_ATE_boolean = $2;
  DW_ATE_complex_float = $3;
  DW_ATE_float = $4;
  DW_ATE_signed = $5;
  DW_ATE_signed_char = $6;
  DW_ATE_unsigned = $7;
  DW_ATE_unsigned_char = $8;
  DW_ATE_lo_user = $80;
  DW_ATE_hi_user = $FF;

  // DWARF access types
  DW_ACCESS_public = 1;
  DW_ACCESS_protected = 2;
  DW_ACCESS_private = 3;

  // Visibility code name
  DW_VIS_local = 1;
  DW_VIS_exported = 2;
  DW_VIS_qualified = 3;

  // Virtuality code name
  DW_VIRTUALITY_none = 0;
  DW_VIRTUALITY_virtual = 1;
  DW_VIRTUALITY_pure_virtual = 2;

  // DWARF Language Constants
  DW_LANG_C89 =         $0001;
  DW_LANG_C =           $0002;
  DW_LANG_Ada83 =       $0003;
  DW_LANG_C_plus_plus = $0004;
  DW_LANG_Cobol74 =     $0005;
  DW_LANG_Cobol85 =     $0006;
  DW_LANG_Fortran77 =   $0007;
  DW_LANG_Fortran90 =   $0008;
  DW_LANG_Pascal83 =    $0009;
  DW_LANG_Modula2 =     $000A;
  DW_LANG_lo_user =     $8000;
  DW_LANG_hi_user =     $FFFF;

  // DWARF identifier case sensitivity mode
  DW_ID_case_sensitive = 0;
  DW_ID_up_case = 1;
  DW_ID_down_case = 2;
  DW_ID_case_insensitive = 3;

  DW_CC_normal = $1;
  DW_CC_program = $2;
  DW_CC_nocall = $3;
  DW_CC_lo_user = $40;
  DW_CC_hi_user = $ff;

  DW_INL_not_inlined = 0;
  DW_INL_inlined = 1;
  DW_INL_declared_not_inlined = 2;
  DW_INL_declared_inlined = 3;

  DW_ORD_row_major = 0;
  DW_ORD_col_major = 1;

  DW_DSC_label = 0;
  DW_DSC_range = 1;


  // Statement program opcodes
  DW_LNS_extended_opcode = 0;
  DW_LNS_copy = 1;
  DW_LNS_advance_pc = 2;
  DW_LNS_advance_line = 3;
  DW_LNS_set_file = 4;
  DW_LNS_set_column = 5;
  DW_LNS_negate_stmt = 6;
  DW_LNS_set_basic_block = 7;
  DW_LNS_const_add_pc = 8;
  DW_LNS_fixed_advance_pc = 9;

  // Extended opcodes
  DW_LNE_end_sequence = 1;
  DW_LNE_set_address = 2;
  DW_LNE_define_file = 3;

  DW_MACINFO_define = 1;
  DW_MACINFO_undef = 2;
  DW_MACINFO_start_file = 3;
  DW_MACINFO_end_file = 4;
  DW_MACINFO_vendor_ext = 255;

  DW_CFA_advance_loc = $1;       // delta
  DW_CFA_offset = $2;            // register ULEB128 offset
  DW_CFA_restore = $3;           // register

  DW_CFA_set_loc = $1;           // address
  DW_CFA_advance_loc1 = $2;      // 1-byte delta
  DW_CFA_advance_loc2 = $3;      // 2-byte delta
  DW_CFA_advance_loc4 = $4;      // 4-byte delta
  DW_CFA_offset_extended = $5;   // ULEB128 register ULEB128 offset
  DW_CFA_restore_extended = $6;  // ULEB128 register
  DW_CFA_undefined = $7;         // ULEB128 register
  DW_CFA_same_value = $8;        // ULEB128 register
  DW_CFA_register = $9;          // ULEB128 register ULEB128 register
  DW_CFA_remember_state = $A;
  DW_CFA_restore_state = $B;
  DW_CFA_def_cfa = $C;           // ULEB128 register ULEB128 offset
  DW_CFA_def_cfa_register = $D;  // ULEB128 register
  DW_CFA_def_cfa_offset = $E;    // ULEB128 offset
  DW_CFA_nop = $0;
  DW_CFA_lo_user = $1C;
  DW_CFA_hi_user = $3F;

//////////////////////////////////////////////////////////////////////

type
  TDwarfBlock = record
    size: integer;
    data: pointer;
  end;

  PDwarfAttribute = ^TDwarfAttribute;
  TDwarfAttribute = record
    name: uint32;
    next: PDwarfAttribute;
    case format: uint32 of
      DW_FORM_addr: (address: uint32);
      DW_FORM_block, DW_FORM_block1, DW_FORM_block2, DW_FORM_block4: (block: TDwarfBlock);
      DW_FORM_sdata, DW_FORM_udata, DW_FORM_data1, DW_FORM_data2, DW_FORM_data4, DW_FORM_data8: (data: uint32);
      DW_FORM_string, DW_FORM_strp: (st: PChar);
      DW_FORM_flag: (flag: boolean);
      DW_FORM_ref_addr, DW_FORM_ref_udata, DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8: (offset: uint32);
  end;

  PDwarfNode = ^TDwarfNode;
  TDwarfNode = record
    abbreviation, tag: uint32;
    hasChildren: boolean;
    next, kids: PDwarfNode;
    attribs: PDwarfAttribute;
  end;
  PPDwarfNode = ^PDwarfNode;

//////////////////////////////////////////////////////////////////////

  TCompilationUnit = class
    unitLength: uint32;       // length of the contribution to the .debug_info section, not including the length field
    producerVersion: uint16;  // version of the DWARF producer, should be 2
    abbrevOffset: uint32;     // offset into the .debug_abbrev section
    addressSize: uint8;       // size in bytes of an address on the target (is the offset portion of a segmented arch)

    rootNode: PDwarfNode;
    macroOffset: uint32;
    lowPC, highPC: uint32;
    lang: uint32;

    // Misc. lists for quick use
    functions, types, classes, variables: TStringList;

    // Stuff for the statement program
    statementOffset, rStatementOffset: uint32;
    dirs, files: TStringList;

    constructor Create;
    destructor Destroy; override;
  end;

//////////////////////////////////////////////////////////////////////

  TPubnamesUnitHeader = packed record
    length: uint32;   // length of the contribution to the .debug_pubnames section, not including the lengthfield
    version: uint16;  // version of the DWARF producer, should be 2
    offset: uint32;   // offset of the information in .debug_info for this compilation unit
    size: uint32;     // size in bytes of the information in .debug_info for this compilation unit
  end;

  TARangesUnitHeader = packed record
    length: uint32;   // length of the contribution to the .debug_arranges section, not including the length field
    version: uint16;  // version of the DWARF producer, should be 2
    offseet: uint32;  // offset into the .debug_info section
    addrSize: uint8;  // size in bytes of an address on the target (is the offset portion of a segmented arch)
    segSize: uint8;   // size in bytes of a segment descriptor on the target
  end;

  TARangeTuple = packed record
    start, size: uint32;
  end;
  TARangeTuples = array[0..0] of TARangeTuple;
  PARangeTuples = ^TARangeTuples;

  TARangeData = record
    count: integer;
    data: PARangeTuples;
  end;

  TDwarfStatementPrologue = packed record
    totalLength: uint32;
    version: uint16;
    prologueLength: uint32;
    minInstructionLength: uint8;
    defaultIsStatement: uint8;
    lineBase: int8;
    lineRange: uint8;
    opcodeBase: uint8;
    // variable sized data follows
  end;

  TDwarfFile = class
    compUnits: TObjectList;
    baseDir: string;
    varList: TStringList;
    procedure DestroyNode(node: PDwarfNode);
    destructor Destroy; override;
    constructor Create;
    function FindContainingUnit(address: uint32): TCompilationUnit;
  end;

  TLineHit = record
    line, column: uint32;
    endSequence, isStatement, basicBlock: boolean;
    filename: string;
  end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -