スタック・サイズのデフォルト値

リンカ・スクリプトまで追いかけて、スタック・サイズを規定するシンボルが_stack_sizeであることまでは判ったが、そのシンボル定義が見つからない。
リンク・オプションでもないらしい。じゃあリンカそのものに埋め込まれているのか?
という話の続きである。



リンカ外部から突き詰めていくという手もあるのだろうけど、ここは直接ソースコードを当たることにした。
AtmelのサイトからToolchainのソースをダウンロードする。今回は

avr32_gnu_toolchain_2.2.1_source.zip

だ。Linux用ではあるがソースコードを確認するだけなので、これでよい。
このzipファイルを解凍ソフトで展開すると、複数の.tar.gzファイル他が出来る。リンカgnu-ldはbinutilsに含まれるので、次にavr32-binutils-2.19.atmel.1.0.0.tar.gzを解凍する。
解凍したディレクトリの中にある「ld」ディレクトリが目的のソースファイルを格納している。
このディレクトリの中で「_stack_size」を検索すると、avr32関係では以下の2つが見つかった。

emulparams\avr32elf.sh
emultempl\avr32elf.em

avr32elf.shはシェル・スクリプトでその記述内容からすると、リンカ・スクリプトを生成するものらしい。昨日見たリンカ・スクリプトと同じ記述が見つかる。AVR32 Studio内でこのシェル・スクリプトを起動しているかと思い、AVR32 Studioのインストール・ディレクトリ以下を検索したがこのシェル・スクリプトは存在しなかった。どうやらToolchainを生成するときだけ実行するもののようだ。
avr32elf.emの方を見る。.emという拡張子はよく知らないが、ファイルの先頭に

# This shell script emits a C file. -*- C -*-
# Copyright (C) 2007 Atmel Corporation
#
# This file is part of GLD, the Gnu Linker.

と書かれているので、gnu-ldの一部のようだ。更に読み進めるとC言語の記述そのもののように見える。この中で「_stack_size」を調べると

64:  lang_add_assignment (exp_assop ('=', "_stack_size",
65:                 exp_intop (stack_size)));

とあり

54:  static int stack_size = 0x1000;

が見つかる。



と言う訳で、_stack_sizeはリンカが内部定義したシンボルで、初期値が0x1000ということである。あー、すっきりした。

それでは判ったことで何か良いことがあるかというとそうでもない。
AVR32 STudioでは、この_stack_sizeを書き換える手段を提供していないからだ。通常ならプロジェクトのプロパティ画面から値を設定できそうなものだが、そうはなっていない。
となると、自分でリンカ・スクリプトを書き換えるしかない訳だが、それならなにも_stack_sizeを変更する必要はなく、自分で好きなようにスタックを定義すればいいのである。

今、MPU(Memory Protection Manager)ドライバの例題を見ているのだが、例題にはリンカ・スクリプトが付いていて、そのスタック関係の記述は以下のようになっている。

72:   __stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 4K;

258:  .stack         ORIGIN(INTRAM) + LENGTH(INTRAM) - __stack_size__ :
259:  {
260:    _stack = .;
261:    *(.stack)
262:    . = __stack_size__;
263:    _estack = .;
264:  } >INTRAM AT>INTRAM :INTRAM

このような感じで自分で定義してしまえばよいのである。



2009/11/20 追記
自己完結したが、デフォルト・スタック・サイズの指定方法を見つけた。

"%AVR32_HOME%\bin\avr32-gcc" --target-help

とすると表示されるターゲット毎に指定可能オプションとして

    • stack

というのがあり、プロジェクトのプロパティ画面からリンカ・オプションに指定する(まだ試していないけど)。