[lld] a6ae333 - [ELF] --wrap: don't error `undefined reference to __real_foo` (--no-allow-shlib-undefined) if foo is a wrapped definition

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 1 23:01:01 PDT 2020


Author: Fangrui Song
Date: 2020-06-01T23:00:51-07:00
New Revision: a6ae333a0c23fc9b0783ca45e2676abac00c6723

URL: https://github.com/llvm/llvm-project/commit/a6ae333a0c23fc9b0783ca45e2676abac00c6723
DIFF: https://github.com/llvm/llvm-project/commit/a6ae333a0c23fc9b0783ca45e2676abac00c6723.diff

LOG: [ELF] --wrap: don't error `undefined reference to __real_foo` (--no-allow-shlib-undefined) if foo is a wrapped definition

This is a regression after D51283.

Also, export `foo` if `__real_foo` is referenced by a shared object.

Added: 
    lld/test/ELF/wrap-shlib-undefined.s

Modified: 
    lld/ELF/SymbolTable.cpp
    lld/test/ELF/wrap-dynamic-undef.s
    lld/test/ELF/wrap-no-real.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 2097234f1adb..f0a6af437c5f 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -40,6 +40,9 @@ void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
   idx2 = idx1;
   idx1 = idx3;
 
+  if (real->exportDynamic)
+    sym->exportDynamic = true;
+
   // Now renaming is complete, and no one refers to real. We drop real from
   // .symtab and .dynsym. If real is undefined, it is important that we don't
   // leave it in .dynsym, because otherwise it might lead to an undefined symbol
@@ -47,6 +50,7 @@ void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
   // alias for sym, but that could degrade the user experience of some tools
   // that can print out only one symbol for each location: sym is a preferred
   // name than real, but they might print out real instead.
+  memcpy(real, sym, sizeof(SymbolUnion));
   real->isUsedInRegularObj = false;
 }
 

diff  --git a/lld/test/ELF/wrap-dynamic-undef.s b/lld/test/ELF/wrap-dynamic-undef.s
index 50ada2d5e556..2abb826411b3 100644
--- a/lld/test/ELF/wrap-dynamic-undef.s
+++ b/lld/test/ELF/wrap-dynamic-undef.s
@@ -8,7 +8,10 @@
 # Test that the dynamic relocation uses foo. We used to produce a
 # relocation with __real_foo.
 
-# CHECK: NOTYPE  GLOBAL DEFAULT UND foo
+# CHECK:      Symbol table '.dynsym' contains 3 entries:
+# CHECK:      NOTYPE  LOCAL  DEFAULT  UND
+# CHECK-NEXT: NOTYPE  GLOBAL DEFAULT  UND foo
+# CHECK-NEXT: NOTYPE  GLOBAL DEFAULT  UND __wrap_foo
 
 .global _start
 _start:

diff  --git a/lld/test/ELF/wrap-no-real.s b/lld/test/ELF/wrap-no-real.s
index 43d94cf91f8a..0078611a79be 100644
--- a/lld/test/ELF/wrap-no-real.s
+++ b/lld/test/ELF/wrap-no-real.s
@@ -23,9 +23,9 @@
 // RUN: llvm-readelf -s -x .got %t2 | FileCheck --check-prefix=READELF --implicit-check-not=__real_ %s
 
 // CHECK2: <_start>:
-// CHECK2-NEXT: movq {{.*}}(%rip), %rax  # 2022b8
-// CHECK2-NEXT: movq {{.*}}(%rip), %rbx  # 2022b8
-// CHECK2-NEXT: movq {{.*}}(%rip), %rcx  # 2022c0
+// CHECK2-NEXT: movq {{.*}}(%rip), %rax  # 2022e0
+// CHECK2-NEXT: movq {{.*}}(%rip), %rbx  # 2022e0
+// CHECK2-NEXT: movq {{.*}}(%rip), %rcx  # 2022e8
 
 .global _start
 _start:

diff  --git a/lld/test/ELF/wrap-shlib-undefined.s b/lld/test/ELF/wrap-shlib-undefined.s
new file mode 100644
index 000000000000..c9c4abeb35fa
--- /dev/null
+++ b/lld/test/ELF/wrap-shlib-undefined.s
@@ -0,0 +1,26 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: echo '.globl bar; bar: call __real_foo' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
+# RUN: ld.lld -shared -soname=t.so %t1.o -o %t.so
+
+## --no-allow-shlib-undefined errors because __real_foo is not defined.
+# RUN: not ld.lld %t.o %t.so -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s
+# ERR: undefined reference to __real_foo
+
+## --wrap=foo defines __real_foo.
+# RUN: ld.lld %t.o %t.so --wrap=foo -o %t
+# RUN: llvm-readelf --dyn-syms %t | FileCheck %s
+
+## FIXME GNU ld does not export __wrap_foo
+## The reference __real_foo from %t.so causes foo to be exported.
+# CHECK:      Symbol table '.dynsym' contains 4 entries:
+# CHECK:      NOTYPE  LOCAL  DEFAULT  UND
+# CHECK-NEXT: NOTYPE  GLOBAL DEFAULT  UND bar
+# CHECK-NEXT: NOTYPE  GLOBAL DEFAULT  UND __wrap_foo
+# CHECK-NEXT: NOTYPE  GLOBAL DEFAULT    6 foo
+
+.globl _start, foo
+_start:
+  call bar
+foo:


        


More information about the llvm-commits mailing list