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/