[PATCH] Allow direct access relocations referencing a protected function symbol

Fangrui Song i@maskray.me
Tue Jun 15 03:19:32 GMT 2021


On 2021-06-15, Alan Modra wrote:
>On Mon, Jun 14, 2021 at 10:43:36AM -0700, Fangrui Song wrote:
>> I shall add a note that this patch will restore the behavior before late
>> 2015 or early 2016.
>
>Also add a note that the patch you posted is incorrect.

Only the description needs an update. The code is correct.

     Treat protected function symbols local to the component like hidden/internal visibilities.
     
     This allows direct access relocations referencing a protected function symbol...

>BTW, I think it was earlier than 2015 that HJ made access to protected
>symbols in shared libraries slower in order to make access from the
>executable faster.  

There were binutils complaints in 2016 from GCC side https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248
but no GCC maintainer has paid enough attention to this issue.

>You are way too late to try to reverse that
>change in GNU ld and gcc.  (I was too late too.  By the time I raised
>objections HJ had code in gcc and binutils, and it seems no one on the
>gcc side cared about the fact that protected symbols in shared
>libraries were made virtually useless from an optimisation perspective
>on x86 and other architectures like arm that followed x86.)

I do not see why it is too late to fix GNU ld.

The GCC behavior on protected function symbols never regresses.

   __attribute__((visibility("protected"))) void *addr() { return (void *)addr; }
   
   __attribute__((visibility("protected"))) int var;
   int load() { return var; }
   
   // inlinable, i.e. no need for -fno-semantic-interposition in -fpic mode.
   __attribute__((visibility("protected"))) int inlinable(int x) { return x + x; }
   int bar(int x) { return inlinable(x); }

I have compiled the code with gcc 4.4, 4.9.4, 5.1, and 11.1, -fno-pic,-fpie and -fpic.
The only regressed case is for `load` (variable case), gcc 5 started to use unnecessary GOT.
This isn't a big deal - global variable accesses should not be in a
performance bottleneck.

Note that `inlinable` is inlinable. It doesn't need to have a branch
relocation which may lead to a JUMP_SLOT.


The main point of the patch is to make this work:

   __attribute__((visibility("protected"))) void *foo () {
     return (void *)foo;
   }

The new GNU ld behavior does suppress dynamic relocations for protected
symbols, which is a bonus.
The GCC behavior will be compatible with all of the pre-2015/2016
behavior, the 2015/2016~2021 behavior, and the future behavior.


More information about the Binutils mailing list