Hiding symbol names in library

前端 未结 4 1652
天涯浪人
天涯浪人 2020-12-04 22:47

I want to hide symbol names which are not relevant to the last user and make visible only APIs in my shared or static library. I have a simple code like that:



        
4条回答
  •  囚心锁ツ
    2020-12-04 23:17

    I realize this is already an old thread. However, I'd like to share some facts about static linking in the sense of making hidden symbols local and hence prevent those symbols from (global) static linkage in an object file or static library. This does not mean making them invisible in the symbol table.

    Mike Kingham's answer is very usefull but not complete on the following detail:

    If you want to conceal f_b1 and f_b3 from static linkage in a static library, you cannot use the visibility attribute to do that at all.

    Let me show that hidden symbols can certainly be made local by using the example of the simple code in file.c and applying ypsu's answer in Symbol hiding in static libraries built with Xcode/gcc. At a first step let's reproduce the objdump output with the hidden attribute visible on f_b1 and f_b3. This can be done by the following command, which gives all functions in file.c the hidden attribute:

    gcc -fvisibility=hidden -c file.c
    

    Output of objdump -t file.o gives

    file.o:     file format elf64-x86-64
    
    SYMBOL TABLE:
    0000000000000000 l    df *ABS*  0000000000000000 file.c
    0000000000000000 l    d  .text  0000000000000000 .text
    0000000000000000 l    d  .data  0000000000000000 .data
    0000000000000000 l    d  .bss   0000000000000000 .bss
    0000000000000000 l    d  .note.GNU-stack    0000000000000000 .note.GNU-stack
    0000000000000000 l    d  .eh_frame  0000000000000000 .eh_frame
    0000000000000000 l    d  .comment   0000000000000000 .comment
    0000000000000000 g     F .text  000000000000000b .hidden f_b1
    000000000000000b g     F .text  0000000000000010 .hidden f_b3
    

    This is exactly the same intermediate result as obtained by Mike Kingham. Now let's make the symbols with the hidden attribute local. That is accomplished by using objcopy from binutils as follows:

    objcopy --localize-hidden --strip-unneeded file.o
    

    Using objdump, gives

    file.o:     file format elf64-x86-64
    
    SYMBOL TABLE:
    0000000000000000 l    d  .text  0000000000000000 .text
    0000000000000000 l     F .text  000000000000000b .hidden f_b1
    000000000000000b l     F .text  0000000000000010 .hidden f_b3
    0000000000000000 l    d  .data  0000000000000000 .data
    0000000000000000 l    d  .bss   0000000000000000 .bss
    0000000000000000 l    d  .comment   0000000000000000 .comment
    0000000000000000 l    d  .note.GNU-stack    0000000000000000 .note.GNU-stack
    0000000000000000 l    d  .eh_frame  0000000000000000 .eh_frame
    

    Likewise, nm file.o gives

    0000000000000000 t f_b1
    000000000000000b t f_b3
    

    Although f_b1 and f_b3 are still visible in the the symbol table they are local. Hence, functions f_b1 and f_b3 are concealed from static linking!

    I'd also like to add a note on declaring functions static and by that having the possibility to remove them from the symbol table completely. First, the removal can be done deterministically and not depending on compiler optimization by using objcopy.

    objcopy --strip-unneeded file.o
    

    The static functions f_b1 and f_b2 are not anymore in the symbol table of file.o.

    Secondly, this use of declaring functions static to let them disappear from the symbol table only works in single source file C-projects. As soon as a C-project consists of many components and hence files this only can be done by merging all C-source and -header files into one single source file and declare all internal interfaces (functions) static with obvious the exception of the global (top) interface. If that is not possible, one can fallback to the method originally described by ypsu (and probably many others - see for instance Restricting symbols in a Linux static library).

提交回复
热议问题