>>dynamic linkerはメモリ上にプログラムコードを配置する時に
>> コードに埋め込まれたアドレス値を書き換えることは出来ないわけですよね?
>いいえ、出来ます。
>例えばmmap()ならMAP_PRIVATEでやってCoWによりプロセス毎にコピーを持つようになるだけです。

open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220P\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1183432, ...}) = 0
mmap2(NULL, 1121740, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x40066000
mmap2(0x40172000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x10b) = 0x40172000
mmap2(0x40176000, 7628, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40176000
close(3) = 0

straceの出力をよく見れば、ld.soによる全てのmmap2(Linux)において
MAP_PRIVATE指定されていました。しかしO_RDONLYでopenして、PROT_READ|PROT_EXECという
保護属性の中で、MAP_PRIVATEというのはどんな意味があるのかな。。。

またMAP_DENYWRITEに関してはmanに以下のように書いてあるのに、ld-2.3.4.soにおいてもまだ
フラグ指定されてるのは、互換性だけの理由かな。
>このフラグは無視される。 (ずっと前は、マップ元のファイルへの書き込みを行おうとすると、
>エラー ETXTBUSY で失敗するようにシグナルが設定されていたが、これは denial-of-service
>(サービス拒否)攻撃の原因となった)


156さんの言ってることがmmapとCoWによりようやく理解できました。
non-PICをDYNに含めることにおいて「効率を〜」という話が出てくるのは
CoWを前提とした話だったのですね。なるほど。
それから考えるとたしかに、DYNにnon-PICを含むことが出来ないのは、
おかしな話に思えます。ELFの仕様が出来上がったのは10年も昔の話だし、
MMUのないCPUなどの事情も考慮されているのかもしれないですね。
他にはGNUツールの開発者のポリシー、またはセキュリティー的な事情とかも
ありうるのかな。ELFを理解できたら、そのうち調べてみたいです。