正直日記



2008/03/05

_ 4.3-20080228版 devkitARM を作りなおしてみる(4)
続きです。

ひょっとして ld で section overlap する問題と objcopy で ROM イメージが
肥大化する問題の原因は一緒なのでは?と思っていたがどうやら違うようだ、と
思っていたのだが、どうやら、やはり根本の原因は同じようだ。

実は、ld 2.18 で OVERLAY の挙動も変わっていたらしい。


ここからは僕の妄想なので例によって読まなくていいです。

--

NEWS から引用しようと思ったら載ってなかった。まだ undocumented かしら。
ついでなので LMA のところを引用しておこう。

* The default output section LMA has changed for allocatable sections from being equal to VMA, to keeping the difference between LMA and VMA the same as the previous output section in the same region. This is a more useful default when using overlays and other cases where you specify an LMA differing from the VMA for some sections.
今からすれば、最初にこれを読んでおけば良かったんだよね。まぁ読んでいても たぶん何のことか分からなかったと思うけど。 OVERLAY に話を戻すと、リンカスクリプトでは以下のように記述されている。
OVERLAY ALIGN(4) : NOCROSSREFS AT (__iwram_overlay_lma) { .iwram0 { *(.iwram0) . = ALIGN(4);} .iwram1 { *(.iwram1) . = ALIGN(4);} .iwram2 { *(.iwram2) . = ALIGN(4);} .iwram3 { *(.iwram3) . = ALIGN(4);} .iwram4 { *(.iwram4) . = ALIGN(4);} .iwram5 { *(.iwram5) . = ALIGN(4);} .iwram6 { *(.iwram6) . = ALIGN(4);} .iwram7 { *(.iwram7) . = ALIGN(4);} .iwram8 { *(.iwram8) . = ALIGN(4);} .iwram9 { *(.iwram9) . = ALIGN(4);} }>iwram = 0xff __ewram_lma = __load_stop_iwram9;
ld 2.17 までは、リンクすると下記のように、いちいち全てのセクションに対し て __load_stop_HOGE が出力されていた。
08000468 A __load_stop_iwram0 08000468 A __load_stop_iwram1 08000468 A __load_stop_iwram2 08000468 A __load_stop_iwram3 08000468 A __load_stop_iwram4 08000468 A __load_stop_iwram5 08000468 A __load_stop_iwram6 08000468 A __load_stop_iwram7 08000468 A __load_stop_iwram8 08000468 A __load_stop_iwram9
だが、ld 2.18 の吐いた map ファイルを見てみると、これしか出力されてない。
08000454 A __load_stop_iwram0
で、__ewram_lma に __load_stop_iwram9 を代入しようとしているのだが、存在 しないのでとりあえず現在地を代入している。のかしら、ちょっと分からんけど。 存在しない場所を指していたらエラーか、せめてワーニング吐いて欲しいよなぁ。
03000054 A __ewram_lma
とにかく、結果的にこいつが RAM 領域を指すようになったせいで、objcopy が RAM 領域から ROM 領域に至るまでを吐くようになったらしい。__ewram_lma か ら ROM 終端アドレスまでのサイズを計算してみたら、バイナリサイズとピッタ リ合致した。やった!やったよママン! というわけでリンカスクリプトを修正することで ld に起因する問題はおおよそ 解決したよ。俺たちの戦いはこれからだ! (これにて ld 2.18 編は終わります。柏先生の次回作にご期待ください)
_ 4.3-20080228版 devkitARM を作りなおしてみる(3)
ひょっとして ld で section overlap する問題と objcopy で ROM イメージが
肥大化する問題の原因は一緒なのでは?と思っていたがどうやら違うようだ。

先に結論から書いておくと、ld の方は bug-binutils 及び bugzilla に、ほぼ
同じ問題が報告されてた。よーするにリンカスクリプトの解釈が ld 2.18 から
一部変更になった、らしい。

bug-binutils : [Bug ld/5785] New: Spurious "section xxx overlaps section yyy"
bugzilla : Spurious "section xxx overlaps section yyy"


ここからは僕の考察がうだうだと、くどくどと書いてあるだけなので、読まなく
ていいです。

--

まず ld の方。
__attribute__ ((section (".iwram"), long_call))
この .iwram セクションは、ROM にコードの実体をおいて(LMA)、RAM にはロード する領域を設ける(VMA)ために、リンカスクリプトでその旨が記述してある。
MEMORY { rom : ORIGIN = 0x08000000, LENGTH = 32M iwram : ORIGIN = 0x03000000, LENGTH = 32K ewram : ORIGIN = 0x02000000, LENGTH = 256K } ... .iwram __iwram_start : AT (__iwram_lma) { /* foo */ } >iwram = 0xff __data_lma = __iwram_lma + SIZEOF(.iwram) ; .bss ALIGN(4) : { /* bar */ } >iwram __bss_end__ = __bss_end ; .data ALIGN(4) : AT (__data_lma) { /* buzz */ } >iwram = 0xff
bugzilla に投稿されているものとほぼ一緒な形態やね。 現象の理由も説明されているんだけど、ちょっと、いやかなり英語に自信が無い。 .iwram で指定した LMA を .bss が引き継ぐようになったため、おかしなことに なってるらしい?
.bss 0x03004794 0xf88 load address 0x08103ce4 .data 0x0300571c 0x89c load address 0x08103ce4
map 出力を見ると確かに、.bss を ROM 領域からロードしようとしてるんだよなー。 で、.data で指定している LMA が __data_lma なのだが、これが .iwram の終わ りを指しているため、同様に .iwram の終わりから LMA が継続している .bss と バッティングするってことかいな。 .bss の締めを AT> iwram に変更することで、エラー無しにリンク出来るように なった。 -- 次に objcopy の方。 ROM イメージが巨大( 83,936,992 bytes )になるのは、本来 ROM 領域に配置され るべき、なんらかのデータの実体が RAM 領域に配置されているため、RAM から ROM までの空間を吐いてしまっているっぽい。 RAM 0x0300:0000 〜 ROM 0x0800:0000 で 80 メガ( 83,886,080 bytes )になる。 int main() { return 0; } みたいなソースでも巨大なイメージになるので、他に リンクしているオブジェクト( gba_crt0.o crti.o crtbegin.o libsysbase.a )か、 リンカスクリプトに問題がありそう。 んで、リンカスクリプトの問題は先ほど解決したばかりなので、となると問題は オブジェクトにあるのか。あったらいいなぁって感じで、まだ調査してないです。 っていうか調査の仕方が分からないです。困る。

最新
2010 | 01 04
2009 | 01 02 03 04 05 06 07 09 10 11 12
2008 | 01 02 03 04 05 06 07 08 09 10 11 12
2007 | 02 03 04 05 06 07 08 10 11 12
2006 | 01 02 03 04 05 06 07 08 09 10 11 12
2005 | 01 02 03 04 05 06 07 08 09 10 11 12