]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
LTO: Restore the wrapper symbol check for standard function
authorH.J. Lu <hjl.tools@gmail.com>
Sat, 3 Aug 2024 02:52:00 +0000 (19:52 -0700)
committerAlan Modra <amodra@gmail.com>
Sat, 3 Aug 2024 04:22:38 +0000 (13:52 +0930)
Call unwrap_hash_lookup to restore the wrapper symbol check for standard
function since reference to standard function may not show up in LTO
symbol table:

[hjl@gnu-tgl-3 pr31956-3]$ nm foo.o
00000000 T main
         U __real_malloc
00000000 T __wrap_malloc
[hjl@gnu-tgl-3 pr31956-3]$  lto-dump -list foo.o
Type   Visibility  Size  Name
function  default     0  malloc
function  default     0  __real_malloc
function  default     3  main
function  default     5  __wrap_malloc
[hjl@gnu-tgl-3 pr31956-3]$ make
gcc -O2 -flto -Wall   -c -o foo.o foo.c
gcc -Wl,--wrap=malloc -O2 -flto -Wall -o x foo.o
/usr/local/bin/ld: /tmp/ccsPW0a9.ltrans0.ltrans.o: in function `main':
<artificial>:(.text.startup+0xa): undefined reference to `__wrap_malloc'
collect2: error: ld returned 1 exit status
make: *** [Makefile:22: x] Error 1
[hjl@gnu-tgl-3 pr31956-3]$

Also add a test to verify that the unused wrapper is removed.

PR ld/31956
* plugin.c (get_symbols): Restore the wrapper symbol check for
standard function.
* testsuite/ld-plugin/lto.exp: Run the malloc test and the
unused test.
* testsuite/ld-plugin/pr31956c.c: New file.
* testsuite/ld-plugin/pr31956d.c: New file.
* testsuite/ld-plugin/pr31956d.d: New file.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
ld/plugin.c
ld/testsuite/ld-plugin/lto.exp
ld/testsuite/ld-plugin/pr31956c.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr31956d.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr31956d.d [new file with mode: 0644]

index 03ee9880d104512781aeba5ca8433c25a437ede3..51c4765cc5b5ca5ea8679bf2af3e2d19678b37b5 100644 (file)
@@ -778,8 +778,18 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
        {
          blhe = h;
          /* Check if a symbol is a wrapper symbol.  */
-         if (blhe && blhe->wrapper_symbol)
-           wrap_status = wrapper;
+         if (blhe)
+           {
+             if (blhe->wrapper_symbol)
+               wrap_status = wrapper;
+             else if (link_info.wrap_hash != NULL)
+               {
+                 struct bfd_link_hash_entry *unwrap
+                   = unwrap_hash_lookup (&link_info, (bfd *) abfd, blhe);
+                 if (unwrap != NULL && unwrap != h)
+                   wrap_status = wrapper;
+               }
+           }
        }
       else
        {
index ad59e2abd61fdf97b8e559f37982695685c278ad..1a8c3736307fdf51dfad5ddaa3cbf90b0d441550 100644 (file)
@@ -546,6 +546,22 @@ set lto_link_elf_tests [list \
    {} \
    "pr31956b" \
   ] \
+  [list \
+   "PR ld/31956 (malloc)" \
+   "-Wl,--wrap=malloc" \
+   "-O2 -flto" \
+   {pr31956c.c} \
+   {} \
+   "pr31956c" \
+  ] \
+  [list \
+   "PR ld/31956 (unused)" \
+   "-Wl,--wrap=parse_line" \
+   "-O2 -flto" \
+   {pr31956d.c} \
+   {{"nm" {} "pr31956d.d"}} \
+   "pr31956d" \
+  ] \
   [list \
    "Build pr30281.so" \
    "-shared -Wl,--version-script,pr30281.t \
diff --git a/ld/testsuite/ld-plugin/pr31956c.c b/ld/testsuite/ld-plugin/pr31956c.c
new file mode 100644 (file)
index 0000000..4a46b2b
--- /dev/null
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+
+extern void *__real_malloc (size_t);
+
+void *
+__wrap_malloc (size_t n)
+{
+  if (n == 0)
+    return NULL;
+  else
+    return __real_malloc (n);
+};
+
+int
+main (void)
+{
+  void *ptr = malloc (30);
+  return ptr == NULL ? 1 : 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr31956d.c b/ld/testsuite/ld-plugin/pr31956d.c
new file mode 100644 (file)
index 0000000..cb7f2d5
--- /dev/null
@@ -0,0 +1,7 @@
+void __wrap_parse_line(void) {};
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr31956d.d b/ld/testsuite/ld-plugin/pr31956d.d
new file mode 100644 (file)
index 0000000..b579cdc
--- /dev/null
@@ -0,0 +1,4 @@
+#failif
+#...
+[0-9a-f]+ T .*parse_line
+#...