160 likes | 281 Views
Static Shared Library. Non-shared v.s. Shared Library. A library is a collection of pre-written function calls. Using existing libraries can save a programmer a lot of time. (e.g., the printf() in the C library)
E N D
Non-shared v.s. Shared Library • A library is a collection of pre-written function calls. • Using existing libraries can save a programmer a lot of time. (e.g., the printf() in the C library) • However, if a library is not shared among many programs, but instead a copy is included in every program that uses it, the size of each linked program will be large. • Also, a lot of disk and memory space will be wasted by these programs that uses non-shared libraries. • This motivates the concept of shared library.
How Does It Work? • At link time, the linker searches through libraries to find modules that resolve undefined external symbols. • Rather than copying the contents of the module into the output file, the linker makes a note of what library the module come from and puts a list of the libraries in the executable. • When the program is loaded , startup code finds those libraries and maps them into the program’s address space before the program starts. • Standard operating system file-mapping semantics automatically share pages that are mapped read-only or copy-on-write.
An Example Program #include <math.h> main() { printf("exponential value %d\n", exp(-1)); }
Its Shared Library Usage Information Program Header: PHDR off 0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2 filesz 0x000000c0 memsz 0x000000c0 flags r-x DYNAMIC off 0x000005f4 vaddr 0x080495f4 paddr 0x080495f4 align 2**2 filesz 0x00000078 memsz 0x00000078 flags rw- Dynamic Section: NEEDED libm.so.2 NEEDED libc.so.4
Linking Shared Libraries • The most difficult aspect of static shared libraries is address space management. • Each shared library occupies a fixed piece of address space in each program in which it is used. • Different libraries have to use non-overlapping addresses if they can be used in the same program. • Assigning address space to libraries is a black art. • On one hand, you want to leave some space in between them to allow version updates. • On the other hand, you like to put popular libraries as close together as possible to minimize the number of page tables needed.
Address Space Allocation Example shieyuan3# ldd a.out a.out: libm.so.2 => /usr/lib/libm.so.2 (0x28065000) libc.so.4 => /usr/lib/libc.so.4 (0x28080000)
Address Space Management • Generally both the code and the data addresses for each library are explicitly defined, with the data area starting on a page boundary a page or two after the end of the code. • This makes it possible to create minor version updates, because updates frequently do not change the data layout, but just add or change code.
Techniques for Minor Updates • Each individual shared library exports symbols, both code and data, and usually also imports symbols if the library depends on other libraries. • To allow library updates, we need a method to update a library without changing the addresses of exported symbols. • For code addresses, rather than exporting the address of each routine, the library contains a table of jump instructions that jump to all of the routines, with the addresses of the jump instructions exported as the addresses of the routines. • The performance cost is one extra jump. Normally this is acceptable.
Techniques for Minor Updates • For exported data, the situation is more difficult, because there is no easy way to add a level of indirection like to one for code addresses. • In practice, however, exported data tend to be tables (e.g., the File structure for the C library) of known size or a single word value like errno. • We can collect these data and place them at the beginning of the data section to precede any anonymous data that are part of individual routines.
Binding Time • Shared libraries raise binding time issues that do not apply to conventionally linked program. • A program that uses a shared library depends on having that shared library available when the program is run. • One kind of error occurs when the required libraries are not present. • In such a case, there is no much we can do. An error message is usually printed.
Binding Time (cont’d) • What will happen if the library is present but the library has changed since the program was linked? • With static shared libraries, symbols are still bound to addresses at link time, but library code is not bound to the executable code until run time. • A static shared library cannot change very much without breaking the programs that it is bound to. • If we change the addresses of routine and data in the new version of library, then the program will crash.
Binding Time (cont’d) • A static shared library can sometimes be updated without breaking the program that uses it, if the updates can be made in a way that does not move any address in the library. • This permits minor version updates, typically for small bug fixes. • Larger changes unavoidably change program addresses, which means that a system needs multiple versions of the library. • E.g., libc.so.4
Structure of Shared Library • The shared library is an executable format file. • The jump table is considered to be text, because it is executable code.