1

objdump ユーティリティを使用すると、変数の相対アドレスを取得できます。たとえば、単純な C プログラムを考えてみましょう。

#include<stdio.h>
void do_stuff(int my_arg){
    int my_local=my_arg+2;
    int i;
    for(i=0;i<my_local;i++)
        printf("i=%d\n",i);
}

int main(){
    do_stuff(2);
    return 0;
}

gcc でコンパイル:

$ gcc -g example.c -o example

ELF 情報については、dwarf フラグを指定して objdump ユーティリティを実行します。

$objdump --dwarf=info の例

出力:

Contents of the .debug_info section:

  Compilation Unit @ offset 0x0:
   Length:        0xd3 (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  8
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_producer    : (indirect string, offset: 0x0): GNU C 4.8.4 -mtune=generic -march=x86-64 -g -fstack-protector 
    <10>   DW_AT_language    : 1    (ANSI C)
    <11>   DW_AT_name        : (indirect string, offset: 0xcd): sample1.c   
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0x7e): /home/bernard/PhD/TEJAS/tejas_installation_kit/Tejas-Simulator/Tejas/benchmark  
    <19>   DW_AT_low_pc      : 0x40052d 
    <21>   DW_AT_high_pc     : 0x54 
    <29>   DW_AT_stmt_list   : 0x0  
 <1><2d>: Abbrev Number: 2 (DW_TAG_base_type)
    <2e>   DW_AT_byte_size   : 8    
    <2f>   DW_AT_encoding    : 7    (unsigned)
    <30>   DW_AT_name        : (indirect string, offset: 0x47): long unsigned int   
 <1><34>: Abbrev Number: 2 (DW_TAG_base_type)
    <35>   DW_AT_byte_size   : 1    
    <36>   DW_AT_encoding    : 8    (unsigned char)
    <37>   DW_AT_name        : (indirect string, offset: 0x62): unsigned char   
 <1><3b>: Abbrev Number: 2 (DW_TAG_base_type)
    <3c>   DW_AT_byte_size   : 2    
    <3d>   DW_AT_encoding    : 7    (unsigned)
    <3e>   DW_AT_name        : (indirect string, offset: 0xde): short unsigned int  
 <1><42>: Abbrev Number: 2 (DW_TAG_base_type)
    <43>   DW_AT_byte_size   : 4    
    <44>   DW_AT_encoding    : 7    (unsigned)
    <45>   DW_AT_name        : (indirect string, offset: 0x4c): unsigned int    
 <1><49>: Abbrev Number: 2 (DW_TAG_base_type)
    <4a>   DW_AT_byte_size   : 1    
    <4b>   DW_AT_encoding    : 6    (signed char)
    <4c>   DW_AT_name        : (indirect string, offset: 0x64): signed char 
 <1><50>: Abbrev Number: 2 (DW_TAG_base_type)
    <51>   DW_AT_byte_size   : 2    
    <52>   DW_AT_encoding    : 5    (signed)
    <53>   DW_AT_name        : (indirect string, offset: 0xf1): short int   
 <1><57>: Abbrev Number: 3 (DW_TAG_base_type)
    <58>   DW_AT_byte_size   : 4    
    <59>   DW_AT_encoding    : 5    (signed)
    <5a>   DW_AT_name        : int  
 <1><5e>: Abbrev Number: 2 (DW_TAG_base_type)
    <5f>   DW_AT_byte_size   : 8    
    <60>   DW_AT_encoding    : 5    (signed)
    <61>   DW_AT_name        : (indirect string, offset: 0x75): long int    
 <1><65>: Abbrev Number: 2 (DW_TAG_base_type)
    <66>   DW_AT_byte_size   : 8    
    <67>   DW_AT_encoding    : 7    (unsigned)
    <68>   DW_AT_name        : (indirect string, offset: 0xfb): sizetype    
 <1><6c>: Abbrev Number: 2 (DW_TAG_base_type)
    <6d>   DW_AT_byte_size   : 1    
    <6e>   DW_AT_encoding    : 6    (signed char)
    <6f>   DW_AT_name        : (indirect string, offset: 0x6b): char    
 <1><73>: Abbrev Number: 4 (DW_TAG_subprogram)
    <74>   DW_AT_external    : 1    
    <74>   DW_AT_name        : (indirect string, offset: 0x59): do_stuff    
    <78>   DW_AT_decl_file   : 1    
    <79>   DW_AT_decl_line   : 2    
    <7a>   DW_AT_prototyped  : 1    
    <7a>   DW_AT_low_pc      : 0x40052d 
    <82>   DW_AT_high_pc     : 0x3f 
    <8a>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <8c>   DW_AT_GNU_all_tail_call_sites: 1 
    <8c>   DW_AT_sibling     : <0xb9>   
 <2><90>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <91>   DW_AT_name        : (indirect string, offset: 0xd7): my_arg  
    <95>   DW_AT_decl_file   : 1    
    <96>   DW_AT_decl_line   : 2    
    <97>   DW_AT_type        : <0x57>   
    <9b>   DW_AT_location    : 2 byte block: 91 5c  (DW_OP_fbreg: -36)
 <2><9e>: Abbrev Number: 6 (DW_TAG_variable)
    <9f>   DW_AT_name        : (indirect string, offset: 0x3e): my_local    
    <a3>   DW_AT_decl_file   : 1    
    <a4>   DW_AT_decl_line   : 3    
    <a5>   DW_AT_type        : <0x57>   
    <a9>   DW_AT_location    : 2 byte block: 91 6c  (DW_OP_fbreg: -20)
 <2><ac>: Abbrev Number: 7 (DW_TAG_variable)
    <ad>   DW_AT_name        : i    
    <af>   DW_AT_decl_file   : 1    
    <b0>   DW_AT_decl_line   : 4    
    <b1>   DW_AT_type        : <0x57>   
    <b5>   DW_AT_location    : 2 byte block: 91 68  (DW_OP_fbreg: -24)
 <2><b8>: Abbrev Number: 0
 <1><b9>: Abbrev Number: 8 (DW_TAG_subprogram)
    <ba>   DW_AT_external    : 1    
    <ba>   DW_AT_name        : (indirect string, offset: 0x70): main    
    <be>   DW_AT_decl_file   : 1    
    <bf>   DW_AT_decl_line   : 9    
    <c0>   DW_AT_type        : <0x57>   
    <c4>   DW_AT_low_pc      : 0x40056c 
    <cc>   DW_AT_high_pc     : 0x15 
    <d4>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <d6>   DW_AT_GNU_all_tail_call_sites: 1 
 <1><d6>: Abbrev Number: 0

私は次のようにしたい: -

  1. my_local などの変数のアドレスを取得したい。最初に DW_TAG_Variable、次に DW_AT_name、上から関数 -20 でベース レジスタによって指定された DW_AT_location を調べます。

質問: 実行時にベース レジスタの内容を知るにはどうすればよいですか。PinTool を使用して実装できますか。

より広い意味での質問: dwarf と Pintool からの情報が与えられたメモリ内のアドレスへの変数 my_local マップが必要です。

前もって感謝します。

4

1 に答える 1