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)