Seen in cmocka package: $ cat foo.h int cook(void); $ cat foo.c #include "foo.h" int __wrap_cook(void) { return 0; } $ cat bar.c int cook(void) { return -1; } $ cat main.c #include "foo.h" int main() { if (cook () == -1) __builtin_abort (); return 0; } $ gcc main.c foo.c bar.c -Wl,--wrap=cook && ./a.out (ok) $ gcc main.c foo.c bar.c -Wl,--wrap=cook -flto && ./a.out Aborted (core dumped) $ cat main.res 3 main.o 2 198 afba4c81ec45b173 PREVAILING_DEF main 215 afba4c81ec45b173 RESOLVED_IR cook foo.o 1 197 34da4dbae42a1068 PREVAILING_DEF_IRONLY __wrap_cook bar.o 1 197 d2fb0e1d62586272 PREVAILING_DEF_IRONLY cook I'm not sure there's an API for linker plugin to resolve a symbol with a deferent one. Honza?
There isn't support for this kind of replacement. I guess the resolution output could be enhanced to handle this.
Is this somehow related to the problem that the LD --wrap does not work for references internal to a translation unit? See: https://www.sourceware.org/ml/binutils/2018-12/msg00210.html https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=4ea904edb7b04ad526bd8a5401729a6c1f5a982f
One of Gentoo users rediscovered similar bug on cmocka-1.1.3 project: https://bugs.gentoo.org/675876 It exhibits as a linker failure: # LANG=C make V=1 VERBOSE=1 /usr/lib64/ccache/bin/x86_64-pc-linux-gnu-gcc -O2 -pipe -flto -fdiagnostics-show-option -frecord-gcc-switches -Wl,-O1 -Wl,--as-needed -O2 -pipe -flto -Wl,--hash-style=gnu -Wl,--wrap=uptime CMakeFiles/test_uptime.dir/test_uptime.c.o -o test_uptime -Wl,-rpath,/dev/shm/portage/dev-util/cmocka-1.1.3/work/cmocka-1.1.3-abi_x86_64.amd64/src ../../../src/libcmocka.so.0.5.1 /usr/lib/librt.so /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: /tmp/cc3ig6Xu.ltrans0.ltrans.o: in function `calc_uptime': <artificial>:(.text+0x46): undefined reference to `__wrap_uptime' collect2: error: ld returned 1 exit status Would extracting another example be useful here?
> > Would extracting another example be useful here? No, but thank you for the report. Note that bintuils has recently documented that: commit 6406a2701bda7437e879bff026adc8a5a94e87ff (HEAD, origin/master, origin/HEAD) Author: Sebastian Huber <sebastian.huber@embedded-brains.de> Date: Mon Jan 14 08:30:19 2019 +0100 ld: Add LTO warning to --wrap documentation ld/ * ld.texi (--wrap): Add warning that LTO may make this feature ineffective.
I think the basic problem is that the LD --wrap feature works only with undefined symbols references and not relocations: See also: https://www.sourceware.org/ml/binutils/2019-01/msg00204.html
*** Bug 89930 has been marked as a duplicate of this bug. ***
As noted at https://sourceware.org/bugzilla/show_bug.cgi?id=24406 this does work with clang+gold and clang+lld, but not with clang+bfd. As this does not work with gcc+gold, the problem is not in the linker.
A linker patch is posted at https://sourceware.org/ml/binutils/2019-04/msg00018.html But it won't work with -O2 since LTO inlines cook before linker can wrap it.
With the patch applied to ld.bfd “clang -flto -fuse-ld=bfd -Wl,--wrap=read t.c” does work.
With the patch applied this works: clang -flto -fuse-ld=bfd -Wl,--wrap=read -O3 t.c gcc -flto -fuse-ld=bfd -Wl,--wrap=read -O3 t.c gcc -flto -fuse-ld=bfd -Wl,--wrap=read -O2 t.c gcc -flto -fuse-ld=bfd -Wl,--wrap=read -O1 t.c This does not work: gcc -flto -fuse-ld=gold -Wl,--wrap=read -O3 t.c gcc -flto -fuse-ld=gold -Wl,--wrap=read -O2 t.c gcc -flto -fuse-ld=gold -Wl,--wrap=read -O1 t.c
Reported for ld.gold at https://sourceware.org/bugzilla/show_bug.cgi?id=24415 .
Since GCC does work but not with gold, the bug is in gold. I am going to close this as moved. https://sourceware.org/bugzilla/show_bug.cgi?id=24415 records the binutils/gold bug.
*** Bug 115953 has been marked as a duplicate of this bug. ***
Just to note with BFD ld from 2.41.0 I see 1 a-t.o 3 194 b4b00c6ef6ad050b PREVAILING_DEF_IRONLY __wrap_cook 198 b4b00c6ef6ad050b PREVAILING_DEF main 214 b4b00c6ef6ad050b RESOLVED_IR cook when building int cook(void); int __wrap_cook(void) { return 0; } int main() { if (cook () == -1) __builtin_abort (); return 0; } but an LTO link fails with /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: ./a.ltrans0.ltrans.o: in function `main': <artificial>:(.text+0x10): undefined reference to `__wrap_cook' GCC emits at LTRANS stage .file "<artificial>" .text .type __wrap_cook, @function __wrap_cook: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size __wrap_cook, .-__wrap_cook .globl main .type main, @function main: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 call cook cmpl $-1, %eax jne .L4 call abort .L4: movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret which I think should be OK. The main difference is that __wrap_cook is an internal symbol but that's OK since the linker told GCC 194 b4b00c6ef6ad050b PREVAILING_DEF_IRONLY __wrap_cook it probably should have used 194 b4b00c6ef6ad050b PREVAILING_DEF __wrap_cook instead.
H.J. has fixed this for upcoming binutils-2.43.