[PATCH] archives require a symbol table on Solaris, even if empty

Danek Duvall via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 9 11:29:53 PST 2017


Rafael Avila de Espindola wrote:

> Danek Duvall <danek.duvall at oracle.com> writes:
> > I've attached a new patch with an updated comment, a testcase, and an
> > archive, with a git-style patch.  Let me know if there's a better way to do
> > this.
> 
> Since the archive format is basically text, I think you can just use
> FileCheck to test that we create a symbol table on an empty file. Take a
> look at llvm/test/Object/archive-format.test. In fact, don't you have to
> update that test with your patch?

I don't -- the problem only appears when there's an actual object file in
the archive, not when the archive is empty or contains only text files.

So I figured out how to use yaml2obj to create a minimal object file.  I
couldn't figure out how to get FileCheck to deal with null characters, so I
used cat -v instead of cat.  Perhaps that last check line isn't strictly
necessary, since the previous line had a 4 in place of the 8 that should be
there, but it's a bit more clear what's going on this way.  I'm happy to
change it, if you don't feel it's necessary or cat -v isn't portable enough.

I also moved the test into archive-format.test, since it seemed like a
reasonable place for it.

Thanks,
Danek
-------------- next part --------------
Index: lib/Object/ArchiveWriter.cpp
===================================================================
--- lib/Object/ArchiveWriter.cpp	(revision 297234)
+++ lib/Object/ArchiveWriter.cpp	(working copy)
@@ -341,6 +341,11 @@
   if (isBSDLike(Kind))
     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.
Index: test/Object/Inputs/solaris-nosymbols.yaml
===================================================================
--- test/Object/Inputs/solaris-nosymbols.yaml	(nonexistent)
+++ test/Object/Inputs/solaris-nosymbols.yaml	(working copy)
@@ -0,0 +1,7 @@
+--- !ELF
+FileHeader:      
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+...
Index: test/Object/archive-format.test
===================================================================
--- test/Object/archive-format.test	(revision 297234)
+++ test/Object/archive-format.test	(working copy)
@@ -78,3 +78,15 @@
 
 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:      !<arch>
+SOLARIS-NEXT: /               0           0     0     0       8         `
+SOLARIS-NEXT: ^@^@^@^@^@^@^@^@foo.o/


More information about the llvm-commits mailing list