From c2bfe0abb1e8b37ffbc47b2871350c7048334d7b Mon Sep 17 00:00:00 2001 From: Danek Duvall Date: Tue, 14 Mar 2017 13:52:36 -0700 Subject: [PATCH] Archives require a symbol table on Solaris, even if empty. On Solaris ld (and some other tools that use the underlying utility libraries, such as elfdump) chokes on an archive library that has no symbol table. The Solaris tools always create one, even if it's empty. That bug has been fixed in the latest development line, and can probably be backported to a supported release, but it would be nice if LLVM's archiver could emit the empty symbol table, too. Fixed in upstream LLVM in revision 297773. --- lib/Object/ArchiveWriter.cpp | 5 +++++ test/Object/Inputs/solaris-nosymbols.yaml | 7 +++++++ test/Object/archive-format.test | 12 ++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 test/Object/Inputs/solaris-nosymbols.yaml diff --git a/lib/Object/ArchiveWriter.cpp b/lib/Object/ArchiveWriter.cpp index f8e3c5a0a03f..b02b5945adfc 100644 --- a/lib/Object/ArchiveWriter.cpp +++ b/lib/Object/ArchiveWriter.cpp @@ -320,6 +320,11 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind, if (Kind == object::Archive::K_BSD) print32(Out, Kind, StringTable.size()); // byte count of the string table Out << StringTable; + // If there are no symbols, emit an empty symbol table, to satisfy Solaris + // tools, older versions of which expect a symbol table in a non-empty + // archive, regardless of whether there are any symbols in it. + if (StringTable.size() == 0) + print32(Out, Kind, 0); // ld64 requires the next member header to start at an offset that is // 4 bytes aligned. diff --git a/test/Object/Inputs/solaris-nosymbols.yaml b/test/Object/Inputs/solaris-nosymbols.yaml new file mode 100644 index 000000000000..85dabedcf9a5 --- /dev/null +++ b/test/Object/Inputs/solaris-nosymbols.yaml @@ -0,0 +1,7 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +... diff --git a/test/Object/archive-format.test b/test/Object/archive-format.test index b9562a36d67b..174f9b9bc573 100644 --- a/test/Object/archive-format.test +++ b/test/Object/archive-format.test @@ -65,3 +65,15 @@ THIN-PATH-NEXT: /65 0 0 0 644 4 ` RUN: not llvm-ar --format=bsd rcT bad.a 0123456789abcde 0123456789abcdef 2>&1 | FileCheck --check-prefix=BSD-THIN %s BSD-THIN: Only the gnu format has a thin mode. + +If an archive has an object with no symbols, the linker and some other +tools on some versions of Solaris will abort operations if there is no +symbol table. Create such an object, put it into an archive, and check to +see that there is an empty symbol table. +RUN: mkdir -p %t +RUN: yaml2obj %S/Inputs/solaris-nosymbols.yaml > %t/foo.o +RUN: llvm-ar rs %t/foo.a %t/foo.o +RUN: cat -v %t/foo.a | FileCheck -strict-whitespace --check-prefix=SOLARIS %s +SOLARIS: ! +SOLARIS-NEXT: / 0 0 0 0 8 ` +SOLARIS-NEXT: ^@^@^@^@^@^@^@^@foo.o/