.
developing primaries

gcc ではコード・リソースが 32KB を越えるような大きなアプリケーションを開発するためにはマルチ・セグメント化を行う必要が出てきます。必ずしもそうではないかもしれませんが。ここではその手順を私の経験に基づいて説明します。


前提

ツールの前提は PRC-Tools 2.0 です。これ以前のものでは、multilink とか何とか言うツールを使うらしいんですが、私もやったことがないので詳しいことは分かりません。また、CodeWarrior を使っている方は、そもそもこういう苦労をする必要はありません。別の苦労をしてください。;-)

なお、Jump Island 等、ワークアラウンドは他にもあるようですが、それも私はやったことがないのでよく分かりません。

m68k-palmos-size で計る

PRC-Tools というのはコンパイラやリンカ、アセンブラ、デバッガ等々、開発に必要なツールセットなんですが、このツール群の中には他にも細々としたものが入っています。今回のマルチ・セグメント化では、この内の二つを使います。

まず、m68k-palmos-size ですが、これはオブジェクト・ファイルを調べてそのサイズの内訳を教えてくれる、というものです。詳しいことは私もよく知りませんが(笑)、これを使って、

[//D/PalmDev/hogehoge/] m68k-palmos-size *.o

などとやると、現在作業中のディレクトリにあるオブジェクト・ファイルを分析してくれます。詳しくは述べませんが、今までうまく make できていたものが、突然、オブジェクトは作れるのに .prc を作るところまで行けなくなった、という場合、しかも .prc が 32KB を越えてきている場合には、まずこれで調べてください。

.text セクションが 32KB を越えているなら多分、それが原因です。

multigen で分ける

で、どうもコード・リソースが 32KB を越えてしまったみたいだ、という場合、multigen を使って、コード・リソースを分割してやる必要があります。ただし、厳密に言うと、multigen で分ける、というわけではありません。multigen はむしろ、分けたものをつなぐためのツールです。

以下、手順をまとめてみました。

1. 関数を分類する

関数のプロトタイプ宣言の部分(無い人は作りましょう)をじっと眺めます。で、えいや、と分けてしまいます。普通、二つに分けるくらいで十分ですが、別に三つに分けても構いません。私は何となく、機能で分類したので、必要もないのに三つに分けています。

2. セクションを定義する

1. の分類にしたがって、コードのセクションを定義します。まず、def ファイルを用意します。これは主に build-prc が使用する定義ファイルで、.prc を作る時の指示をここにいろいろ書いておくことができます。名前とか CreatorID も指定できるので、けっこう便利です。でも、私は今回のマルチ・セグメント化を行うまで、こういうファイルの存在すら知りませんでしたが。

で、マルチ・セグメント化の際には、このファイルの中に multiple code という節を用意しておかなければなりません。こんな感じです。

multiple code {"hogefoo" "hogebar"}

こうしておくと、build-prc などのツールは、「なるほど、今作ってるこいつには、標準のコード・セクション「以外」に、hogefoo と hogebar というセクションがあるんだな」ということを認識してくれます。というわけで、コードを二つに分けるなら、{ } の中のエントリは1つだけです。なお、セクションの名前は8文字以内にしてください。

3. 定義に従って関数を記述する

関数のプロトタイプ宣言に、セクション属性を書き加えていきます。標準のセクションに配置される関数には何も追加する必要はありませんが、それ以外のセクションに置くものについては、以下のような感じで宣言を修正してください。

#define FOO_FUNC __attribute__ ((section ("hogefoo")))
#define BAR_FUNC __attribute__ ((section ("hogebar")))

void HogeFooFunction(void) FOO_FUNC;
void HogeBarFunction(void) BAR_FUNC;

要は、これはこのセクションに行く関数だよ、という但し書きを付け加えているわけです。

4. Makefile を修正する

最後に、Makefile を修正します。続く(笑)。