Go to main content
Oracle® Solaris 11.3 リンカーとライブラリガイド

印刷ビューの終了

更新: 2015 年 10 月
 
 

elfdump を使用したファイルの解析

ELF ファイルの内容を解析するために、標準の UNIX ユーティリティー dump(1)nm(1)size(1) など、さまざまなツールが使用できます。Oracle Solaris では、これらのツールは大部分が elfdump(1) に置き換えられました。

以降のセクションで説明するさまざまなパフォーマンスの問題を調べるには、eldump を使用して ELF オブジェクトの内容を診断すると役に立つことがあります。

ELF 形式では、データがセクションにまとめられます。次に、セクションはセグメントと呼ばれる単位に割り当てられます。セグメントには、ファイルの一部がどのようにメモリーにマップされるかが記述されます。mmapobj(2) を参照してください。これらの読み込み可能セグメントは、elfdump(1) コマンドを使用して PT_LOAD エントリを調べることによって表示できます。

$ elfdump -p -NPT_LOAD libfoo.so.1
Program Header[0]:
    p_vaddr:      0           p_flags:    [ PF_X PF_R ]
    p_paddr:      0           p_type:     [ PT_LOAD ]
    p_filesz:     0x53c       p_memsz:    0x53c
    p_offset:     0           p_align:    0x10000

Program Header[1]:
    p_vaddr:      0x1053c     p_flags:    [ PF_X PF_W PF_R ]
    p_paddr:      0           p_type:     [ PT_LOAD ]
    p_filesz:     0x114       p_memsz:    0x13c
    p_offset:     0x53c       p_align:    0x10000

共有オブジェクト libfoo.so.1 には、一般に「テキスト」セグメントおよび「データ」セグメントと呼ばれる 2 つの読み込み可能なセグメントがあります。テキストセグメントがマップされ、その内容 (PF_XPF_R) の読み込みと実行が可能になります。データセグメントもマップされ、その内容 PF_W が変更できるようになります。データセグメントのメモリーサイズ (p_memsz) は、ファイルサイズ (p_filesz) とは異なります。この違いは、データセグメントの一部であり、セグメントが読み込まれると動的に作成される .bss セクションを示すものです。

プログラマがファイルについて考えるとき、多くの場合、そのコード内の関数とデータ要素を定義するシンボルの点から考えます。これらのシンボルは、elfdump–s オプションを使用すると表示できます。

$ elfdump -sN.symtab libfoo.so.1

Symbol Table Section:  .symtab
   index    value     size  type bind oth ver shndx          name
    ....
    [36]  0x10628     0x28  OBJT GLOB  D    0 .data          data
    ....
    [38]  0x10650     0x28  OBJT GLOB  D    0 .bss           bss
    ....
    [40]    0x520      0xc  FUNC GLOB  D    0 .init          _init
    ....
    [44]    0x508     0x14  FUNC GLOB  D    0 .text          foo
    .... 
    [46]    0x52c      0xc  FUNC GLOB  D    0 .fini          _fini

elfdump で表示されるシンボルテーブル情報には、シンボルに関連するセクションが含まれます。elfdump–c オプションを使用すると、これらのセクションに関する情報を表示できます。

$ elfdump -c libfoo.so.1
....
Section Header[6]:  sh_name: .text
    sh_addr:      0x4f8           sh_flags:   [ SHF_ALLOC SHF_EXECINSTR ]
    sh_size:      0x28            sh_type:    [ SHT_PROGBITS ]
    sh_offset:    0x4f8           sh_entsize: 0
    sh_link:      0               sh_info:    0
    sh_addralign: 0x8

Section Header[7]:  sh_name: .init
    sh_addr:      0x520           sh_flags:   [ SHF_ALLOC SHF_EXECINSTR ]
    sh_size:      0xc             sh_type:    [ SHT_PROGBITS ]
    sh_offset:    0x520           sh_entsize: 0
    sh_link:      0               sh_info:    0
    sh_addralign: 0x4

Section Header[8]:  sh_name: .fini
    sh_addr:      0x52c           sh_flags:   [ SHF_ALLOC SHF_EXECINSTR ]
    sh_size:      0xc             sh_type:    [ SHT_PROGBITS ]
    sh_offset:    0x52c           sh_entsize: 0
    sh_link:      0               sh_info:    0
    sh_addralign: 0x4
....
Section Header[12]:  sh_name: .data
   sh_addr:      0x10628         sh_flags:   [ SHF_WRITE SHF_ALLOC ]
   sh_size:      0x28            sh_type:    [ SHT_PROGBITS ]
   sh_offset:    0x628           sh_entsize: 0
   sh_link:      0               sh_info:    0
   sh_addralign: 0x4
....
Section Header[14]:  sh_name: .bss
   sh_addr:      0x10650         sh_flags:   [ SHF_WRITE SHF_ALLOC ]
   sh_size:      0x28            sh_type:    [ SHT_NOBITS ]
   sh_offset:    0x650           sh_entsize: 0
   sh_link:      0               sh_info:    0
   sh_addralign: 0x4
....

上記の例の elfdump(1) からの出力は、関数 _initfoo、および _fini と、セクション .init.text、および .fini との関連を示します。これらのセクションは読み取り専用であるため、「テキスト」セグメントの一部です。

同様に、データ配列 databss は、それぞれセクション .data.bss に関連付けられています。これらのセクションは書き込み可能であるため、「データ」セグメントの一部です。