フォローアップELF 実行エントリ ポイントの仮想アドレスが、0x0 ではなく 0x80xxxxx の形式になっているのはなぜですか? Linux バイナリの仮想メモリ アドレスが 0x8048000 から始まるのはなぜですか? ld
、デフォルトとは異なるエントリ ポイントを使用できないのはなぜld -e
ですか?
その場合segmentation fault
、デフォルトのエントリ ポイントに近いアドレスであっても、リターン コード 139 が返されます。なんで?
編集:
質問をより具体的にします。
.text
.globl _start
_start:
movl $0x4,%eax # eax = code for 'write' system call
movl $1,%ebx # ebx = file descriptor to standard output
movl $message,%ecx # ecx = pointer to the message
movl $13,%edx # edx = length of the message
int $0x80 # make the system call
movl $0x0,%ebx # the status returned by 'exit'
movl $0x1,%eax # eax = code for 'exit' system call
int $0x80 # make the system call
.data
.globl message
message:
.string "Hello world\n" # The message as data
これを でコンパイルしas program.s -o program.o
て静的にリンクするとld -N program.o -o program
、テキスト セグメントの およびエントリ ポイントとしてreadelf -l program
表示0x0000000000400078
されます。実行すると、「Hello world」が出力されます。VirtAddr
0x400078
しかし、ld -N -e0x400082 -Ttext=0x400082 program.o -o program
(テキストセグメントとエントリポイントを4バイト移動して)リンクしようとすると、プログラムはkilled
. で検査するとreadelf -l
、タイプ の 2 つの異なるヘッダーが表示されます。1LOAD
つは at で0x0000000000400082
、もう 1 つは at0x00000000004000b0
です。
試してみると、すべて機能し、セクション0x400086
は 1 つしかありません。LOAD
- 何が起きてる?
- 選択できるメモリアドレス、選択できないメモリアドレス、およびその理由は?
ありがとうございます。