SP 16
SP 16
SP 16
Dynamic Linking
Dynamic linking defers much of the linking process until a program starts running or even later. It provides several benefits:
Easier to create than statically linked shared library Easier to update than statically linked shared library Semantics are closer to those of unshared libraries. Permit a problem to load and unload routines at run time.
Of course, its performance cost is higher because the linking process needs to be redone every time a program runs. However, most people are willing to pay this overhead given its offered advantages.
GOT Operation
Reference Data
Once the GOT register is loaded, code can reference local static data using the GOT register as a base register, because the distance from a static datum in the programs data segment to the GOT is fixed at link time. Addresses of global data are not bound until the program is loaded. So, to reference global data, code has to load a pointer to the data from the GOT and then dereference that pointer. This extra memory reference makes programs somewhat slower. However, most programmers are willing to pay for it. Of course, this pointer needs to be loaded to the GOT when the program is dynamically linked.
R_386_RELATIVE
This is used to mark data addresses in a PIC shared library that need to be relocated at load time. The run-time loader use this information to do load-time relocation. Note that the code is usually PIC and sharable. However, usually the data is not sharable (has its own copy in the physical memory) and not PIC. Thus they may need to be relocated. For example:
Char buf[100]; char *datap = &buf[0];
PLT Operation
Lazy Binding
Programs that use shared libraries generally contain calls to a lot of functions. In a single run of the program, many of the functions are never called. To speed program startup, dynamically linked ELF programs use lazy binding of procedure addresses. This is accomplished by means of a PLT. Each dynamically bound program has a PLT, with the PLT containing an entry for each nonlocal routine called from the prohgram.
PLT Details
The first entry in the PLT, which is called PLT0, is special code to call the dynamic linker. At load time, the dynamically linker automatically places two values in the GOT.
At GOT+4, it puts a code that identifies the particular library. At GOT+8, it puts the address of the dynamic linkers symbol resolution routine.
The rest of PLT entries, which we call PLTn, each starts with an indirect jump through a GOT entry that is initially set to point to the push instructions in the PLT entry that follows the jmp.
PLT Details
Following the jmp is a push instruction that pushes a relocation offset. The offset is the offset of a special relocation entry of type R_386_JMP_SLOT in the files relocation table. The relocation entrys symbol reference points to the symbol in the files symbol table and its address points to the GOT entry.
PLT Details
The first time the program calls a PLT entry, the first jump in the PLT entry in effect does nothing, because the GOT entry through which it jumps points back into the PLT entry. Then the push instruction pushes the offset value, which indirectly identifies both the symbol to resolve and the GOT entry into which to resolve it, and jumps to PLT0. The instruction in PLT0 pushes another code that identifies which program it is, and then jump into stub code in the dynamic linker with the two identifying codes at the top of the stack. The return address back to the routine that called into the PLT is also pushed into the stack.
PLT Details
Now the stub code saves all registers and calls an internal routine to do the resolution. The two identidying words suffice to find the librarys symbol table and the routines entry in that symbol table. The dynamic linker looks up the symbol value using the run-time symbol table and stores the routines address into the GOT entry. (Dynamic loading is also possible here.)
PLT Details
Then the stub code restores the registers, pops the two words that the PLT pushed, and jump off to the routine. With the GOT entry having been updated, subsequent calls to that PLT entry jumps directly to the routine itself without entering the dynamic linker.
Finding Library
Once the linker has found the file containing the library, the dynamic linker opens the file and reads the ELF header to find the program header, which in turn points to the files segments including the dynamic segment. The linker allocate space for the librarys text and data segments and maps them in, along with zeroed pages for bss. For the librarys dynamic segment, it adds the librarys symbol table to the chain of symbol tables, and if the library requires further libraries that are not already loaded, it adds any new libraries to the list to be loaded.
Finding Library
When this process terminates, all of the libraries have been mapped in, and the loader has a logical global symbol table consisting of the union of all of the symbol tables of the program and the mapped libraries.
An Example C Program
int xx, yy; main() { xx = 1; yy = 2; printf ("xx %d yy %d\n", xx, yy); }
Dynamic Section
Dynamic Section: NEEDED libc.so.4 INIT 0x8048390 FINI 0x8048550 HASH 0x8048128 STRTAB 0x80482c8 SYMTAB 0x80481b8 STRSZ 0xad SYMENT 0x10 DEBUG 0x0 PLTGOT 0x8049584 PLTRELSZ 0x18 PLTREL 0x11 JMPREL 0x8048378
Section Header
Sections: Idx Name 0 .interp Size 00000019 CONTENTS, 1 .note.ABI-tag 00000018 CONTENTS, 2 .hash 00000090 CONTENTS, 3 .dynsym 00000110 CONTENTS, 4 .dynstr 000000ad CONTENTS, 5 .rel.plt 00000018 CONTENTS, 6 .init 0000000b CONTENTS, 7 .plt 00000040 CONTENTS, 8 .text 00000174 VMA LMA File off 080480f4 080480f4 000000f4 ALLOC, LOAD, READONLY, DATA 08048110 08048110 00000110 ALLOC, LOAD, READONLY, DATA 08048128 08048128 00000128 ALLOC, LOAD, READONLY, DATA 080481b8 080481b8 000001b8 ALLOC, LOAD, READONLY, DATA 080482c8 080482c8 000002c8 ALLOC, LOAD, READONLY, DATA 08048378 08048378 00000378 ALLOC, LOAD, READONLY, DATA 08048390 08048390 00000390 ALLOC, LOAD, READONLY, CODE 0804839c 0804839c 0000039c ALLOC, LOAD, READONLY, CODE 080483dc 080483dc 000003dc Algn 2**0 2**2 2**2
2**2
2**0 2**2
2**2
2**2 2**2
17 .bss
18 .stab 19 .stabstr
20 .comment