Reputation: 19333
I have a set of three nearly identical static c libraries (compiled with -fPIC
), for which I am not able to have them recompiled. All libraries export the same symbols, so the only way I can bundle them together is to to modify the symbols with a prefix for each static library via objcopy
, i.e.:
for i in pineapple coconut banana
do
objcopy --prefix-symbols=${i}_ lib${i}.a
done
Now, I have three libraries with unique symbols, and can proceed to hack away writing a header to deal with the three near-duplicate header/API files for each of the libraries.
Is just renaming the exported symbols of a library like this safe? Does it have any "gotchas" or unforeseen consequences that could lead to stability problems at runtime? Are all references to the symbol within the library itself automagically corrected, or is it possible that some piece of library code (other than things like dlsym()
calls) will try to reference the old symbol and segfault?
Upvotes: 4
Views: 1169
Reputation: 213616
Is just renaming the exported symbols of a library like this safe?
Depends on "safe against what".
Does it have any "gotchas" or unforeseen consequences
Yes, see below.
that could lead to stability problems at runtime?
No. If you manage to link the final binary (a big IF), then the resulting binary will work.
Are all references to the symbol within the library itself automagically corrected
Yes, they are. The --prefix-symbols
flag changes both the definitions, and the unresolved references (this will cause problems, as you'll see momentarily).
IFF the library is completely self-contained (does not reference any symbols other than the ones it itself defines), then prefixing all symbols will work: newly renamed unresolved references will now call pineapple_foo
instead of foo
, and this reference will be resolved at link time to the renamed definition with the new name, just as desired.
The trouble comes when the target library calls something outside of itself (e.g. anything from libc
). These calls will also be prefixed, so you'll get an unresolved reference to something like pineapple_open
, or pineapple_printf
.
You may be thinking: I'll just provide a replacement somewhere else:
int pineapple_open(const char *filename, int flag, int mode)
{
return open(filename, flag, mode);
}
That is tedious, but works for functions. Where it breaks is with global variables: errno
, h_errno
, etc.
Since you mentioned -fPIC
, note that dynamic library support depends on _GLOBAL_OFFSET_TABLE_
, which you don't want renamed either.
Upvotes: 5
Reputation: 32742
Assuming the libraries were constructed from multiple source files, the symbols exported from the library will almost certainly be referenced by other places in the library. So changing the names of the symbols will result in link problems later.
Upvotes: 0