Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change Symbol Visibility in Object File or Library ('t' -> 'T')

I need to change the symbol visibility in an object file or library. For example, a particular shared object has a symbol name present, but its local so I can't bind to it (the lower t indicates local in the TEXT section):

$ nm /usr/local/ssl/lib/libcrypto.so | grep -i OPENSSL_cpuid_setup
00000000000c3f80 t OPENSSL_cpuid_setup
000000000008a360 t fips_openssl_cpuid_setup

The same symbol is present in the archive, but the archive not being used in this project (the upper T indicates global in the TEXT section):

$ nm /usr/local/ssl/lib/libcrypto.a | grep -i OPENSSL_cpuid_setup
0000000000000310 T OPENSSL_cpuid_setup
000000000000f8e0 T fips_openssl_cpuid_setup

I'd like the visibility of OPENSSL_cpuid_setup to be global rather than local.

Is there a way to change the symbol visibility in a object file or library? I've been through Binutil tools, and it does not look like there's a suitable tool.

And for completeness, the 'easiest' methods are not available because the source code is sequestered and cannot be changed. The easiest methods include (1) removing static from the declaration; and (2) using GCC's visibility attributes.

like image 397
jww Avatar asked Oct 19 '25 14:10

jww


1 Answers

You could try (untested) objcopy with the --globalize-symbol option. However, this is only going to work with the archive, not the dynamic library, as you can modify the normal symbol table and not the (hashed) dynamic symbol table.

A disgusting hack would be to determine the offset of the routine from a global (using objdump and writing it to a file from your makefile), then create a function pointer, then jump to that (yuck).

like image 59
abligh Avatar answered Oct 21 '25 06:10

abligh