TOC   Previous  

Symbol Versioning

Example

We demonstrate the use of symbol versioning via an example...

First we create a library that contains a single definition of a function, and build that library with a version script:

bash$ cat sv_lib_v1.c
#include 

void xyz(void) { printf("v1 xyz\n"); }
bash$ cat sv_v1.map
VER_1 {
        global: xyz;
        local:  *;      # Hide all other symbols
};

bash$ gcc -g -c -fPIC -Wall sv_lib_v1.c
bash$ gcc -g -shared -o libsv.so sv_lib_v1.o \
            -Wl,--version-script,sv_v1.map

The symbols listed under VER_1 are associated with that tag.

We then build a program that uses "version 1" of our function:

bash$ cat sv_prog.c
#include <stdlib.h>

int main(int argc, char *argv[])
{
    void xyz(void);

    xyz();
    exit(EXIT_SUCCESS);
}
bash$ gcc -g -o p1 sv_prog.c libsv.so

Running the program produces the expected result:

bash$ LD_LIBRARY_PATH=. ./p1
v1 xyz

Suppose we want to modify the definition of our function xyz(), but still want to ensure that p1 continues to use the old definition.

We create a modified version of the shared library source file:

bash$ cat sv_lib_v2.c
#include 

__asm__(".symver xyz_old,xyz@VER_1");
__asm__(".symver xyz_new,xyz@@VER_2");

void xyz_old(void) { printf("v1 xyz\n"); }

void xyz_new(void) { printf("v2 xyz\n"); }

void pqr(void) { printf("v2 pqr()\n"); }
bash$ cat sv_v2.map
VER_1 {
        global: xyz;
        local:  *;      # Hide all other symbols
};

VER_2 {
        global: xyz; pqr;
        local:  *;      # Hide all other symbols
};

(C) 2006, Michael Kerrisk