[llvm-dev] wrap with symver and LTO

Fangrui Song via llvm-dev
2021-07-24T21:00:01Z

On 2021-07-24, Gilles Vollant via llvm-dev wrote:
>Hello,
>
>
>
>I've a c++ program  which use log function
>
>
>
>
>
>When I compile under Ubuntu 20.04 (or Debian 11 frezze version), the binary
>is linked to function log of GLIBC 2.29
>
>I need distribute the binary to Ubuntu 18.04 (and 16.04) computer.
>
>
>
>My first solution is
>
>
>
>which I compile with clang 12 on Ubuntu 20.04 (or Debian 11 frezze version).
>
>
>
>(Somes peoples had same problem with memcpy)
>
>https://stackoverflow.com/questions/8823267/linking-against-older-symbol-ver
>sion-in-a-so-file
>
>https://stackoverflow.com/questions/36461555/is-it-possible-to-statically-li
>nk-libstdc-and-wrap-memcpy
>
>https://gist.github.com/nicky-zs/7541169
>
>
>
>So I add this switch on link command line: -Wl,--wrap=log
>
>
>
>And I compile in a .C file:
>
>
>
>
>
>double __log_glibc_2_2_5(double x);
>
>asm(".symver __log_glibc_2_2_5, log at GLIBC_2.2.5 <mailto:log at
GLIBC_2.2.5> ");
>
>
>
>double __wrap_log(double x)
>
>{
>
>    return __log_glibc_2_2_5(x);
>
>}
>
>
>
>
>
>This is perfect Clang WITHOUT Link Time Optimisation. The solution is also
>fine with GCC (with and without LTO)
>
>With Clang+LTO, the first call of log do an infinite loop and program never
>stop
>
>.
>
>My workaround with clang LTO is using a more complex dlopen/dlsym stuff in
>my __wrap_log function.
>
>
>
>
>
>Do you think there is a possible solution?
>
>
>
>Regards
>
>Gilles Vollant


//--- a.c
#include <stdio.h>
#include <math.h>

double __log_glibc_2_2_5(double x);

asm(".symver __log_glibc_2_2_5, log at GLIBC_2.2.5");

double __wrap_log(double x) {
   return __log_glibc_2_2_5(x);
}
//--- b.c
#include <stdio.h>
#include <math.h>

int main() {
   printf("%lf\n", log(3.0));
}


% clang a.c b.c -lm -Wl,--wrap=log -flto=thin -fuse-ld=lld -o a.lld &&
./a.lld
1.098612
% clang a.c b.c -lm -Wl,--wrap=log -flto=thin -fuse-ld=bfd -o a.bfd &&
./a.bfd
1.098612
% clang a.c b.c -lm -Wl,--wrap=log -flto=thin -fuse-ld=gold -o a.gold &&
./a.gold
[1]    805257 segmentation fault  ./a.gold


In gold, --wrap=log seems to apply to a non-default version symbol log at
GLIBC_2.2.5 .
I consider it a bug.


Note: ld.lld's --wrap has another difference with GNU linkers
https://sourceware.org/bugzilla/show_bug.cgi?id=26358
I personally think ld.lld's is superior because LTO, non-LTO and relocatable
links behave the same.