Internal visibility


In GCC on Linux on Power, -fvisibility=internal enables internal

$ cat t.c
int foo(int i) { return i + 1; }
$ gcc t.c -c -fvisibility=internal
$ readelf -s t.o | grep foo
     8: 0000000000000000 60 FUNC GLOBAL INTERNAL 1 foo

But in Clang/LLVM, GlobalValue::VisibilityTypes does not have internal

  /// An enumeration for the kinds of visibility of global values.
  enum VisibilityTypes {
    DefaultVisibility = 0, ///< The GV is visible
    HiddenVisibility, ///< The GV is hidden
    ProtectedVisibility ///< The GV is protected

and using -fvisibility=internal in Clang uses the
close-but-not-quite-the-same hidden visibility:

$ clang t.c -c -fvisibility=internal
$ readelf -s t.o | grep foo
     2: 0000000000000000 36 FUNC GLOBAL HIDDEN 2 foo

Given that -fvisibility=internal is accepted, I assume this behaviour is
intentional. Can anyone help me understand why that is, or point me to
where I can find out more?



I don’t think there’s any technical reason not to add support for internal visibility. In 2015, I added the alias in clang:

$ git show 7737bd9f9fb5d9cfd5717f36791036fa08d57b95
commit 7737bd9f9fb5d9cfd5717f36791036fa08d57b95
Author: Reid Kleckner <>

[Driver] Alias -fvisibility=internal to -fvisibility=hidden

The ELF symbol visibilities are:

  • internal: Not visibile across DSOs, cannot pass address across DSOs
  • hidden: Not visibile across DSOs, can be called indirectly
  • default: Usually visible across DSOs, possibly interposable
  • protected: Visible across DSOs, not interposable

LLVM only supports the latter 3 visibilities. Internal visibility is in
theory useful, as it allows you to assume that the caller is maintaining
a PIC register for you in %ebx, or in some other pre-arranged location.
As far as LLVM is concerned, this isn’t worth the trouble. Using hidden
visibility is always correct, so we can just do that.

Resolves PR9183.

llvm-svn: 250954

While I did say “As far as LLVM is concerned, this isn’t worth the trouble.”, but that was mostly just a reflection of the fact that I filed this bug in 2011 and it never got any attention:

Given what I know about how PIC code works for PPC, it seems like it might be worth someone’s time to add this visibility mode.