2013-09-26 2 views
0

Я пытаюсь понять общие библиотеки. Из того, что я знаю, общие библиотеки имеют свои базовые адреса как ноль, поэтому их можно загружать по любому адресу во время выполнения, и поэтому переменные правильно перемещаются либо во время выполнения, либо во время загрузки. Поэтому перед загрузкой библиотеки всем символам даются некоторые смещения от базы библиотеки. Следовательно, я попытался исследовать некоторые существующие библиотеки, а также создал одну библиотеку. Но я нашел некоторые отличия. Для libc.so я нашел следующее:назначение адресов в общей библиотеке

$ objdump -D /lib64/libc.so.6 

    /lib64/libc.so.6:  file format elf64-x86-64 


    Disassembly of section .note.gnu.build-id: 

    0000003b47a00270 <.note.gnu.build-id>: 
     3b47a00270: 04 00     add $0x0,%al 
     3b47a00272: 00 00     add %al,(%rax) 
     3b47a00274: 14 00     adc $0x0,%al 
     3b47a00276: 00 00     add %al,(%rax) 
     3b47a00278: 03 00     add (%rax),%eax 
    [More contents...] 

Из того, что я знаю, является то, что заголовки эльфов занимают некоторое пространство. Но даже если это произойдет, оно не будет занимать адреса от 0 до 0x3b47a00270. Итак, я создал свою собственную библиотеку (с помощью -fpic и -shared флаги), и я увидел это:

$ objdump -D ./libvector.so 
./libvector.so:  file format elf64-x86-64 


Disassembly of section .note.gnu.build-id: 

00000000000001c8 <.note.gnu.build-id>: 
1c8: 04 00     add $0x0,%al 
1ca: 00 00     add %al,(%rax) 
1cc: 14 00     adc $0x0,%al 
1ce: 00 00     add %al,(%rax) 
1d0: 03 00     add (%rax),%eax 
[More contents...] 

Это одна кажется более разумным с точки зрения адресов. .note.gnu.build-id начинается с 0x1c8. Итак, ребята, любая идея, почему в случае libc или других существующих библиотек, таких как libpthread, дело другое? Я использую fedora 18 x86_64. Я думаю, что это может быть случай prelinking, но я не уверен, и даже если это, как найти, что это prelinked? Большое спасибо заранее ...

ответ

1

objdump -D /lib64/libc.so.6

Вы разбираете разделы, которые не содержат код. Поскольку вы еще не понимаете, что делаете, придерживайтесь objdump -d - это будет вас путать.

Из того, что я знаю, разделяемые библиотеки имеют свои базовые адреса в качестве нулевого

выше утверждение неверно: общие библиотеки могут иметь свой базовый адрес как ноль, но они не должны ,

почему в случае LIBC или других существующих библиотек, как libpthread, дело обстоит иначе

Поскольку эти библиотеки были связать. См. «Предварительная ссылка для человека», например. here.

Вы можете увидеть это clearer с readelf -l. Вы хотите посмотреть на VirtAddr на первый сегмент LOAD.

В случае библиотеки, не связанной с предварительным соединением, этот адрес будет равен 0. В случае вашего предварительного связывания libc.so.6 оно будет 0x3b47a00000. Также обратите внимание, что системы RedHat часто настраиваются для повторного запуска prelink каждые две недели, и поэтому адрес, который ваш libc.so.6 имеет префикс, может меняться со временем.

Смежные вопросы