2

We are using an third party static library, let say A.a for android development. We link it as shared library and it works fine in the one App, but when use B.so to build another C.so, some symbols in A.a cannot find. We have already use -Wl,--export-dynamic and -Wl,--whole-archive to build B.so. We have using nm to check those symbols, it exist but list as “t” instead of “T”,which means it is local symbols instead of external. Seams the A.a are build with -fvisibility=hidden after som investigation.

But because some reason it is hard for us to got an new build library immediately, so we need some workaround. Is there any way to export those symbols as global even it has been build with -fvisibility=hidden in B.so at link time.

ZijingWu
  • 3,350
  • 3
  • 25
  • 40

1 Answers1

3

We have using nm to check those symbols

You shouldn't: on ELF platforms, nm is inadequate for the job. Use readelf -Ws instead.

it exist but list as “t” instead of “T”,which means it is local symbols instead of external. Seams the A.a are build with -fvisibility=hidden after som investigation.

Your conclusion does not follow: there are many reasons a symbol may show up as a t. Being compiled with -fvisibility=hidden is only one of many possibilities.

Is there any way to export those symbols as global even it has been build with -fvisibility=hidden

The symbol table is just a linear table of Elf{32,64}_Sym[]s. You can find the start of this table in the object file with readelf -WS foo.o | grep '\.symtab', find the number of offending symbol from readelf -Ws, and find the offset of the symbol in the foo.o by combining the two:

sym-offset = .symtab offset + (sym-number * sizeof(Sym))

Once you have the offset, you can override its .st_info with STV_DEFAULT (if your theory is correct and you located the symbol correctly, you should find STV_HIDDEN there currently).

Once you've patched your foo.o, the symbol will no longer be hidden, and when you link foo.o into B.so, it will be global / exported.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • "Once you've patched your foo.o, the symbol will no longer be hidden" - don't we need to update the hash table as well? – yugr Dec 31 '21 at 04:28
  • @yugr "once you've patched `foo.o`, when you link `foo.o` into `B.so` it will be exported" -- the linker will build the new hash table. – Employed Russian Dec 31 '21 at 05:23
  • I see, thanks. I wonder if hashtab could be patched as well (for a more realistic usecase of already linked shlib). – yugr Dec 31 '21 at 05:35
  • I've added a draft tool at https://github.com/yugr/SymbolHider . It seems to work for linked shlibs as well which is an important usecase. I'd appreciate your review/comments on proposed solution. – yugr Jan 04 '22 at 12:34
  • (the tool is for hiding symbols of course as unhiding them would require a non-trivial patching of `.dynsym` and hashtables which is probly unrealistic) – yugr Jan 04 '22 at 12:41