2011年7月19日火曜日

Mach-Oファイル形式と、それにまつわるツール

「Mach-O」とは Mac OS X におけるオブジェクトファイルのフォーマットのこと(LinuxにおけるELFみたいなもの)。詳しいことは apple.com のドキュメント「Mac OS X ABI Mach-O File Format Reference」にとても分かりやすく書いてある。

LinuxのELFなら readelfldd などでオブジェクトファイルを解析できる。一方、Mach-O の場合はどうすればいいのだろうか。このあたり、実際に手を動かして調べたことを記録しておく。

Mach-Oフォーマットに関する雑感

  • ELFより分かりやすい気がする(とりあえず「プログラムヘッダ」「セクションヘッダ」のような二面性がない)
  • Mach header, load commands, segments, segments の中の sections で構成されている
  • segmentは6種類だけ(__PAGEZERO, __TEXT, __DATA, __OBJC, __IMPORT, __LINKEDIT)
  • segment と sections の名前は、それぞれ大文字、小文字で表す(命名規約)

otoolコマンド

Linuxの"readelf"みたいなコマンドで、Mach-Oの情報をフォーマットして出力してくれる。オプション-vで人間向けのシンボリックな表示になる。

Machヘッダ
$ otool -hv /bin/ls
/bin/ls:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    13       1928   NOUNDEFS DYLDLINK TWOLEVEL
__TEXTセグメントの中の __textセクション
$ otool -tv /bin/ls
/bin/ls:
(__TEXT,__text) section
0000000100001478 pushq $0x00
000000010000147a movq %rsp,%rbp
000000010000147d andq $0xf0,%rsp
(略)
__DATAセグメントの中の __dataセクション
$ otool -dv /bin/ls|head
/bin/ls:
(__DATA,__data) section
0000000100006540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0000000100006550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0000000100006560 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
(略)
共有ライブラリの依存関係。Linuxでの lddコマンドに相当
$ otool -Lv /bin/ls
/bin/ls:
 /usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
 time stamp 2 Thu Jan  1 09:00:02 1970
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0)
 time stamp 2 Thu Jan  1 09:00:02 1970

sizeコマンド

セグメントのサイズを表示してくれるコマンド。オプション無しなら __TEXT, __DATA, __OBJC, その他, 全体 を表示。オプション有り(-mなど)だと、すべてのセグメントについて表示。

オプションなし
$ size /bin/ls
__TEXT __DATA __OBJC others dec hex
24576 4096 0 4294979584 4295008256 10000a000
-m オプション
$ size -m /bin/ls
Segment __PAGEZERO: 4294967296
Segment __TEXT: 24576
 Section __text: 14575
 Section __symbol_stub1: 456
 Section __stub_helper: 776
 Section __cstring: 1199
 Section __const: 56
 Section __unwind_info: 188
 Section __eh_frame: 2072
 total 19322
Segment __DATA: 4096
 Section __nl_symbol_ptr: 56
 Section __la_symbol_ptr: 608
 Section __program_vars: 40
 Section __const: 600
 Section __data: 76
 Section __bss: 228
 Section __common: 140
 total 1748
Segment __LINKEDIT: 12288
total 4295008256

nmコマンド

Linuxでおなじみのコマンドだが(GNU の binutils に入ってる)、Macにも同じ名前のコマンドがあった。U, sなどのシンボルの意味はLinuxとだいたい一緒かな。

実行ファイルの場合
$ nm /bin/ls
                 U __DefaultRuneLocale
                 U ___assert_rtn
                 U ___error
(略)
共有ライブラリの場合
$ nm /usr/lib/libSystem.B.dylib
000000000014331a s  stub helpers
000000000017a1e6 S $ld$hide$os10.4$__Unwind_Backtrace
000000000017a1d0 S $ld$hide$os10.4$__Unwind_DeleteException
(略)

0 件のコメント:

コメントを投稿