<div dir="ltr">IIRC, internal visibility is a guarantee that a function is not escaped and called indirectly from another DSO. This allows the compiler to avoid setting up a TOC or PIC base register in the prologue for architectures that have one. This was notably expensive for x86_32 because of the call/pop code sequence required to materialize EIP. There are other RISC-y architectures (PPC? 64? not sure) with PIC base registers that could benefit from internal visibility support, but I think most of them are considered legacy architectures at this point, so it's not top priority.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, May 10, 2021 at 12:52 PM Fangrui Song via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 2021-05-10, Y Song via cfe-dev wrote:<br>
>Hi,<br>
><br>
>The bpf linker project tries to explore to use INTERNAL visibility as in<br>
> <a href="https://lore.kernel.org/bpf/20210507054119.270888-1-andrii@kernel.org/" rel="noreferrer" target="_blank">https://lore.kernel.org/bpf/20210507054119.270888-1-andrii@kernel.org/</a><br>
><br>
>But we found clang actually changed user "internal" visibility to "hidden".<br>
>For example, I have the following example,<br>
><br>
>$ cat t.c<br>
>int __attribute__((visibility("internal"))) foo() { return 0; }<br>
>$ clang -c t.c && llvm-readelf -s t.o | grep foo<br>
> 3: 0000000000000000 8 FUNC GLOBAL HIDDEN 2 foo<br>
>$ gcc -c t.c && llvm-readelf -s t.o | grep foo<br>
> 8: 0000000000000000 11 FUNC GLOBAL INTERNAL 1 foo<br>
>$<br>
><br>
>Looks like this is caused by clang Attr.td,<br>
><br>
>diff --git a/clang/include/clang/Basic/Attr.td<br>
>b/clang/include/clang/Basic/Attr.td<br>
>index 5e04f32187cd..4559a1bcfe42 100644<br>
>--- a/clang/include/clang/Basic/Attr.td<br>
>+++ b/clang/include/clang/Basic/Attr.td<br>
>@@ -2776,7 +2776,7 @@ def Visibility : InheritableAttr {<br>
> let Spellings = [GCC<"visibility">];<br>
> let Args = [EnumArgument<"Visibility", "VisibilityType",<br>
> ["default", "hidden", "internal", "protected"],<br>
>- ["Default", "Hidden", "Hidden", "Protected"]>];<br>
>+ ["Default", "Hidden", "Internal", "Protected"]>];<br>
> let MeaningfulToClassTemplateDefinition = 1;<br>
> let Documentation = [Undocumented];<br>
> }<br>
>@@ -2786,7 +2786,7 @@ def TypeVisibility : InheritableAttr {<br>
> let Spellings = [Clang<"type_visibility">];<br>
> let Args = [EnumArgument<"Visibility", "VisibilityType",<br>
> ["default", "hidden", "internal", "protected"],<br>
>- ["Default", "Hidden", "Hidden", "Protected"]>];<br>
>+ ["Default", "Hidden", "Internal", "Protected"]>];<br>
> // let Subjects = [Tag, ObjCInterface, Namespace];<br>
> let Documentation = [Undocumented];<br>
> }<br>
><br>
>One of early commits,<br>
><br>
>commit 570024a8d9b4a4aa4a35f077a0a65003dc7b71fe<br>
>Author: Eli Friedman <<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>><br>
>Date: Thu Aug 5 06:57:20 2010 +0000<br>
><br>
> Implement #pragma GCC visibility.<br>
><br>
> llvm-svn: 110315<br>
><br>
>I see<br>
><br>
>+ else if (VisType->isStr("internal"))<br>
>+ type = VisibilityAttr::HiddenVisibility; // FIXME<br>
><br>
>Do we have any plan to support Internal visibility?<br>
<br>
I don't think there is value supporting STV_INTERNAL.<br>
<br>
STV_INTERNAL as we see today in the ELF specification was requested by SGI.<br>
<br>
> The meaning of this visibility attribute may be defined by processor<br>
> supplements to further constrain hidden symbols. A processor<br>
> supplement's definition should be such that generic tools can safely<br>
> treat internal symbols as hidden. An internal symbol contained in a<br>
> relocatable object must be either removed or converted to STB_LOCAL<br>
> binding by the link-editor when the relocatable object is included in an<br>
> executable file or shared object.<br>
<br>
I recall from reading somewhere that it is used by its propritery<br>
compiler for some LTO like optimizations. STV_INTERNAL is identical to<br>
STV_HIDDEN in GNU/Solaris (and likely HP-UX).<br>
<br>
For the Linux kernel, my suggestion is to just use __attribute__((visibility("hidden"))).<br>
Then there will be no confusion that "internal" translates to STV_HIDDEN.<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>