どうも、えいだです!!VBプログラマに見下されるらしいです!!
参考: http://sevendegrees.blogspot.com/2006/08/blog-post_04.html


文書がわかりにくくなろうとならなかろうと、そういった、まあ、アレのナニであるよーつまり、世間の意見に惑わされてるようでは一流じゃねーとかそういった感じー。
あと、約170歳は約190歳の間違いであったので、お詫びして訂正しまる。


昨日のあらすじは、「Adaを勉強する前にPPCMach-Oを勉強する必要があるですよ」っていう話。
というわけで、今日のえいだはMach-Oについて調べるのですもはやAda関係ぬー!!あだーー!!OSX界の西田亙に俺はなる!それは無理ですー!!


とみせかけて、調べなくても全部書いてあるのだったー!!あとは各自読むるとよいです。
http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachOTopics/Articles/dynamic_code.html

#include <stdio.h>
int main() {
  puts("a");
}

まず、こんなコードがあるとしまして、(とぅーどぅー:こういうのをAdaでさらっと書けるように)これをふとぅーにコンパイルすると

/Users/Ada/test/gcc$ gcc-4.1 main.c -O2 -S 
/Users/Ada/test/gcc$ cat main.s
	.machine ppc
	.cstring
	.align 2
LC0:
	.ascii "a?0"
	.text
	.align 2
	.globl _main
_main:
	mflr r0
	bcl 20,31,"L00000000001$pb"
"L00000000001$pb":
	stw r31,-4(r1)
	mflr r31
	mtlr r0
	addis r3,r31,ha16(LC0-"L00000000001$pb")
	lwz r31,-4(r1)
	la r3,lo16(LC0-"L00000000001$pb")(r3)
	b L_puts$stub
	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
	.align 5
L_puts$stub:
	.indirect_symbol _puts
	mflr r0
	bcl 20,31,"L00000000001$spb"
"L00000000001$spb":
	mflr r11
	addis r11,r11,ha16(L_puts$lazy_ptr-"L00000000001$spb")
	mtlr r0
	lwzu r12,lo16(L_puts$lazy_ptr-"L00000000001$spb")(r11)
	mtctr r12
	bctr
	.lazy_symbol_pointer
L_puts$lazy_ptr:
	.indirect_symbol _puts
	.long	dyld_stub_binding_helper
	.subsections_via_symbols

あっというまにこんなコードになります!すごい!全然読めぬ!嘘です。ちょっとだけ読めるようになりました。mflr と mtlr がリンクレジスタごにょごにょだってわかればよゆーです。


まず、これはややこすぅいーです!ダイナミックリンクしたコードを呼ぶように、Indirect function callしてるのと、自身のコードをPIC(Positioin Independent Code)にするためのコードが混ざってるからです!!

まず、基本的な知識として、

  • 共有ライブラリは、PICにして、呼ぶときは、Indirect function callするとよろしい
  • PICにしたりIndirect function callしたりするのはコストがかかるので、ただのアプリケーションプログラムはそういうことしないほうがよい

というのがあるまする。これらについては、ELFのPLTとか、GOTとか、PEのidataとか、そういうあたりを調べれば出てくると思わるる。ので、各自調べて。


さて、ここで、驚くべき事実が明らかに!!OSXgccはふとぅーに使うと、PICのコードを生成するんです!!なぜだぁーーー!
よーするに、無駄があるんです!無駄がーー!PICにしなくてよいです!なんか話がずれてきたーーー!


PICにしないほうほうは-mdynamic-no-picとかそんなの。

/Users/Ada/test/gcc$ gcc-4.1 main.c -O2 -S -mdynamic-no-pic
/Users/Ada/test/gcc$ cat main.s
	.machine ppc
	.cstring
	.align 2
LC0:
	.ascii "a?0"
	.text
	.align 2
	.globl _main
_main:
	lis r3,ha16(LC0)
	la r3,lo16(LC0)(r3)
	b L_puts$stub
	.section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16
	.align 4
L_puts$stub:
	.indirect_symbol _puts
	lis r11,ha16(L_puts$lazy_ptr)
	lwzu r12,lo16(L_puts$lazy_ptr)(r11)
	mtctr r12
	bctr
	.lazy_symbol_pointer
L_puts$lazy_ptr:
	.indirect_symbol _puts
	.long	dyld_stub_binding_helper
	.subsections_via_symbols

だいぶすっきりな感じでございまー。
おるるー昨日問題になってたpure_instructionsとかは
http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/index.html
ここを読めばわかるかもー。ただのセクションのフラグだー。(説明を省きすぎだー)S_ATTR_PURE_INSTRUCTIONSとかいうの。


さてさて、話がずれまくったので戻しますよ。
まず、共有ライブラリ…と思ったけど、なんか面倒になったのでいいやー。大体わかったし。


まとめ:
アプリケーションをコンパイルするときは -mdynamic-no-pic を付けましょう
参考: http://www.unsanity.org/archives/000044.php

明日はPPC…といきたいところだけど、諸事情で無理なのでAdaやるぜーAdaー