Say you have a shared library with versioned symbols that has the function init(int *param) defined in two versions, where new_init is made the default for init (that’s what the @@ means):
#include "shared1.h"
void new_init (int *param)
{
*param = 0;
}
void old_init (int *param)
{
*param = -1;
}
__asm__(".symver new_init,init@@VERS_2");
__asm__(".symver old_init,init@VERS_1");
Say you have a second shared library that provides a function do_something() uses that init from the first shared library:
#include "shared1.h"
int do_something ()
{
int var;
init (&var);
return var;
}
And you have an app that just prints the result:
#include "shared2.h"
#include
int main(int argc, char *argv[])
{
printf ("Result: %d\n", do_something ());
return 0;
}
And all of this is cobbled together with the following Makefile:
all: app
libshared.so: shared1.c shared1.h
cc -o $@ $< -shared -fPIC -Wl,--version-script=version.script
libmoreshared.so: libshared.so shared2.c
cc -o $@ shared2.c -shared -fPIC
app: libmoreshared.so app.c
cc -o $@ -L. app.c -lmoreshared -lshared
What's the output of
LD_LIBRARY_PATH=. ./app
Update: Try to answer it without compiling and running it at first.
Update2: I forgot the version.script, sorry.
VERS_1 {
local:
old_init;
};
VERS_2 {
local:
new_init;
} VERS_1;
bash: ./app: no such file or directory
(syntax error in app.c -> no output from gcc -> file not found)
Does this qualify ?
No 🙂 And you basically should be able to answer it without compiling… 😛
The contents of version.script are not shown so potentially it could do anything.
Also when linking moreshared it does not link against libshared. This is probably what screws up symbol lookup (and why you should always use -Wl,–no-undefined).
Yep 🙂
I wonder if the missing contents of the version.script are relevant to the answer.
Krzesimir: Kind of, but I just forgot to add it.
My guess is that it will print -1, but it should print 0, since new_init() is set as default.
The point is that it really depends. On the version script, on the ld.so behavior if you forget to link the intermediate library.
I was probably wrong.
with this script,
VERS_1 {
local:
*;
};
VERS_2 {
init;
} VERS_1;
it prints 0.