■
どうも、えいだです!!VBプログラマに見下されるらしいです!!
参考: http://sevendegrees.blogspot.com/2006/08/blog-post_04.html
文書がわかりにくくなろうとならなかろうと、そういった、まあ、アレのナニであるよーつまり、世間の意見に惑わされてるようでは一流じゃねーとかそういった感じー。
あと、約170歳は約190歳の間違いであったので、お詫びして訂正しまる。
昨日のあらすじは、「Adaを勉強する前にPPCとMach-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とか、そういうあたりを調べれば出てくると思わるる。ので、各自調べて。
さて、ここで、驚くべき事実が明らかに!!OSXのgccはふとぅーに使うと、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ー