Search code examples
linuxgccvisibilityelfbinutils

Find out a function symbol's visibility in an object file (.o)


I only cares about default/hidden visibility.
The .o file is not compiled with IPO.

How to find out a symbol's visibility in the .o file?

Why I have to find it out from .o file:
On certain platform, I ran into a gcov.a which appears problematic.
And I have to figure out where it is wrong.
1. I cannot know how exactly the toolchain is configured and built.
2. As part of libgcc magic, figure it out from source code is extremely difficult.


Solution

  • You can find out the visibility of a symbol in an object file by examining the file's symbol table with objdump -t. If the symbol is hidden it will be labelled .hidden in the 6th field of its objdump record, followed by its name. If its visibility is default there will be no such label and the 6th field will be the name (the usual case). For example:

    foo.c (default visibility)

    #include <stdio.h>
    
    void foo(void)
    {
        puts("foo");
    }
    

    Compile and examine:

    $ gcc -c -fPIC foo.c
    $ objdump -t foo.o | grep foo
    foo.o:     file format elf64-x86-64
    0000000000000000 l    df *ABS*  0000000000000000 foo.c
    0000000000000000 g     F .text  0000000000000013 foo
    

    foo.c (hidden visibility)

    #include <stdio.h>
    
    __attribute__ ((visibility ("hidden"))) void foo(void)
    {
        puts("foo");
    }
    

    Recompile and re-examine:

    $ gcc -c -fPIC foo.c
    $ objdump -t foo.o | grep foo
    foo.o:     file format elf64-x86-64
    0000000000000000 l    df *ABS*  0000000000000000 foo.c
    0000000000000000 g     F .text  0000000000000013 .hidden foo