「Mach-O」とは Mac OS X におけるオブジェクトファイルのフォーマットのこと(LinuxにおけるELFみたいなもの)。詳しいことは apple.com のドキュメント「Mac OS X ABI Mach-O File Format Reference」にとても分かりやすく書いてある。
LinuxのELFなら readelf
や ldd
などでオブジェクトファイルを解析できる。一方、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 件のコメント:
コメントを投稿