2013-09-26 84 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。我認爲這可能是一個預先鏈接的例子,但我不確定,即使它是如何發現它是預先鏈接的? 感謝很多提前...

回答

1

objdump -D /lib64/libc.so.6

您拆卸不包含代碼段。既然你(還)不明白你在做什麼,堅持objdump -d - 它會讓你更少迷惑。

據我所知,共享庫有自己的基地地址爲零

上述聲明是不正確:共享庫可以有自己的基址,零,但他們不必。

爲什麼在libc中或類似的libpthread其他現有庫的情況下,由於這些庫已預鏈接的情況是不同的

。請參閱「man prelink」,例如here

你可以用readelf -l來看清楚。你想看看第一個LOAD細分市場的VirtAddr

如果是非預鏈接庫,該地址將爲0.如果您的鏈接爲libc.so.6,則爲0x3b47a00000。另外請注意,RedHat系統通常設置爲每兩週重新運行預鏈接,因此您的libc.so.6鏈接的地址可能隨時間而改變。