<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">