[llvm-dev] wrap with symver and LTO
Fangrui Song via llvm-dev
llvm-dev at lists.llvm.org
Sat Jul 24 14:00:01 PDT 2021
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.
More information about the llvm-dev
mailing list