Skip to content

Commit

Permalink
[lld] Provide a hook to customize undefined symbols error handling
Browse files Browse the repository at this point in the history
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
  • Loading branch information
serge-sans-paille committed Nov 9, 2020
1 parent 28fc173 commit 1e70ec1
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 3 deletions.
3 changes: 3 additions & 0 deletions lld/Common/ErrorHandler.cpp
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/Relocations.cpp
Expand Up @@ -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() {
Expand Down
4 changes: 4 additions & 0 deletions lld/docs/error_handling_script.rst
Expand Up @@ -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
============

Expand Down
2 changes: 2 additions & 0 deletions lld/docs/ld.lld.1
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion lld/include/lld/Common/ErrorHandler.h
Expand Up @@ -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:
Expand Down
31 changes: 30 additions & 1 deletion lld/test/ELF/error-handling-script-linux.test
Expand Up @@ -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 $*"

0 comments on commit 1e70ec1

Please sign in to comment.