📄 dwarfutils.pas
字号:
//////////////////////////////////////////////////////////////////////
// //
// 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 + -