2016-04-25 18 views
0

DWARFから参照することで変数のアドレスを取得するにはどうすればよいですか?DWARFで参照を間接参照する方法

たとえば、我々は次の構造を有する:その後

struct sub_struct 
{ 
    int a, b; 
    sub_struct(int a, int b) : a(a), b(b) {} 
} 

struct main_struct 
{ 
    sub_struct & as_ref; 
    int c, d; 
    main_struct(sub_struct & ss) : as_ref(ss), c(0x100), d(0x101) {} 
} 

私たちは地球環境にこの構造体を初期化: test_inst.as_ref実際

sub_struct test_sub(0x10, 0x11); 
main_struct test_inst(sub_struct); 

は、構造体への参照を持つべきであるtest_sub。そして私はas_ref参照に格納されている変数の場所を取得したいと思います。

は、私はその後、私は自分の作成した構造体を取得します、コンパイルされたコードのドワーフファイルを読み込む場合:

Compilation Unit @ offset 0x1a80bf: 
    Length:  0x11e (32-bit) 
    Version:  3 
    Abbrev Offset: 0xd3e6 
    Pointer Size: 4 
<0><1a80ca>: Abbrev Number: 1 (DW_TAG_compile_unit) 
    <1a814d> DW_AT_stmt_list : 0x8e02a 
    <1a8151> DW_AT_macro_info : 0xc6fb 
<1><1a819b>: Abbrev Number: 3 (DW_TAG_variable) 
    <1a819c> DW_AT_name  : test_inst 
    <1a81ad> DW_AT_type  : <0x1a7643> 
    <1a81b6> DW_AT_location : 5 byte block: 3 50 6e ff 1f (DW_OP_addr: 1fff6e50) 
    <1a81bc> Unknown AT value: 2768: 1 
<1><1a81e0>: Abbrev Number: 0 

    Compilation Unit @ offset 0x1a829e: 
    Length:  0xb8 (32-bit) 
    Version:  3 
    Abbrev Offset: 0xd3e6 
    Pointer Size: 4 
<0><1a82a9>: Abbrev Number: 1 (DW_TAG_compile_unit) 
    <1a832c> DW_AT_stmt_list : 0x8e02a 
    <1a8330> DW_AT_macro_info : 0xc6fb 
<1><1a8334>: Abbrev Number: 3 (DW_TAG_variable) 
    <1a8335> DW_AT_name  : test_sub 
    <1a834a> DW_AT_type  : <0x1a761a> 
    <1a8352> DW_AT_location : 5 byte block: 3 48 7d ff 1f (DW_OP_addr: 1fff7d48) 
    <1a8358> Unknown AT value: 2768: 1 
<1><1a8359>: Abbrev Number: 0 

あなたは test_inst が0x1fff6e50アドレスに配置されて見ることができるように。 test_subは0x1fff6e48にあります。これは正しいです。私たちは、メモリを、確認したい場合:

  • test_sub.aは0x1fff6e48
  • test_sub.bに位置しています0x1fff6e4cに位置しています0x1fff6e50
  • test_inst.cに配置する必要があります
  • test_inst.as_refが配置されている
  • 0x1fff6e54
  • でtest_inst.dは私がのみを参照している場合、私は、手動で0x1fff6e48アドレスを見つける方法を知りたい0x1fff6e58

に位置していますas_refにあります。 main_structため

ドワーフ情報はこれです:タイプas_ref

<1><1a7643>: Abbrev Number: 40 (DW_TAG_structure_type) 
    <1a7644> DW_AT_sibling  : <0x1a76cf> 
    <1a7648> DW_AT_name  : test_struct 
    <1a7654> DW_AT_byte_size : 44 
<2><1a7655>: Abbrev Number: 44 (DW_TAG_member) 
    <1a7656> DW_AT_type  : <0x1a683a> 
    <1a7658> DW_AT_accessibility: 1 (public) 
    <1a7659> DW_AT_name  : as_ref 
    <1a7660> DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0) 
<2><1a7663>: Abbrev Number: 44 (DW_TAG_member) 
    <1a7664> DW_AT_type  : <0x1a6833> 
    <1a7666> DW_AT_accessibility: 1 (public) 
    <1a7667> DW_AT_name  : c 
    <1a7669> DW_AT_data_member_location: 2 byte block: 23 4 (DW_OP_plus_uconst: 4) 
<2><1a766c>: Abbrev Number: 44 (DW_TAG_member) 
    <1a766d> DW_AT_type  : <0x1a6833> 
    <1a766f> DW_AT_accessibility: 1 (public) 
    <1a7670> DW_AT_name  : d 
    <1a7672> DW_AT_data_member_location: 2 byte block: 23 8 (DW_OP_plus_uconst: 8) 
<2><1a76ce>: Abbrev Number: 0 

このへの参照である:

<1><1a683a>: Abbrev Number: 5 (DW_TAG_reference_type) 
<1a683b> DW_AT_type  : <0x1a761a> 

これにrereferenceされる:

<1><1a761a>: Abbrev Number: 40 (DW_TAG_structure_type) 
    <1a761b> DW_AT_sibling  : <0x1a7643> 
    <1a761f> DW_AT_name  : sub_struct 
    <1a762f> DW_AT_byte_size : 8 
<2><1a7630>: Abbrev Number: 44 (DW_TAG_member) 
    <1a7631> DW_AT_type  : <0x1a6833> 
    <1a7633> DW_AT_accessibility: 1 (public) 
    <1a7634> DW_AT_name  : a 
    <1a7636> DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0) 
<2><1a7639>: Abbrev Number: 44 (DW_TAG_member) 
    <1a763a> DW_AT_type  : <0x1a6833> 
    <1a763c> DW_AT_accessibility: 1 (public) 
    <1a763d> DW_AT_name  : b 
    <1a763f> DW_AT_data_member_location: 2 byte block: 23 4 (DW_OP_plus_uconst: 4) 
<2><1a7642>: Abbrev Number: 0 

答えて

1

TLDR:ポインタとリファレンス大統領は同じものだ。 as_refには、参照されたsub_structのアドレスが含まれています。これはas_refはに位置していることを示しています

は0(これ0x1fff6e50)オフセット:

<2><1a7655>: Abbrev Number: 44 (DW_TAG_member) 
    <1a7656> DW_AT_type  : <0x1a683a> 
    <1a7658> DW_AT_accessibility: 1 (public) 
    <1a7659> DW_AT_name  : as_ref 
    <1a7660> DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0) 

イッツタイプは次式で与えられます。それは別の型への参照です意味

<1><1a683a>: Abbrev Number: 5 (DW_TAG_reference_type) 
    <1a683b> DW_AT_type  : <0x1a761a> 

を。参照とポインタは同一のものです:彼らは別の変数のアドレスを含んでいます。別のプロセスから

void* main_struct_addr = 0x1fff6e50; // from DWARF 
std::uint64_t as_ref_offset = 0;  // from DWARF 
void* main_as_ref_addr = (char*) main_struct_addr + as_ref_offset; 
void as_addr = *(void**) main_a_ref_addr; 
assert(as_adddr == (void*) 0x1fff6e48); 

std::uint64_t main_struct_addr = 0x1fff6e50; // from DWARF 
std::uint64_t as_ref_offset = 0;    // from DWARF 
std::uint64_t main_as_ref_addr = main_struct_addr + as_ref_offset; 
errno = 0; 
void* as_addr = (void*) ptrace(PTRACE_PEEKDATA, pid, (void*) main_as_ref_addr, NULL); 
if (errno) { ... } 
assert(as_adddr == (void*) 0x1fff6e48); 
プロセス内