From ce3c5dae06566eb3ae31e44a459cc8c9cb9e060d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 22 Oct 2020 15:26:52 -0700 Subject: [PATCH] [ELF] --warn-backrefs: save the referenced InputFile * For a diagnostic `A refers to B` where B refers to a bitcode file, if the symbol gets optimized out, the user may see `A refers to `; if the symbol is retained, the user may see `A refers to lto.tmp`. Save the reference InputFile * in the DenseMap so that the original filename is available in reportBackrefs(). --- lld/ELF/Symbols.cpp | 11 +++++++---- lld/ELF/Symbols.h | 4 +++- lld/test/ELF/lto/warn-backrefs.ll | 30 ++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 lld/test/ELF/lto/warn-backrefs.ll diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 8f2f55418df5..eed0251c82e3 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -64,7 +64,8 @@ Defined *ElfSym::relaIpltStart; Defined *ElfSym::relaIpltEnd; Defined *ElfSym::riscvGlobalPointer; Defined *ElfSym::tlsModuleBase; -DenseMap elf::backwardReferences; +DenseMap> + elf::backwardReferences; static uint64_t getSymVA(const Symbol &sym, int64_t &addend) { switch (sym.kind()) { @@ -377,7 +378,8 @@ void elf::reportBackrefs() { for (auto &it : backwardReferences) { const Symbol &sym = *it.first; warn("backward reference detected: " + sym.getName() + " in " + - toString(it.second) + " refers to " + toString(sym.file)); + toString(it.second.first) + " refers to " + + toString(it.second.second)); } } @@ -532,9 +534,10 @@ void Symbol::resolveUndefined(const Undefined &other) { // A traditional linker does not error for -ldef1 -lref -ldef2 (linking // sandwich), where def2 may or may not be the same as def1. We don't want // to warn for this case, so dismiss the warning if we see a subsequent lazy - // definition. + // definition. this->file needs to be saved because in the case of LTO it + // may be reset to nullptr or be replaced with a file named lto.tmp. if (backref && !isWeak()) - backwardReferences.try_emplace(this, other.file); + backwardReferences.try_emplace(this, std::make_pair(other.file, file)); return; } diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index b69d263153d2..a8d056a32f98 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -567,7 +567,9 @@ void reportBackrefs(); // A mapping from a symbol to an InputFile referencing it backward. Used by // --warn-backrefs. -extern llvm::DenseMap backwardReferences; +extern llvm::DenseMap> + backwardReferences; } // namespace elf } // namespace lld diff --git a/lld/test/ELF/lto/warn-backrefs.ll b/lld/test/ELF/lto/warn-backrefs.ll new file mode 100644 index 000000000000..0de73673c0e5 --- /dev/null +++ b/lld/test/ELF/lto/warn-backrefs.ll @@ -0,0 +1,30 @@ +; REQUIRES: x86 +;; Test that the referenced filename is correct (not or lto.tmp). + +; RUN: split-file %s %t +; RUN: llvm-as %t/a.ll -o %ta.o +; RUN: llvm-as %t/b.ll -o %tb.o +; RUN: ld.lld --warn-backrefs --start-lib %tb.o --end-lib %ta.o 2>&1 | FileCheck %s + +; CHECK: warning: backward reference detected: f in {{.*}}a.o refers to {{.*}}b.o + +;--- a.ll +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @f() + +define void @_start() { +entry: + call void () @f() + ret void +} + +;--- b.ll +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @f() { +entry: + ret void +}