GNUリンカスクリプト

リンカスクリプトの話。リンカはコンパイラごとに異なるけれども、参考にしたサイトはGNU系リンカだ。ARMのScatterファイルとは構文が違う。

命令文はReadOnly, 変数はRead/WriteするためにRAMに展開する。

リンカの仕事はシンボルを解決すること。

a.s -> a.o
b.s -> b.o

のようにソースコードをコンパイルする。

試しに、ファイルに存在しないシンボルがある状態でコンパイルしてみる。

$arm-none-eabi-nm main.o
00000000 d arr
00000003 d eoa
00000004 t start
00000010 t stop
         U sum

t = .text, d = .data, U = unresolvedと表示されている。リンカを実行したときに他のファイルにsumシンボルがもしも見つかれば、sumの最終的な番地に解決される。これをリロケーションという。

あとはセクションマージング(section merging)という、複数のオブジェクトファイルの中のセクション同士を隣り合ったアドレスに並び変える機能もある。ようは.textは.text同士をまとめてくれる機能。

リンカスクリプトはこんなの。

SECTIONS {
    . = 0x00000000;
    .text = {
        abc.o (.text);
        def.o (.text);
    }
}

.をロケーションカウンタといって、現在位置を表すR/W可能なシンボルである。セクションの先頭では必ず0に初期化されるので上のコードは無駄なことを書いている。あとセミコロンは必要っぽい。

SECTIONS {
    .text : { * (.text) }
}

ワイルドカードが使える。

SECTIONS {
    .text: { * (.text); }
    . = 0x0400;
    .data: { * (.data); }
}

ロケーションカウンタの値を変えることで、データセクションの位置をずらす。