Symbol resolution when multiple versions of same library are used

1000 views Asked by At

I have a solaris shared object (common.so file) that runs as part of a third party application(app.exe). I do not have access to the source code of the application. To the so, I need to add a capability to post http requests. My plan is to use libcurl with openssl. The tricky part is that app.exe already has a dependency on an older version of curl (7.14) which does not support ssl with tls v1.2.

I downloaded the source code and built curl (7.55.1) and openssl .a files. I was also able to build common.so with static dependency on these archive files. ldd does not show dependency on curl or ssl .so files and it also does not report any "Symbol not found" errors.

With this result, I was expecting my version of curl to be invoked when the so runs as part of the application but it did not. Instead curl_version() displays older version and I get the error unknown ssl protocol error

I am using solaris studio compiler. The application does not depend on curl libraries directly but depends on a different .so file which exports symbols with the same names as curl. I realized from nm and I am assuming that this .so file also links curl statically.

1

There are 1 answers

4
Aconcagua On

When app.exe loads the two SO in question, it adds the functions of each to its symbol table. Now one of two possible scenarios must occur (which one actually is OS detail but irrelevant here...):

  1. The newer version is loaded before the older version and the older one overwrites the newer one's entries.
  2. The newer version is loaded after the older one, and as there are already entries in the table, it is not updated any more.

Now the cleanest solution – if applicable, i. e. if you have access to the sources – would be updating the other SO to use the newer version of curl. If doing so, consider creating curl as a new SO instead of linking it statically into both common.so and the other SO.

Otherwise, to solve the issue directly, you would have to switch the order the app loads the SO, which probaly would mean to decompile app.exe and rebuild it with the linkage order of the SO changed. Problem then: there might be two versions of app.exe around then, and you must make sure that only the correct one is distributed with your common.so. Potential source of trouble, too...

Apart from this, best I can think up is a workaround:

You might modify the curl prefix from curl_ to e. g. curl_755_. Do not try this by hand, though, you most likely would go crazy this way... Use a script (e. g. perl or python) for instead. And if you ever update the curl sources, you can just run it again then...

Faster version, but potentially unsafe: just replace any occurences. Safer: Identify the externally visible functions (and possibly global objects) in a first run and keep them in a map, then replace any occurence of a string contained in the map with the corresponding value.

The latter approach (map) would additionally allow to generate macros in the header files of the following form:

#define curl_xyz curl_755_xyz

These macros allow the sources of common.so to just look like as if the original sources of curl were used...