<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/64488>64488</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Creating hidden-visibility function symbol alias does not lead to shortened (jmp rather than jmpq) jumps where possible unlike on gcc (SysV x86-64 ABI) 
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          pskocik
      </td>
    </tr>
</table>

<pre>
    I've been experimenting with a technique from https://www.cs.dartmouth.edu/~sergey/cs258/ABI/UlrichDrepper-How-To-Write-Shared-Libraries.pdf on using hidden-visibility aliases for intra-library function calls in order to prevent such calls from being routed through the PLT.

On both compilers, hidden aliases succeed at preventing calls through them from being routed through the PLT, however, gcc also makes such calls short (jmp rather than jmpq) where possible, whereas clang fails to do this unless the real function from which the hidden alias was made was static.

Example:

```
#include <stdio.h>

#define $hid extern __attribute((visibility("hidden")))
#define $noinl __attribute((__noinline__))

$noinl void foo(void);
$hid $noinl void foo_hid(void);
static $noinl void foo_static(void);
$noinl void foo(void){ puts("B"); }
__attribute((alias("foo"),visibility("hidden"))) void foo_hid(void);
static __attribute((alias("foo"))) void foo_static(void);
$noinl  void callfoo(void){ foo(); } //thru PLT
$noinl  void callfoo_hid(void){ foo_hid(); } //direct but on clang (not gcc) unnecessarily jmpq rather than jmp
$noinl  void callfoo_static(void){ foo_static(); } //direct and a short jmp


static $noinl void bar_static(void);
$noinl void bar(void);
$hid $noinl void bar_hid(void);
$noinl static void bar_static(void){ puts("A"); }
__attribute((alias("bar_static"),visibility("hidden"))) void bar_hid(void);
__attribute((alias("bar_static"),visibility("default"))) void bar(void);
$noinl  void callbar(void){ bar(); } //thru PLT
$noinl void callbar_hid(void){ bar_hid(); } //direct and a short jmp
$noinl  void callbar_static(void){ bar_static(); } //direct and a short jmp

```

Upon compiling the above, linking it to a shared library and inspecting,  callbar is routed through the PLT, and callbar_hid and callbar_static are direct and short on both compilers. However, for foo, which doesn't start out static, the equivalent is true only on gcc.
On clang, callfoo_hid is unnecessarily a long  (jmpq) direct jump, although it could have been short (jmp).


```
$ gcc -fpic hidden_alias.c -O2 -shared -o a.out  && objdump -drw a.out |grep -A1 'call\(foo\|bar\)'

0000000000001140 <callfoo>:
    1140:       e9 0b ff ff ff          jmpq   1050 <foo@plt>
--
0000000000001150 <callfoo_hid>:
    1150:       eb de                   jmp    1130 <foo>
--
0000000000001160 <callfoo_static>:
    1160:       eb ce   jmp    1130 <foo>
--
0000000000001180 <callbar>:
 1180:  e9 bb fe ff ff          jmpq   1040 <bar@plt>
--
0000000000001190 <callbar_hid>:
    1190:       eb de                   jmp    1170 <bar>
--
00000000000011a0 <callbar_static>:
    11a0:       eb ce   jmp    1170 <bar>

$ clang -fpic hidden_alias.c -O2 -shared -o a.out  && objdump -drw a.out |grep -A1 'call\(foo\|bar\)' 

0000000000001140 <callfoo>:
    1140:       e9 0b ff ff ff          jmpq 1050 <foo@plt>
--
0000000000001150 <callfoo_hid>:
    1150:       e9 db ff ff ff          jmpq   1130 <foo>
--
0000000000001160 <callfoo_static>:
    1160:       eb ce                   jmp    1130 <foo>
--
0000000000001180 <callbar>:
    1180:       e9 bb fe ff ff  jmpq   1040 <bar@plt>
--
0000000000001190 <callbar_hid>:
 1190:  eb de                   jmp    1170 <bar>
--
00000000000011a0 <callbar_static>:
    11a0:       eb ce                   jmp    1170 <bar>

```




