assignment of addresses in shared library

295 Views Asked by At

I am trying to understand the shared libraries. From what I know, shared libraries have their base addresses as zero so they can be loaded at any address during runtime and so the variables are correctly relocated either during runtime or load time. So before the loading of the library, all the symbols are given some offsets from the base of the library. Hence, I tried to investigate some existing libraries and also created one library. But I found some differences. For libc.so, what I found is this :

$ 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...]

From what I know, is that the elf headers take some space. But even if it does, it won't take up the addresses from 0 to 0x3b47a00270. So, I created my own library (using -fPIC and -shared flags) and I saw this :

$ 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...]

This one seems more reasonable in terms of addresses. .note.gnu.build-id here starts at 0x1c8. So, guys any idea, why in case of libc or the other existing libraries like libpthread, the case is different? I am using fedora 18 x86_64. I think that this may be a case of prelinking but I am not sure and even if it is how to find that it is prelinked? Thanks a lot in advance...

1

There are 1 best solutions below

0
On

objdump -D /lib64/libc.so.6

You are disassembling sections which do not contain code. Since you don't (yet) understand what you are doing, stick to objdump -d -- it will confuse you less.

From what I know, shared libraries have their base addresses as zero

The above statement is incorrect: shared libraries may have their base address as zero, but they don't have to.

why in case of libc or the other existing libraries like libpthread, the case is different

Because these libraries have been prelinked. See "man prelink", e.g. here.

You can see this clearer with readelf -l. You want to look at the VirtAddr for the first LOAD segment.

In case of non-prelinked library, that address would be 0. In case of your prelinked libc.so.6, it will be 0x3b47a00000. Also note that RedHat systems are often set up to re-run prelink every two weeks, and so the address your libc.so.6 is prelinked at may change with time.