Mach-O Golf

http://shinh.skr.jp/binary/hello_macho.s

PPC で 248Byte 。でけええ。先人の作業を参考にしたりパクリつつ。特に作るプロセスは textEx を使わせていただいています。

http://d.hatena.ne.jp/shotaro_tsuji/20061220/1166610321

http://d.hatena.ne.jp/shotaro_tsuji/20061219/1166458799

http://jijixi.azito.com/cgi-bin/diary/index.rb?date=20061114#t

でかい理由は PPCレジスタが多すぎるから。まさかレジスタが多いことに不満を言う日が来るとは思わなかったよ。えーと何? 40本レジスタあるんだ。それでそれぞれの初期値指定しないといけないんだ、ふーんじゃあそれだけで 160B かい?というような。

otool -l でロードコマンドをダンプすると、

ux103$ otool -l a.out
a.out:
Load command 0
      cmd LC_SEGMENT
  cmdsize 44 Inconsistent size
  segname Hello, world!

   vmaddr 0x00000000
   vmsize 0x00001000
  fileoff 0
 filesize 244
  maxprot 0x00000007
 initprot 0x00000005
   nsects 176
    flags 0x1
 ... nsects の部分はオーバーラップしてるのでこっから壊れてる

セグメントの名前が "Hello, world!" 。あとレジスタ指定する空間にコードは埋めてます。結局、 28B の Mach-O ヘッダ、 44B (本来は56B指定しないといけないけど重ねた) の LC_SEGMENT ロードコマンド、最後に LC_UNIXTHREAD ロードコマンドがあるんだけど、これが計 176B 。最初の 16B がヘッダ、んで 160B のレジスタ指定する場所。その 160B に余裕でコード埋まるのでそれで終了。コード自体もレジスタの初期値入れられるとかで微妙に縮むので縮めてあります。

縮む方法があるとすると、 UNIXTHREAD 以外のもっと短いロードコマンドタイプがあるか調べてみるとか、 UNIXTHREAD と SEGMENT の順序入れ替えて重ねてみるとかかと思います。後者はちょっと実験してみた感じ無理な気がしましたが自信無し。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h