Move __.SYMDEF handling to ar.go. One less bit of special-casing in read_symbols.go. We filter out the sysv-style symbol table, so we should filter out the macOS one too. Add tests for util/ar to cover this and the Linux case. Change-Id: Id16d8b0526c1b6e0149df1df4006848d7b3a4b2f Reviewed-on: https://boringssl-review.googlesource.com/c/33347 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com>
diff --git a/util/ar/ar.go b/util/ar/ar.go index f5dee62..ce5c65c 100644 --- a/util/ar/ar.go +++ b/util/ar/ar.go
@@ -141,6 +141,10 @@ name = name[:null] } + if name == "__.SYMDEF" || name == "__.SYMDEF SORTED" { + continue + } + ret[name] = contents }
diff --git a/util/ar/ar_test.go b/util/ar/ar_test.go new file mode 100644 index 0000000..f9e23ff --- /dev/null +++ b/util/ar/ar_test.go
@@ -0,0 +1,95 @@ +// Copyright (c) 2018, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +package ar + +import ( + "bytes" + "flag" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +var testDataDir = flag.String("testdata", "testdata", "The path to the test data directory.") + +type arTest struct { + name string + in string + out []string + // allowPadding is true if the contents may have trailing newlines at end. + // On macOS, ar calls ranlib which pads all inputs up to eight bytes with + // newlines. Unlike ar's native padding up to two bytes, this padding is + // included in the size field, so it is not removed when decoding. + allowPadding bool +} + +func (test *arTest) Path(file string) string { + return filepath.Join(*testDataDir, test.name, file) +} + +func removeTrailingNewlines(in []byte) []byte { + for len(in) > 0 && in[len(in)-1] == '\n' { + in = in[:len(in)-1] + } + return in +} + +var arTests = []arTest{ + {"linux", "libsample.a", []string{"foo.c.o", "bar.cc.o"}, false}, + {"mac", "libsample.a", []string{"foo.c.o", "bar.cc.o"}, true}, +} + +func TestAR(t *testing.T) { + for _, test := range arTests { + t.Run(test.name, func(t *testing.T) { + in, err := os.Open(test.Path(test.in)) + if err != nil { + t.Fatalf("opening input failed: %s", err) + } + defer in.Close() + + ret, err := ParseAR(in) + if err != nil { + t.Fatalf("reading input failed: %s", err) + } + + expectedFiles := make(map[string]struct{}) + for _, file := range test.out { + expectedFiles[file] = struct{}{} + expected, err := ioutil.ReadFile(test.Path(file)) + if err != nil { + t.Fatalf("error reading %s: %s", file, err) + } + got, ok := ret[file] + if test.allowPadding { + got = removeTrailingNewlines(got) + expected = removeTrailingNewlines(got) + } + if !ok { + t.Errorf("file %s missing from output", file) + } else if !bytes.Equal(got, expected) { + t.Errorf("contents for file %s did not match", file) + } + } + + for file, _ := range ret { + if _, ok := expectedFiles[file]; !ok { + t.Errorf("output contained unexpected file %q", file) + } + } + }) + } +}
diff --git a/util/ar/testdata/linux/bar.cc.o b/util/ar/testdata/linux/bar.cc.o new file mode 100644 index 0000000..92e83a9 --- /dev/null +++ b/util/ar/testdata/linux/bar.cc.o Binary files differ
diff --git a/util/ar/testdata/linux/foo.c.o b/util/ar/testdata/linux/foo.c.o new file mode 100644 index 0000000..6423c1d --- /dev/null +++ b/util/ar/testdata/linux/foo.c.o Binary files differ
diff --git a/util/ar/testdata/linux/libsample.a b/util/ar/testdata/linux/libsample.a new file mode 100644 index 0000000..cae6ae7 --- /dev/null +++ b/util/ar/testdata/linux/libsample.a Binary files differ
diff --git a/util/ar/testdata/mac/bar.cc.o b/util/ar/testdata/mac/bar.cc.o new file mode 100644 index 0000000..9c60798 --- /dev/null +++ b/util/ar/testdata/mac/bar.cc.o Binary files differ
diff --git a/util/ar/testdata/mac/foo.c.o b/util/ar/testdata/mac/foo.c.o new file mode 100644 index 0000000..0f96a0a --- /dev/null +++ b/util/ar/testdata/mac/foo.c.o Binary files differ
diff --git a/util/ar/testdata/mac/libsample.a b/util/ar/testdata/mac/libsample.a new file mode 100644 index 0000000..b7d8eb5 --- /dev/null +++ b/util/ar/testdata/mac/libsample.a Binary files differ
diff --git a/util/ar/testdata/sample/CMakeLists.txt b/util/ar/testdata/sample/CMakeLists.txt new file mode 100644 index 0000000..9ea2fe8 --- /dev/null +++ b/util/ar/testdata/sample/CMakeLists.txt
@@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) +project(Sample) +add_library(sample STATIC foo.c bar.cc)
diff --git a/util/ar/testdata/sample/bar.cc b/util/ar/testdata/sample/bar.cc new file mode 100644 index 0000000..a0ac7e1 --- /dev/null +++ b/util/ar/testdata/sample/bar.cc
@@ -0,0 +1,15 @@ +extern "C" { +void foo(); +void bar() {} +} + +namespace bar_namespace { + +void SomeExternalFunction(); + +void SomeFunction() { + foo(); + SomeExternalFunction(); +} + +} // namespace bar_namespace
diff --git a/util/ar/testdata/sample/foo.c b/util/ar/testdata/sample/foo.c new file mode 100644 index 0000000..fed596c --- /dev/null +++ b/util/ar/testdata/sample/foo.c
@@ -0,0 +1,7 @@ +extern void external_symbol(void); +extern void bar(void); + +void foo(void) { + external_symbol(); + bar(); +}
diff --git a/util/read_symbols.go b/util/read_symbols.go index 495e9e6..fc3e069 100644 --- a/util/read_symbols.go +++ b/util/read_symbols.go
@@ -93,9 +93,6 @@ } for name, contents := range objectFiles { - if !strings.HasSuffix(name, ".o") { - continue - } syms, err := listSymbols(contents) if err != nil { printAndExit("Error listing symbols from %q in %q: %s", name, archive, err)