bitvisor.elf を objdump したらなんかおかしい時の対策


どうしてobjdump するの?

BitVisor で何か開発するときに,たまにバイナリファイルを逆アセンブルして,その結果を見たい時がある.
例えば,MMIO領域にあるレジスタの値が変わるまでwhileループで待つ,なんて処理はgccの最適化の餌食になりやすいので,こういう処理がちゃんとバイナリとして出力されてるかを確認したくなるときがある.

objdumpt すると...

上記の訳で,BitVisor を64bit マシン向けにビルドして,そのelfファイルをobjdump したりするのだが,なんだか妙なアセンブラが出力される.

例えばobjdump -S bitvisor.elf とすると,こんな感じものが混じってる.

$ 
                        printf ("%c", str[i]);
40153eab:       48                      dec    %eax
40153eac:       63 c3                   arpl   %ax,%bx
40153eae:       41                      inc    %ecx
40153eaf:       0f be 34 04             movsbl (%esp,%eax,1),%esi
40153eb3:       bf c3 f0 15 40          mov    $0x4015f0c3,%edi
40153eb8:       b8 00 00 00 00          mov    $0x0,%eax
40153ebd:       e8 05 2d fd ff          call   40126bc7 <printf>

arpl あたりがどうもおかしい.

なぜなぜどうして?

https://ja.wikipedia.org/wiki/X64 曰く

64ビットモードで再割り当てされたx86命令

  • ARPL (Adjust Requestor Privilege Level)命令は、64ビットモードでは、新しいMOVSXD命令になった。
  • 1バイトのINC, DEC命令は、64ビットモードでは、REXプリフィックスになった。一方、2バイトのINC, DEC命令は、64ビットモードでも使用可能である。
  • 64ビットモードで廃止されたLDS, LES命令は、のちにインテルによってAVX命令のVEXプリフィックスとして割り当てられた。VEXプリフィックスに続く2バイト目を32ビットモードでは未定義であった11xxxxxxという形式にすることにより、AVX命令は32ビットモードでも使用可能である。

( https://ja.wikipedia.org/wiki/X64 から引用)

とのこと.

どうも,バイナリファイルの情報が間違っているらしく,x86 32bit のアセンブラで解釈しているらしい.

ちゃんとしたアセンブラ見たい時はどうするの?

解決するには,Makefile のFORMATをいじればよい.

(2015/12/09 16:05(UTC+2:00)頃 hdk_2 様からのコメントの内容を反映)
解決するには,objdump に-m i386:x86-64 というオプションを付ければよいらしい.

objdump -m i386:x86-64 -S bitvisor.elf とすると,先ほどの箇所は以下のようになる.

                        printf ("%c", str[i]);
40153eab:       48 63 c3                movslq %ebx,%rax
40153eae:       41 0f be 34 04          movsbl (%r12,%rax,1),%esi
40153eb3:       bf c3 f0 15 40          mov    $0x4015f0c3,%edi
40153eb8:       b8 00 00 00 00          mov    $0x0,%eax
40153ebd:       e8 05 2d fd ff          callq  40126bc7 <printf>