Sei sulla pagina 1di 14

Writing Shared Libraries

Ulrich Drepper

What DSOs are for

Enclose code which is used multiple times in different programs Enable dynamically loading additional functionality which

Is not always needed Is created and/or distributed separately

How DSOs should NOT be used


Do not use the program design abstraction to guide the creation of the DSOs! That means: do not create an individual DSO for the implementation of each little part of the project

Properties of DSOs

DSOs must be position independent


Use of special compiler and linker options Some source code is inherently position dependent and needs to be rewritten for maximum performance

All exported interfaces can be directly used from other objects

Exported interfaces constitute the ABI which cannot be changed

Task when writing a DSO

Optimize performance:

Minimize resource usage Minimize load times Minimize runtime overhead when using DSO

Do not introduce security risks Enable maintainability:


Restrict exported symbols Hide incompatible changes

Costs of DSO Usage

Each DSO has to be separately mapped into the process' address space Before first use, DSO must be adjusted for the chosen load address Symbols are searched for in many places for by name Calls which could cross DSO boundaries are indirect Variables which might be in another DSO are accessed indirectly

Reducing the Costs I

Use as few DSOs as possible. All code which is always used together should be in one DSO Write code which is inherently position independent to reduce relocation time

constchar*arr[]={ one,two, three};

Each array element needs a relocation Array not read-only Relocations need memory at runtime

Reducing the Costs II

Avoid lookup by name when the definition is known to be local to the DSO:

Either do not export the symbol in the first place Or use a local alias to avoid the name lookup To reduce symbol table size and possibility of hash collision To reduce binary size (fewer strings etc)

Avoid exporting symbols

Master Before Writing DSO

Understand symbol lookup, global namespace, ... Identify symbols which are meant to be used from the outside Instruct linker to avoid exporting symbols not on the list Cleanup source code

Avoid position-dependent code staticconstchar*str=foo;

Maintaining Compatibility

Programs using a DSO might be around forever Really incompatible DSO versions must not clash: identified by SONAME (simple string) Better: avoiding incompatibility

Good interface design (not discussed here) Use symbol versioning to provide multiple independent versions concurrently

Power of Symbol Versioning I


intget_number(void){ return1; } Incompatible change

intget_number(void){ return2; }

Power of Symbol Versioning II


intold_get_number(void){ return1; } asm(.symverold_get_number, get_number@VERS1.0); intnew_get_number(void){ return2; } asm(.symvernew_get_number, get_number@@VERS2.0);

Power of Symbol Versioning III

Applications linked against old DSO keep running Applications linked against new DSO will start using new definition Limitations:

Only executables and DSOs can be protected Data structure changes need to be handled separately, too

Additional Reading
http://people.redhat.com/drepper/dsohowto.pdf

Questions?

Potrebbero piacerti anche