共有ライブラリアーキテクチャによってロードされたメモリアドレス領域は依存していますか?

共有ライブラリアーキテクチャによってロードされたメモリアドレス領域は依存していますか?

x86では、プロセスのVMでは、共有ライブラリがオンラインのほとんどの記事で言及されているmmap領域であるヒープとスタックの間にロードされることがわかりました。ただし、PowerPC Linuxシステムでは、プログラム自体がロードされる場所の下にロードされたすべてのライブラリが表示されます。 「strace」は、ライブラリロードアドレスがライブラリをロード/マッピングする前に事前に決定されることを示します(ldによって決定されると仮定)。

これが建築に関連しているのだろうか。これに関するオンライン文書はありますか?

メモリマップ(ppc):

> cat /proc/self/maps
00100000-00102000 r-xp 00000000 00:00 0          [vdso]
0fe40000-0ffab000 r-xp 00000000 08:02 147120     /lib/libc-2.11.1.so
0ffab000-0ffbb000 ---p 0016b000 08:02 147120     /lib/libc-2.11.1.so
0ffbb000-0ffbf000 r--p 0016b000 08:02 147120     /lib/libc-2.11.1.so
0ffbf000-0ffc0000 rw-p 0016f000 08:02 147120     /lib/libc-2.11.1.so
0ffc0000-0ffc3000 rw-p 00000000 00:00 0 
0ffd0000-0fff0000 r-xp 00000000 08:02 147113     /lib/ld-2.11.1.so
0fff0000-0fff1000 r--p 00020000 08:02 147113     /lib/ld-2.11.1.so
0fff1000-0fff2000 rw-p 00021000 08:02 147113     /lib/ld-2.11.1.so
10000000-10005000 r-xp 00000000 08:02 195850     /bin/cat
10014000-10015000 rw-p 00004000 08:02 195850     /bin/cat
10015000-10036000 rwxp 00000000 00:00 0          [heap]
24000000-24001000 rw-p 00000000 00:00 0 
24013000-24014000 rw-p 00000000 00:00 0 
bfade000-bfaff000 rw-p 00000000 00:00 0          [stack]

strace (ppcから):

> strace cat
execve("/bin/cat", ["cat"], [/* 26 vars */]) = 0
brk(0)                                  = 0x10015000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x24000000
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(0x3, 0xbfb84558)                = 0
mmap(NULL, 70203, PROT_READ, MAP_PRIVATE, 3, 0) = 0x24001000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\24\0\0\0\1\17\345\376\260\0\0\0004"..., 512) = 512
fstat64(0x3, 0xbfb84540)                = 0
mmap(0xfe40000, 1582324, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xfe40000
mprotect(0xffab000, 65536, PROT_NONE)   = 0
mmap(0xffbb000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16b000) = 0xffbb000
mmap(0xffc0000, 9460, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xffc0000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x24013000
mprotect(0xffbb000, 16384, PROT_READ)   = 0
mprotect(0xfff0000, 4096, PROT_READ)    = 0
munmap(0x24001000, 70203)               = 0
brk(0)                                  = 0x10015000
brk(0x10036000)                         = 0x10036000
fstat64(0x1, 0xbfb84d00)                = 0
fstat64(0, 0xbfb84d00)                  = 0

ベストアンサー1

ランタイムスタックの(好ましい)構成は、ハードウェアアーキテクチャによって異なります。ただし、プログラム自体と共有ライブラリ、動的にリンクされた実行可能ファイルの場合、マップされた領域のメモリ位置はリンカによって決定されます。一般的に言えば、ユーザープログラムのコンポーネントがどこにあるべきかを判断するのはカーネルの仕事ではありません。 CPU アーキテクチャもそのような順序を意味しません。同じハードウェア上または実行中のオペレーティングシステム(カーネルなど)内でも、さまざまなリンカがそれを別の方法で配置することを想像できます(exec Linux呼び出しはELFファイルからリンカ名を抽出します。の変数を参照elf_interpreter)。load_elf_binary()fs/binfmt_elf.c

Linuxでは、デフォルトの動的リンカーはld-linuxglibcの一部です。オブジェクトマッピングを試みる方法は、ソースコードの関数で見ることができます_dl_map_object_from_fd()elf/dl-load.c実行可能ファイルのデフォルト設定が考慮される場合があり(おそらく実行可能ファイルを作成したコンパイラとリンカによって異なります)、メモリマップ構成がカーネルによって決定されることがあります。

動的リンカーとそのアーキテクチャの依存関係に関するGoogle情報があります。たとえば、次のようになります。

おすすめ記事