watatsu というものです。
始めての投稿です。
gnu ld を使ってリンクをしたときに疑問に思い、投稿しました。

リンカスクリプトで、以下のようにリンクしたときに、スタック・デー
タ各セグメントを別々の領域として使うことは出来るのでしょうか。ど
なたかご教授をお願いします。

以下に例を示します。

OUTPUT_FORMAT("binary")
OUTPUT_ARCH(i386)

SECTIONS
{
        _align = 4K;
        OVERLAY 0 : AT(0)
        {
                .text   { *(.text)
                          _etext = ALIGN(_align);
                          . = _etext; }
                .data   { *(.data .rodata)
                          *(.bss)
                          _edata = ALIGN(_align);
                          . = _edata; }
        }
}

として、GDT に、コードセグメント用としてロードしたアドレスを
起点として _etext だけ、コードセグメントに、そこから_e
dataだけデータセグメントに割り当て、それ以降をエキスパンドダ
ウン型のスタック領域として割り当てて、例えば以下のようなコードを
bochs 上で実行するとエラーになります。(便宜上重要な部分だ
け抜きだします。)

file1.S:
        .org 0
        .code32
        // ds, es, fs, gs はデータセグメント
        // cs は現在のコードセグメント
        // ss はスタックセグメント
        xorl %esp, %esp
        decl %esp
        jmp start

file2.c:
        int bogus_func(int* bar)
        {
                // この代入で例外が発生します…
                *bar = 0;
        }
        extern void start(void) 
                __asm__ ("start")
                __attribute__((noreturn));
        void start(void)
        {
                int foo;
                bogus_func(&foo);
        cont:
                goto cont;
        }

逆アセンブルした結果から推測すると、宣言した変数が全てスタック上
でやりとりされ、bogus_funcにポインタを渡すと、スタック
へのポインタが渡され、メモリの実体を指してないようです。
つまり、fooがスタック上にあるにもかかわらず、barへの代入の
時点でデータセグメントに対して変更を加えようとするのです。
どなたかご教授願よろしくお願いします。

gcc 3.2.3
  コンフィグオプション: ./configure
GNU ld 2.13

; cltack
; cltack@xug.biglobe.ne.jp