ついついtalosのビルドをしてみました。
子供が寝ている間に・・・。
昨日の日記に書いた通り、ソースを読むためにsvnでチェックアウトする。
読書会のお話だと、Talosのコンセプトがいまひとつぴんとこない部分もあった。だからこそ、余計にソースが読みたいのだ。
ここで、カーネルエンジニアの悲しい性、ついついビルドをしてしまう。
./configure oadg first
cd objs/first
make gnutools
これによって、binutilsのソース一式を取ってきてビルドしてくれる。
ここで子供が起きてきて、メシだの風呂だので一時中断。
戻ってくると・・・・コンパイルエラー。
どうも、-WallでコンパイルしているのでWarningもエラーにしている。
ビルドが終わるまでに、3ファイル分ソースを直す。
☆mktemp()はセキュアでないのでmkstemp()を使うべきだよね。
これは単純。
[eria@localhost binutils]$ diff bucomm.c bucomm.c.org
426c426< mkstemp (tmpname);
- -
> mktemp (tmpname);
433c433< mkstemp (tmpname);
- -
> mktemp (tmpname);
- objs/binutils-2.17/gas/app.c
☆要は配列に対して範囲外アクセスをするところがあるというもの。これは穏やかではない。
ソースみると、
ch = GET ();
if (ch == EOF)
{
as_warn (_("end of file in string; '%c' inserted"), quotechar);
state = old_state;
UNGET ('\n');
PUT (quotechar);
}
となっていて、UNGET()で警告を吐いているようだ。
GET()とUNGET()はapp.cにあり、以下のとおり。
#define GET() \
(from < fromend \
? * (unsigned char *) (from++) \
: (saved_input = NULL, \
fromlen = (*get) (input_buffer, sizeof input_buffer), \
from = input_buffer, \
fromend = from + fromlen, \
(fromlen == 0 \
? EOF \
: * (unsigned char *) (from++))))#define UNGET(uch) (*--from = (uch))
GET()でEOFが返ってくる場合、fromは配列の先頭を指している。
この状況で*--fromすると見事にメモリをこわしてしまう。
この配列の使い方をみると時間がかかりそう。なので、この問題の修正パッチがでていないかどうか調べてみる.(http://www.gnu.org/software/binutils/binutils.html)
cvs経由でソース落としてきて、cvs log app.c すると
revision 1.45
date: 2008/06/04 16:10:21; author: nickc; state: Exp; lines: +4 -2
* app.c (do_scrub_chars): Do not UNGET an EOF value.
まさにそのものズバリの修正が・・・かと思ったが、ここは違う。
仕方がないので、cvsからチェックアウトしてきたbinutils2.19のソースを見る。以下赤字部分が違うようだ.
ch = GET ();
if (ch == EOF)
{
/* This buffer is here specifically so
that the UNGET below will work. */
static char one_char_buf[1];as_warn (_("end of file in string; '%c' inserted"), quotechar);
state = old_state;
from = fromend = one_char_buf + 1;
fromlen = 1;
UNGET ('\n');
PUT (quotechar);
}
そこまでUNGET()にこだわらなくても・・・・と思う。これってUNGET()するだけ無駄じゃん。
ということで、akachochinは以下のパッチにした.
[eria@localhost gas]$ diff app.c app.c.org
565a566
> UNGET ('\n');
最後はgas/read.cに未初期化変数があるという警告。
未初期化変数はある特定の関数で必ず値がセットされるので、とりあえず0初期化。
[eria@localhost gas]$ diff read.c read.c.org
1282c1282< char stopc = 0;
- -
> char stopc;
1426c1426< char stopc = 0;
- -
> char stopc;
1810c1810< char stopc = 0;
- -
> char stopc;
1932c1932< char stopc = 0;
- -
> char stopc;
2884c2884< char stopc = 0;
- -
> char stopc;
3060c3060< char stopc = 0;
- -
> char stopc;
3137c3137< char stopc = 0;
- -
> char stopc;
3517c3517< char stopc = 0;
- -
> char stopc;
5013c5013< char stopc = 0;
- -
> char stopc;
これで無事にgnutoolsのビルドが完了!
あとはmakeでtalosを作成!(これはあっという間に終わる。)