</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWM1u4zgSfhr6UpAhU_7TwYfEaWMGGKAXmJndY0CRJYsJRapJKu5c9tkXpGRbjn_aPbvBjiEoEcmqr6pUxfpE5pzcasQVmT2S2dOItb4ydtW4V8Pl66gw4n31K6GLN4QCUQN-b9DKGrWXegs76Stg4JFXWn5rEUpraqi8bxzJHgjdELrZ7XZj7saCWV-b1ldjFC2hm387tFt8J3TDHZ0tCd08PP5K6OZPZSWvniw2DdrkF7NL_jDJv6z0mPxeMYsi-U0WllmJbtyIEoyG1gVbKikE6uRNOllIJf07MCWZQwelsSC1tyxRUfQdylZzL40GzpRyIDUYK9CCN9BYfEPtwbW86qejUwUGEGtajwJ8ZU27rcBXCP_47Y8xSZ9I-tDdv2oojK-Am7qRCq0jdN0bd7DItZwjCmB-jxeUd2gD3fWPoaNys8M3tOHfLefAlDNQs9cOZ--Eq4z1QOjypW7AMl8Fdyum4aVuvhGaw65Ci9AY52ShMCiLI8wBV0xvoWQyWGdAGPCVdNBqhc5FQywydQxqNHpXSd5ZOfQddsxBzQTGf5xnXvKT6H35zupGYciewSiZp_3VPdJMaq5agUCytfNCmnFFsi8nIjQTWEqNQOi0kgLwu0er4fmZeW9l0XokdEno8pgw8Zl25hJKCc3761yhNlKrc13Pz3FCanx-PpHtNfRyb0YKKI0J6EaKsCx7PKwJxp4tfa7CurPlXQQvLO8mLgNcNWLxCE3rXReHxz4E2SOQxVMnfOZwfKnd-qiqC9r6xzG907E7AU81_tj3bm0ojLMAdANHx6HbxXxl21hvNxR9cKVT1g-eKRTSIvdQtD5sYV2JEbrUxociDv60WiNH55iV6j2W6ce6vWnMWRR6ew7j10xiWgDr94sjyOB-MekKZu9NuoLZezM_aL2cIId1vTXXjTjJ6oefzOqhxp9M7uu2_5eAAkvWKn8R8b6sP124eOwl7836oZ7zpD8O_lyGXTTz4us8Gf8rafyhncT7n02ow9i0Q7sNnYsV5i12QiX1axiUPjTAoDUwEdjTiQAltWuQhz4eBPbmg3Q3GneQG4Tx5LlPa2YRBg517piPFGMMvxw5QKA7cRdb901YGHSa0IUPtRLEWw_78K2jPfitlW9MBd4jHXjbIhit3gPQlu8b9Nd-mwpCgx0PIhUYblUMlNFb6MlGJBe9Cy9t3UTHla9iMKQHbloloGJ7hjkkKoTm4_P954wNTCPvScpG8p5tPMeKGnNIvlJI-teVGGDj4DwQOid0DqZ4EW3dQCLsrp8ii_XWYgPJwwQIXQQ_yWxN6DJEdLYmi3UolTCSE7oYWpUOfpPJNA3UZN9hsi8HQgMAEKbjQI45pAWUZX91P5LmcbcHmKSzqCfomKaN8geSkySXUGdD1FiEZ8izPXIBAuHDr0PuFmYH5NuY8xPMPq_OYOdHWI5_CWd5wAlvYAgQ5g7hLAoo8Wo4u9cSFNwTznwIeTmc-b3hXByQb2OyE8xr4WRXw3mOc6ySjmX8H-oEPrdQPrNMchC3CvRTy-R_UJ3XqyaquVI4n1Uyf5N6-SnYG5RheB-JVSbyLGcjXE3m-WSazrPFbFStOOPzEukiK3M-EYXgtMiyYiaycjZfZrwcyRVNaZYu08Vkks4nszFN53RJ86IseJ4JWpJpijWTaqzUWz02djuSzrW4mk-ny-VIsQKVi-c3lGrcQZwM5HD2NLKrIJMU7daRaaqk8-6oxUuvcLW2yPzlA5TDF717rwuj-k_4QCcgfKcoZCLwodixUaO4dbwQWr_7cMgArVbyFXuaEaR_f3f_hO_LeTKfQjwPymHUWrU6PVLaSl-1xZibmtBNcKf_kzTWvCD3hG5iEByhmxik_wQAAP__Dp6KYQ">