Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

gnu ld, binutils についての質問です。

8 views
Skip to first unread message

clt...@xug.biglobe.ne.jp

unread,
May 30, 2003, 6:29:47 PM5/30/03
to
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
; clt...@xug.biglobe.ne.jp

Shinji KONO

unread,
May 30, 2003, 10:49:24 AM5/30/03
to
河野真治 @ 琉球大学情報工学です。

In article <bb7mc9$80$1...@bgsv5648.tk.mesh.ad.jp>, clt...@xug.biglobe.ne.jp writes


> 逆アセンブルした結果から推測すると、宣言した変数が全てスタック上
> でやりとりされ、bogus_funcにポインタを渡すと、スタック
> へのポインタが渡され、メモリの実体を指してないようです。

ま、逆アセンブルの結果を見ればわかると思いますが...

> int bogus_func(int* bar)
> {

この段階でbarがスタックセグメントを指しているってことがコン
パイラに伝わらないとデータセグメントが使われてしまいますよね。
教える方法があるかどうかは知りません。

> {
> int foo;
> bogus_func(&foo);

こっちで「エラー」を出すのが正しいとは思うけど、

でも、ポインタをデータとスタックで、やりとりするつもりなら、
スタックセグメントとデータセグメントをわけるのは、止めた方が
良いと思うよ。(ま、言うことを聞くような奴ならそんなことは
しないわけだが... せいぜい苦労してください... 8086 なら
ともかく...)

---
Shinji KONO @ Information Engineering, University of the Ryukyus,
PRESTO, Japan Science and Technology Corporation
河野真治 @ 琉球大学工学部情報工学科,
科学技術振興事業団さきがけ研究21(機能と構成)

clt...@xug.biglobe.ne.jp

unread,
May 30, 2003, 12:12:35 PM5/30/03
to
watatsu です。

> > int bogus_func(int* bar)
> この段階でbarがスタックセグメントを指しているってことがコン
> パイラに伝わらないとデータセグメントが使われてしまいますよね。
> 教える方法があるかどうかは知りません。

分かりました。
# なるほど。スタックに詰まれたかデータセグメント上にあるか
# 分からない…

> > {
> > int foo;
> > bogus_func(&foo);
> こっちで「エラー」を出すのが正しいとは思うけど、

ずっとはまってました。
コンパイルが通ってぬか喜び。

> でも、ポインタをデータとスタックで、やりとりするつもりなら、
> スタックセグメントとデータセグメントをわけるのは、止めた方が
> 良いと思うよ。

そうですね。無難です。
スタックセグメントの取り扱いがデータセグメントとほぼ同じという、謎の勘違いしてました。
どうやってスタックから如何にデータを保護するのか、について頭をひねっていました。(汗)
ずっと「リンカスクリプトが怪しい」などと勝手に決め付けてまし
た。(汗汗)

助かりました。
ありがとうございました。

; clt...@xug.biglobe.ne.jp

0 new messages