[ELF] Add --warn-backrefs-exclude=<glob>
D77522 changed --warn-backrefs to not warn for linking sandwich
problems (-ldef1 -lref -ldef2). This removed lots of false positives.
However, glibc still has some problems. libc.a defines some symbols
which are normally in libm.a and libpthread.a, e.g. __isnanl/raise.
For a linking order `-lm -lpthread -lc`, I have seen:
```
// different resolutions: GNU ld/gold select libc.a(s_isnan.o) as the definition
backward reference detected: __isnanl in libc.a(printf_fp.o) refers to libm.a(m_isnanl.o)
// different resolutions: GNU ld/gold select libc.a(raise.o) as the definition
backward reference detected: raise in libc.a(abort.o) refers to libpthread.a(pt-raise.o)
```
To facilitate deployment of --warn-backrefs, add --warn-backrefs-exclude= so that
certain known issues (which may be impractical to fix) can be whitelisted.
Deliberate choices:
* Not a comma-separated list (`--warn-backrefs-exclude=liba.a,libb.a`).
-Wl, splits the argument at commas, so we cannot use commas.
--export-dynamic-symbol is similar.
* Not in the style of `--warn-backrefs='*' --warn-backrefs=-liba.a`.
We just need exclusion, not inclusion. For easier build system
integration, we should avoid order dependency. With the current
scheme, we enable --warn-backrefs, and indivial libraries can add
--warn-backrefs-exclude=<glob> to their LDFLAGS.
Reviewed By: psmith
Differential Revision: https://reviews.llvm.org/D77512
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index fe1c2ca..235ebe4 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -16,6 +16,7 @@
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Strings.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include <cstring>
@@ -514,6 +515,17 @@
// group assignment rule simulates the traditional linker's semantics.
bool backref = config->warnBackrefs && other.file &&
file->groupId < other.file->groupId;
+ if (backref) {
+ // Some libraries have known problems and can cause noise. Filter them out
+ // with --warn-backrefs-exclude=.
+ StringRef name =
+ !file->archiveName.empty() ? file->archiveName : file->getName();
+ for (const llvm::GlobPattern &pat : config->warnBackrefsExclude)
+ if (pat.match(name)) {
+ backref = false;
+ break;
+ }
+ }
fetch();
// We don't report backward references to weak symbols as they can be