Universal Binaryというものがあります。これは1つのバイナリの中に2つ以上の実行体が格納されたものです。32bit版と64bit版のバイナリを1つのファイルで配布することも出来るようになるので便利なシロモノです。Windowsもこういったものを採用してほしかったと思います。
この形式の場合次のようなヘッダがファイル先頭に付きます。
struct fat_header { uint32_t magic; // FAT_MAGIC uint32_t nfat_arch; }; struct fat_arch { uint32_t cputype; uint32_t cpusubtype; uint32_t offset; uint32_t size; uint32_t align; }; #define FAT_MAGIC (0xcafebabeU) #define FAT_CIGAM (0xbebafecaU)
構造としては fat_headerが出現し、nfat_archの個数分だけfat_arch構造体が後続します。fat_arch構造体にあるoffsetの位置からmach_headerやmach_header_64が出現します。
手元で試してみたところ、ファイルマジックは FAT_CIGAM のほうで出現し、この構造体の他のメンバについてはエンディアン反転する必要がありました。後続のmachヘッダ部分でのMH_MAGIC/MH_MAGIC_64についてはそのままだったのでひっくり返す必要はありませんでした。
この差がちょっと不思議な感じです。
今までのコードはマジック値をそのままチェックしていましたが、今回の件でわかるようにエンディアンが逆の場合でも読めるように直さないといけないなと感じました。