円でエンエンエン
MACバイナリーだどーーーんの巻き
前回までのあらすじ
秋葉原に行った岡夫婦、MACG3用のハードディスクを安価で買い上げ、OS−Xにして岡チャン30歳に贈呈。
さて、相変わらずの日本語です。今回はOS−Xの環境が手に入りましたので、カーボンのコンパイル結果であるところのバイナリMach-O(マッハ・オー)のファイルレイアウトに迫ってみましょう。もうめんどくさいんで結果をどうぞ。

みんな気になるマジックナンバーはMACH時代の名残を受けたFEED FACEです。ちなみにFEED FACEというのはこういうFACEのことです。


続いて続く__PAGEZERO, __TEXT,などの大文字がセグメント名、小文字で続くのがセクション名である
さて、恒例の検算のコーナーです。
ここにレイアウトがあるので、それとてらしあわせて結果を見ていくことにしましょう。
Specifies
general attributes of the file.
struct mach_header
{ unsigned long magic; cpu_type_t cputype; cpu_subtype_t cpusubtype; unsigned long filetype; unsigned long ncmds; unsigned long sizeofcmds; unsigned long flags;};/* Constant for the magic field of the mach_header */#define MH_MAGIC 0xfeedface /* the mach magic number */#define MH_CIGAM NXSwapInt(MH_MAGIC)
Unsigned Long はよいとして、その後に続くcpu_type_t、とかcpu_subtype_tの型が意味不明である。こういう場合は次に続くSegmentのフォーマットを見てみることにしてみたりもする。
struct segment_command
{ unsigned long cmd; /* LC_SEGMENT */ unsigned long cmdsize; /* includes sizeof section structs */ char segname[16]; /* segment name */ unsigned long vmaddr; /* memory address of this segment */ unsigned long vmsize; /* memory size of this segment */ unsigned long fileoff; /* file offset of this segment */ unsigned long filesize; /* amount to map from the file */ vm_prot_t maxprot; /* maximum VM protection */ vm_prot_t initprot; /* initial VM protection */ unsigned long nsects; /* number of sections in segment */ unsigned long flags; /* flags */}; 以上のことからセグメント分として当の__PAGEZEROが登場するまでに8バイトの空間が必要であることがわかる。しかしここでもよくわからないvm_prot_tとかいう型が登場するので、さらにその下のSectionのフォーマットを見ることにした。
struct section
{ char sectname[16]; /* name of this section */ char segname[16]; /* segment this section goes in */ unsigned long addr; /* memory address of this section */ unsigned long size; /* size in bytes of this section */ unsigned long offset; /* file offset of this section */ unsigned long align; /* section alignment (power of 2) */ unsigned long reloff; /* file offset of relocation entries */ unsigned long nreloc; /* number of relocation entries */ unsigned long flags; /* flags (section type and attributes)*/ unsigned long reserved1; /* reserved */ unsigned long reserved2; /* reserved */};
この場合はセクション名が先頭にきて次に所属するsegnameが16バイトついてくる。

この場合_PAGEZEROは特殊なセグメントらしいので、次の__TEXTセグメントを観察する。__text __TEXTとなっているところがセクションの始まりで、__TEXTとピンで書かれているのがセグメントの定義部だ。いろいろふまえて色づけしたのが上。
struct mach_header
{ unsigned long magic;0xFEEDFACE cpu_type_t cputype;0x12 cpu_subtype_t cpusubtype;0x00 unsigned long filetype;0x02 unsigned long ncmds;0x0E unsigned long sizeofcmds;0x06C0 unsigned long flags;0x85};
__PAGEZEROは読みがいがないなので __TEXTを見てみる
struct segment_command
{unsigned long cmd; /* LC_SEGMENT */ 0x01
unsigned long cmdsize; /* includes sizeof section structs */ 0x01D0
char segname[16]; /* segment name */ __TEXT
unsigned long vmaddr; /* memory address of this segment */ 0x0100
unsigned long vmsize; /* memory size of this segment */ 0x0100
unsigned long fileoff; /* file offset of this segment */ 0x0000
unsigned long filesize; /* amount to map from the file */ 0x0100
vm_prot_t maxprot; /* maximum VM protection */ 0x07
vm_prot_t initprot; /* initial VM protection */ 0x05
unsigned long nsects; /* number of sections in segment */ 0x06
unsigned long flags; /* flags */ 0x00
};struct section
{char sectname[16]; /* name of this section */__text
char segname[16]; /* segment this section goes in */__TEXT unsigned long addr; /* memory address of this section */0x191C unsigned long size; /* size in bytes of this section */0x03D8 unsigned long offset; /* file offset of this section */0x0910 unsigned long align; /* section alignment (power of 2) */0x0002 unsigned long reloff; /* file offset of relocation entries */0x0000 unsigned long nreloc; /* number of relocation entries */0x0000 unsigned long flags; /* flags (section type and attributes)*/08000400 unsigned long reserved1; /* reserved */ unsigned long reserved2; /* reserved */};