11

When using gcc to build a shared library, it's possible to limit the visibility of the symbols using -fvisibility=hidden. I also just learned you can limit visibility using the version-script option to ld.

Now I want to know if it's possible to combine these. Say I have a program with the following:

void foobar() {}
void say_hello() {}

Then I have the version script file with:

{
  global:
    foobar;
}

And I compile this with:

gcc -fvisibility=hidden -Wl,--version-script=<version-script> test.c -shared -o libtest.so

When I run nm on this afterwards, I find that no symbols are exported. Is there anyway that I can set the default visibility to hidden and use the version-script (or something else) to export symbols?

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
Jonathan Sternberg
  • 6,421
  • 7
  • 39
  • 58
  • In here https://gcc.gnu.org/wiki/Visibility, it says "Some people may suggest that GNU linker version scripts can do just as well. Perhaps for C programs this is true, but for C++ it cannot be true...", seems not suggested to use this. – jw_ Dec 01 '19 at 08:56

1 Answers1

12

Your question makes no sense: why fight -fvisibility with a linker script, when you can use the linker script to export exactly what you need, and hide everything else:

{
  global: foobar;
  local: *;
};

Update:

Because the code I need to use this on uses __attribute__((visibility("default"))) ...

The linker script works just fine with symbols so marked. Example:

// t.c
int __attribute__((visibility("default"))) foo() { return 1; }
int bar() { return 2; }
int __attribute__((visibility("default"))) exported() { return 3; }

// t.lds
{
  global: exported;
  local: *;
};

gcc t.c -Wl,--version-script=t.lds -fPIC -shared -o t.so && nm -D t.so
                 w _Jv_RegisterClasses
                 w __cxa_finalize
                 w __gmon_start__
00000000000004f2 T exported
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Because the code I need to use this on uses __attribute__((visibility("default"))) in the code to mark visibility sometimes, but it sometimes relies on the linker script. The way this is handled right now is just a gigantic hack and I'm trying to figure out if there's a better way to do it. – Jonathan Sternberg Nov 15 '11 at 15:32
  • Your question *still* doesn't make any sense. You may want to try to explain what your *real* question is better. – Employed Russian Nov 15 '11 at 16:04
  • 2
    Visibility annotations are preferred to linker scripts as they allow more aggressive optimization by compilers. Scripts are still needed for full trimming of external library interface due to issues in [libgcc](https://gcc.gnu.org/ml/gcc-help/2018-04/msg00097.html) and [ld](https://sourceware.org/ml/binutils/2018-04/msg00326.html). – yugr Oct 05 '18 at 21:32
  • What if I want to export all functions, but hide everything else (i.e. global variables)? Or better, just hide the globals and leave everything else unchanged. How to do that via linker script? – Dan M. Apr 29 '22 at 12:40