ついつい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);

☆要は配列に対して範囲外アクセスをするところがあるというもの。これは穏やかではない。

ソースみると、

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を作成!(これはあっという間に終わる。)