[lld] r366836 - ld.lld: Demangle symbols from archives in diagnostics

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 26 01:34:03 PDT 2019


Merged to release_90 in r369882

On Tue, Jul 23, 2019 at 8:59 PM Nico Weber via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Author: nico
> Date: Tue Jul 23 12:00:01 2019
> New Revision: 366836
>
> URL: http://llvm.org/viewvc/llvm-project?rev=366836&view=rev
> Log:
> ld.lld: Demangle symbols from archives in diagnostics
>
> This ports r366573 from COFF to ELF.
>
> There are now to toString(Archive::Symbol), one doing MSVC demangling
> in COFF and one doing Itanium demangling in ELF, so rename these two
> to toCOFFString() and to toELFString() to not get a duplicate symbol.
>
> Nothing ever passes a raw Archive::Symbol to CHECK(), so these not
> being part of the normal toString() machinery seems ok.
>
> There are two code paths in the ELF linker that emits this type of
> diagnostic:
>
> 1. The "normal" one in InputFiles.cpp. This is covered by the tweaked test.
>
> 2. An additional one that's only used for libcalls if there's at least
>    one bitcode in the link, and if the libcall symbol is lazy, and
>    lazily loaded from an archive (i.e. not from a lazy .o file).
>    (This code path was added in r339301.) Since all libcall names so far
>    are C symbols and never mangled, the change there is not observable
>    and hence not covered by tests.
>
> Differential Revision: https://reviews.llvm.org/D65095
>
> Modified:
>     lld/trunk/COFF/Driver.cpp
>     lld/trunk/COFF/InputFiles.cpp
>     lld/trunk/COFF/Symbols.cpp
>     lld/trunk/COFF/Symbols.h
>     lld/trunk/ELF/InputFiles.cpp
>     lld/trunk/ELF/Symbols.cpp
>     lld/trunk/ELF/Symbols.h
>     lld/trunk/test/ELF/archive-thin-missing-member.s
>
> Modified: lld/trunk/COFF/Driver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=366836&r1=366835&r2=366836&view=diff
> ==============================================================================
> --- lld/trunk/COFF/Driver.cpp (original)
> +++ lld/trunk/COFF/Driver.cpp Tue Jul 23 12:00:01 2019
> @@ -273,7 +273,7 @@ void LinkerDriver::enqueueArchiveMember(
>
>    auto reportBufferError = [=](Error &&e, StringRef childName) {
>      fatal("could not get the buffer for the member defining symbol " +
> -          toString(sym) + ": " + parentName + "(" + childName + "): " +
> +          toCOFFString(sym) + ": " + parentName + "(" + childName + "): " +
>            toString(std::move(e)));
>    };
>
> @@ -284,7 +284,8 @@ void LinkerDriver::enqueueArchiveMember(
>        reportBufferError(mbOrErr.takeError(), check(c.getFullName()));
>      MemoryBufferRef mb = mbOrErr.get();
>      enqueueTask([=]() {
> -      driver->addArchiveBuffer(mb, toString(sym), parentName, offsetInArchive);
> +      driver->addArchiveBuffer(mb, toCOFFString(sym), parentName,
> +                               offsetInArchive);
>      });
>      return;
>    }
> @@ -292,7 +293,7 @@ void LinkerDriver::enqueueArchiveMember(
>    std::string childName = CHECK(
>        c.getFullName(),
>        "could not get the filename for the member defining symbol " +
> -      toString(sym));
> +      toCOFFString(sym));
>    auto future = std::make_shared<std::future<MBErrPair>>(
>        createFutureForFile(childName));
>    enqueueTask([=]() {
> @@ -300,7 +301,8 @@ void LinkerDriver::enqueueArchiveMember(
>      if (mbOrErr.second)
>        reportBufferError(errorCodeToError(mbOrErr.second), childName);
>      driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)),
> -                             toString(sym), parentName, /*OffsetInArchive=*/0);
> +                             toCOFFString(sym), parentName,
> +                             /*OffsetInArchive=*/0);
>    });
>  }
>
>
> Modified: lld/trunk/COFF/InputFiles.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=366836&r1=366835&r2=366836&view=diff
> ==============================================================================
> --- lld/trunk/COFF/InputFiles.cpp (original)
> +++ lld/trunk/COFF/InputFiles.cpp Tue Jul 23 12:00:01 2019
> @@ -86,8 +86,9 @@ void ArchiveFile::parse() {
>
>  // Returns a buffer pointing to a member file containing a given symbol.
>  void ArchiveFile::addMember(const Archive::Symbol &sym) {
> -  const Archive::Child &c = CHECK(
> -      sym.getMember(), "could not get the member for symbol " + toString(sym));
> +  const Archive::Child &c =
> +      CHECK(sym.getMember(),
> +            "could not get the member for symbol " + toCOFFString(sym));
>
>    // Return an empty buffer if we have already returned the same buffer.
>    if (!seen.insert(c.getChildOffset()).second)
>
> Modified: lld/trunk/COFF/Symbols.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.cpp?rev=366836&r1=366835&r2=366836&view=diff
> ==============================================================================
> --- lld/trunk/COFF/Symbols.cpp (original)
> +++ lld/trunk/COFF/Symbols.cpp Tue Jul 23 12:00:01 2019
> @@ -33,7 +33,9 @@ static std::string demangle(StringRef sy
>    return symName;
>  }
>  std::string toString(coff::Symbol &b) { return demangle(b.getName()); }
> -std::string toString(const Archive::Symbol &b) { return demangle(b.getName()); }
> +std::string toCOFFString(const Archive::Symbol &b) {
> +  return demangle(b.getName());
> +}
>
>  namespace coff {
>
>
> Modified: lld/trunk/COFF/Symbols.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=366836&r1=366835&r2=366836&view=diff
> ==============================================================================
> --- lld/trunk/COFF/Symbols.h (original)
> +++ lld/trunk/COFF/Symbols.h Tue Jul 23 12:00:01 2019
> @@ -21,6 +21,14 @@
>  #include <vector>
>
>  namespace lld {
> +
> +std::string toString(coff::Symbol &b);
> +
> +// There are two different ways to convert an Archive::Symbol to a string:
> +// One for Microsoft name mangling and one for Itanium name mangling.
> +// Call the functions toCOFFString and toELFString, not just toString.
> +std::string toCOFFString(const coff::Archive::Symbol &b);
> +
>  namespace coff {
>
>  using llvm::object::Archive;
> @@ -429,8 +437,6 @@ void replaceSymbol(Symbol *s, ArgT &&...
>  }
>  } // namespace coff
>
> -std::string toString(coff::Symbol &b);
> -std::string toString(const coff::Archive::Symbol &b);
>  } // namespace lld
>
>  #endif
>
> Modified: lld/trunk/ELF/InputFiles.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=366836&r1=366835&r2=366836&view=diff
> ==============================================================================
> --- lld/trunk/ELF/InputFiles.cpp (original)
> +++ lld/trunk/ELF/InputFiles.cpp Tue Jul 23 12:00:01 2019
> @@ -1148,7 +1148,7 @@ void ArchiveFile::fetch(const Archive::S
>    Archive::Child c =
>        CHECK(sym.getMember(), toString(this) +
>                                   ": could not get the member for symbol " +
> -                                 sym.getName());
> +                                 toELFString(sym));
>
>    if (!seen.insert(c.getChildOffset()).second)
>      return;
> @@ -1157,7 +1157,7 @@ void ArchiveFile::fetch(const Archive::S
>        CHECK(c.getMemoryBufferRef(),
>              toString(this) +
>                  ": could not get the buffer for the member defining symbol " +
> -                sym.getName());
> +                toELFString(sym));
>
>    if (tar && c.getParent()->isThin())
>      tar->append(relativeToRoot(CHECK(c.getFullName(), this)), mb.getBuffer());
>
> Modified: lld/trunk/ELF/Symbols.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=366836&r1=366835&r2=366836&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Symbols.cpp (original)
> +++ lld/trunk/ELF/Symbols.cpp Tue Jul 23 12:00:01 2019
> @@ -42,6 +42,20 @@ Defined *ElfSym::relaIpltEnd;
>  Defined *ElfSym::riscvGlobalPointer;
>  Defined *ElfSym::tlsModuleBase;
>
> +// Returns a symbol for an error message.
> +static std::string demangle(StringRef symName) {
> +  if (config->demangle)
> +    if (Optional<std::string> s = demangleItanium(symName))
> +      return *s;
> +  return symName;
> +}
> +namespace lld {
> +std::string toString(const Symbol &b) { return demangle(b.getName()); }
> +std::string toELFString(const Archive::Symbol &b) {
> +  return demangle(b.getName());
> +}
> +} // namespace lld
> +
>  static uint64_t getSymVA(const Symbol &sym, int64_t &addend) {
>    switch (sym.kind()) {
>    case Symbol::DefinedKind: {
> @@ -250,12 +264,13 @@ void Symbol::fetch() const {
>  }
>
>  MemoryBufferRef LazyArchive::getMemberBuffer() {
> -  Archive::Child c = CHECK(
> -      sym.getMember(), "could not get the member for symbol " + sym.getName());
> +  Archive::Child c =
> +      CHECK(sym.getMember(),
> +            "could not get the member for symbol " + toELFString(sym));
>
>    return CHECK(c.getMemoryBufferRef(),
>                 "could not get the buffer for the member defining symbol " +
> -                   sym.getName());
> +                   toELFString(sym));
>  }
>
>  uint8_t Symbol::computeBinding() const {
> @@ -331,14 +346,6 @@ void elf::maybeWarnUnorderableSymbol(con
>      report(": unable to order discarded symbol: ");
>  }
>
> -// Returns a symbol for an error message.
> -std::string lld::toString(const Symbol &b) {
> -  if (config->demangle)
> -    if (Optional<std::string> s = demangleItanium(b.getName()))
> -      return *s;
> -  return b.getName();
> -}
> -
>  static uint8_t getMinVisibility(uint8_t va, uint8_t vb) {
>    if (va == STV_DEFAULT)
>      return vb;
>
> Modified: lld/trunk/ELF/Symbols.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=366836&r1=366835&r2=366836&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Symbols.h (original)
> +++ lld/trunk/ELF/Symbols.h Tue Jul 23 12:00:01 2019
> @@ -33,7 +33,11 @@ class Undefined;
>  } // namespace elf
>
>  std::string toString(const elf::Symbol &);
> -std::string toString(const elf::InputFile *);
> +
> +// There are two different ways to convert an Archive::Symbol to a string:
> +// One for Microsoft name mangling and one for Itanium name mangling.
> +// Call the functions toCOFFString and toELFString, not just toString.
> +std::string toELFString(const elf::Archive::Symbol &);
>
>  namespace elf {
>
>
> Modified: lld/trunk/test/ELF/archive-thin-missing-member.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/archive-thin-missing-member.s?rev=366836&r1=366835&r2=366836&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/archive-thin-missing-member.s (original)
> +++ lld/trunk/test/ELF/archive-thin-missing-member.s Tue Jul 23 12:00:01 2019
> @@ -8,17 +8,19 @@
>  # RUN: rm %t.o
>
>  # Test error when loading symbols from missing thin archive member.
> -# RUN: not ld.lld %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
> +# RUN: not ld.lld --entry=_Z1fi %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
>  # ERR1: {{.*}}-no-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
>
>  # Test error when thin archive has symbol table but member is missing.
> -# RUN: not ld.lld -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
> -# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol _start: '{{.*}}.o': {{[Nn]}}o such file or directory
> +# RUN: not ld.lld --entry=_Z1fi -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
> +# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol f(int): '{{.*}}.o': {{[Nn]}}o such file or directory
> +# RUN: not ld.lld --entry=_Z1fi --no-demangle -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2MANGLE
> +# ERR2MANGLE: {{.*}}-syms.a: could not get the buffer for the member defining symbol _Z1fi: '{{.*}}.o': {{[Nn]}}o such file or directory
>
>  # Test error when thin archive is linked using --whole-archive but member is missing.
> -# RUN: not ld.lld --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3
> +# RUN: not ld.lld --entry=_Z1fi --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3
>  # ERR3: {{.*}}-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
>
> -.global _start
> -_start:
> +.global _Z1fi
> +_Z1fi:
>      nop
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list