[cfe-dev] different gcc/clang behavior for Internal visibility
Fangrui Song via cfe-dev
cfe-dev at lists.llvm.org
Mon May 10 12:51:59 PDT 2021
On 2021-05-10, Y Song via cfe-dev wrote:
>Hi,
>
>The bpf linker project tries to explore to use INTERNAL visibility as in
> https://lore.kernel.org/bpf/20210507054119.270888-1-andrii@kernel.org/
>
>But we found clang actually changed user "internal" visibility to "hidden".
>For example, I have the following example,
>
>$ cat t.c
>int __attribute__((visibility("internal"))) foo() { return 0; }
>$ clang -c t.c && llvm-readelf -s t.o | grep foo
> 3: 0000000000000000 8 FUNC GLOBAL HIDDEN 2 foo
>$ gcc -c t.c && llvm-readelf -s t.o | grep foo
> 8: 0000000000000000 11 FUNC GLOBAL INTERNAL 1 foo
>$
>
>Looks like this is caused by clang Attr.td,
>
>diff --git a/clang/include/clang/Basic/Attr.td
>b/clang/include/clang/Basic/Attr.td
>index 5e04f32187cd..4559a1bcfe42 100644
>--- a/clang/include/clang/Basic/Attr.td
>+++ b/clang/include/clang/Basic/Attr.td
>@@ -2776,7 +2776,7 @@ def Visibility : InheritableAttr {
> let Spellings = [GCC<"visibility">];
> let Args = [EnumArgument<"Visibility", "VisibilityType",
> ["default", "hidden", "internal", "protected"],
>- ["Default", "Hidden", "Hidden", "Protected"]>];
>+ ["Default", "Hidden", "Internal", "Protected"]>];
> let MeaningfulToClassTemplateDefinition = 1;
> let Documentation = [Undocumented];
> }
>@@ -2786,7 +2786,7 @@ def TypeVisibility : InheritableAttr {
> let Spellings = [Clang<"type_visibility">];
> let Args = [EnumArgument<"Visibility", "VisibilityType",
> ["default", "hidden", "internal", "protected"],
>- ["Default", "Hidden", "Hidden", "Protected"]>];
>+ ["Default", "Hidden", "Internal", "Protected"]>];
> // let Subjects = [Tag, ObjCInterface, Namespace];
> let Documentation = [Undocumented];
> }
>
>One of early commits,
>
>commit 570024a8d9b4a4aa4a35f077a0a65003dc7b71fe
>Author: Eli Friedman <eli.friedman at gmail.com>
>Date: Thu Aug 5 06:57:20 2010 +0000
>
> Implement #pragma GCC visibility.
>
> llvm-svn: 110315
>
>I see
>
>+ else if (VisType->isStr("internal"))
>+ type = VisibilityAttr::HiddenVisibility; // FIXME
>
>Do we have any plan to support Internal visibility?
I don't think there is value supporting STV_INTERNAL.
STV_INTERNAL as we see today in the ELF specification was requested by SGI.
> The meaning of this visibility attribute may be defined by processor
> supplements to further constrain hidden symbols. A processor
> supplement's definition should be such that generic tools can safely
> treat internal symbols as hidden. An internal symbol contained in a
> relocatable object must be either removed or converted to STB_LOCAL
> binding by the link-editor when the relocatable object is included in an
> executable file or shared object.
I recall from reading somewhere that it is used by its propritery
compiler for some LTO like optimizations. STV_INTERNAL is identical to
STV_HIDDEN in GNU/Solaris (and likely HP-UX).
For the Linux kernel, my suggestion is to just use __attribute__((visibility("hidden"))).
Then there will be no confusion that "internal" translates to STV_HIDDEN.
More information about the cfe-dev
mailing list