[lld] Provide a hook to customize undefined symbols error handling
authorserge-sans-paille <sguelton@redhat.com>
Mon, 19 Oct 2020 11:21:23 +0000 (13:21 +0200)
committerserge-sans-paille <sguelton@redhat.com>
Mon, 9 Nov 2020 12:28:48 +0000 (13:28 +0100)
This is a follow up to https://reviews.llvm.org/D87758, implementing the missing
symbol part, as done by binutils.

Differential Revision: https://reviews.llvm.org/D89687

lld/Common/ErrorHandler.cpp
lld/ELF/Relocations.cpp
lld/docs/error_handling_script.rst
lld/docs/ld.lld.1
lld/include/lld/Common/ErrorHandler.h
lld/test/ELF/error-handling-script-linux.test

index 0e32fc5..41122e8 100644 (file)
@@ -239,6 +239,9 @@ void ErrorHandler::error(const Twine &msg, ErrorTag tag,
   case ErrorTag::LibNotFound:
     scriptArgs.push_back("missing-lib");
     break;
+  case ErrorTag::SymbolNotFound:
+    scriptArgs.push_back("undefined-symbol");
+    break;
   }
   scriptArgs.insert(scriptArgs.end(), args.begin(), args.end());
   int res = llvm::sys::ExecuteAndWait(errorHandlingScript, scriptArgs);
index 3a97715..abb21f1 100644 (file)
@@ -919,7 +919,7 @@ static void reportUndefinedSymbol(const UndefinedDiag &undef,
   if (undef.isWarning)
     warn(msg);
   else
-    error(msg);
+    error(msg, ErrorTag::SymbolNotFound, {sym.getName()});
 }
 
 template <class ELFT> void elf::reportUndefinedSymbols() {
index 30905cd..53efa8b 100644 (file)
@@ -27,6 +27,10 @@ The following tags are supported:
   is specified as the second argument, e.g. ``error-handling-script missing-lib
   mylib``
 
+- ``undefined-symbol``: indicates that given symbol is marked as undefined. The
+  unmangled symbol name is specified as the second argument, e.g.
+  ``error-handling-script undefined-symbol mysymbol``
+
 Return Value
 ============
 
index 0de278a..538d09d 100644 (file)
@@ -192,6 +192,8 @@ expected to return 0 on success. Any other value is considered a generic error.
 may be
 .Cm missing-lib
 followed by the name of the missing library.
+.Cm undefined-symbol
+followed by the name of the undefined symbol.
 .It Fl -execute-only
 Mark executable sections unreadable.
 This option is currently only supported on AArch64.
index 64f3630..4460452 100644 (file)
@@ -89,7 +89,7 @@ extern llvm::raw_ostream *stderrOS;
 llvm::raw_ostream &outs();
 llvm::raw_ostream &errs();
 
-enum class ErrorTag { LibNotFound };
+enum class ErrorTag { LibNotFound, SymbolNotFound };
 
 class ErrorHandler {
 public:
index c499680..54e1b29 100755 (executable)
@@ -2,16 +2,45 @@
 # REQUIRES: x86
 # UNSUPPORTED: system-windows
 
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t0.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64 /dev/null -o %t0.o
 # RUN: not ld.lld -o /dev/null -lidontexist --error-handling-script=%s %t0.o 2>&1 |\
 # RUN:   FileCheck --check-prefix=CHECK-LIB %s
 # RUN: not ld.lld -o /dev/null -lidontexist --error-handling-script=%s.nope %t0.o 2>&1 |\
 # RUN:   FileCheck --check-prefix=CHECK-SCRIPT-DOES-NOT-EXIST -DFILE=%s.nope %s
 
+# RUN: echo 'bar: movl a(%rip), %eax' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
+# RUN: not ld.lld -o /dev/null --error-handling-script=%s %t1.o 2>&1 |\
+# RUN:   FileCheck --check-prefix=CHECK-SYM-C %s
+
+# RUN: echo 'bar: movl _Z1av(%rip), %eax' | llvm-mc -filetype=obj -triple=x86_64 - -o %t2.o
+# RUN: not ld.lld -o /dev/null --demangle --error-handling-script=%s %t2.o 2>&1 |\
+# RUN:   FileCheck --check-prefix=CHECK-SYM-CXX-DEMANGLE %s
+# RUN: not ld.lld -o /dev/null --no-demangle --error-handling-script=%s %t2.o 2>&1 |\
+# RUN:   FileCheck --check-prefix=CHECK-SYM-CXX-NO-DEMANGLE %s
+
+# RUN: { echo 'a_: ret'; echo 'bar: movl a(%rip), %eax' ; } | llvm-mc -filetype=obj -triple=x86_64 - -o %t3.o
+# RUN: not ld.lld -o /dev/null --error-handling-script=%s %t3.o 2>&1 |\
+# RUN:   FileCheck --check-prefix=CHECK-SYM-C-CORRECTION -DOBJ=%t3.o %s
+
 # CHECK-LIB:      script: info: called with missing-lib idontexist
 # CHECK-LIB-NEXT: ld.lld: error: unable to find library -lidontexist
 
 # CHECK-SCRIPT-DOES-NOT-EXIST:      ld.lld: error: unable to find library -lidontexist
 # CHECK-SCRIPT-DOES-NOT-EXIST-NEXT: ld.lld: error: error handling script '[[FILE]]' failed to execute
 
+# CHECK-SYM-C:      script: info: called with undefined-symbol a
+# CHECK-SYM-C-NEXT: ld.lld: error: undefined symbol: a
+
+# CHECK-SYM-CXX-DEMANGLE:      script: info: called with undefined-symbol _Z1av
+# CHECK-SYM-CXX-DEMANGLE-NEXT: ld.lld: error: undefined symbol: a()
+
+# CHECK-SYM-CXX-NO-DEMANGLE:      script: info: called with undefined-symbol _Z1av
+# CHECK-SYM-CXX-NO-DEMANGLE-NEXT: ld.lld: error: undefined symbol: _Z1av
+
+# CHECK-SYM-C-CORRECTION:      script: info: called with undefined-symbol a
+# CHECK-SYM-C-CORRECTION-NEXT: ld.lld: error: undefined symbol: a
+# CHECK-SYM-C-CORRECTION-NEXT: >>> referenced by [[OBJ]]:
+# CHECK-SYM-C-CORRECTION-NEXT: >>> did you mean: a_
+
+
 echo "script: info: called with $*"