2017-08-30 11:14:40 +09:00
|
|
|
// Copyright 2017 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package goobj
|
|
|
|
|
|
|
|
|
|
import (
|
2017-09-10 09:45:49 +09:00
|
|
|
"debug/elf"
|
|
|
|
|
"debug/macho"
|
|
|
|
|
"debug/pe"
|
2017-08-30 11:14:40 +09:00
|
|
|
"fmt"
|
|
|
|
|
"internal/testenv"
|
2019-02-21 10:49:22 +01:00
|
|
|
"internal/xcoff"
|
2017-09-10 09:45:49 +09:00
|
|
|
"io"
|
2017-08-30 11:14:40 +09:00
|
|
|
"io/ioutil"
|
|
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"runtime"
|
[dev.link] cmd/internal/goobj: add index to symbol name for indexed symbols
With old object files, when objdump an object file which, for
example, contains a call of fmt.Fprintf, it shows a symbol
reference like
R_CALL:fmt.Fprintf
With new object files, as the symbol reference is indexed, the
reference becomes
R_CALL:fmt.#33
The object file does not contain information of what symbol #33
in the fmt package is.
To make this more useful, print the index when dumping the symbol
definitions. This way, when dumping the fmt package, e.g.
"go tool nm fmt.a", it will print
6c705 T fmt.Fprintf#33
So we can find out what symbol #33 actually is.
Change-Id: I320776597d28615ce18dd0617c352d2b8180db49
Reviewed-on: https://go-review.googlesource.com/c/go/+/229246
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-04-21 13:07:22 -04:00
|
|
|
"strings"
|
2017-08-30 11:14:40 +09:00
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
2017-09-10 09:45:49 +09:00
|
|
|
buildDir string
|
|
|
|
|
go1obj string
|
|
|
|
|
go2obj string
|
|
|
|
|
goarchive string
|
|
|
|
|
cgoarchive string
|
2017-08-30 11:14:40 +09:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
|
if !testenv.HasGoBuild() {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := buildGoobj(); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
os.RemoveAll(buildDir)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exit := m.Run()
|
|
|
|
|
|
|
|
|
|
os.RemoveAll(buildDir)
|
|
|
|
|
os.Exit(exit)
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-10 09:45:49 +09:00
|
|
|
func copyDir(dst, src string) error {
|
|
|
|
|
err := os.MkdirAll(dst, 0777)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
fis, err := ioutil.ReadDir(src)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
for _, fi := range fis {
|
|
|
|
|
err = copyFile(filepath.Join(dst, fi.Name()), filepath.Join(src, fi.Name()))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func copyFile(dst, src string) (err error) {
|
|
|
|
|
var s, d *os.File
|
|
|
|
|
s, err = os.Open(src)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer s.Close()
|
|
|
|
|
d, err = os.Create(dst)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer func() {
|
|
|
|
|
e := d.Close()
|
|
|
|
|
if err == nil {
|
|
|
|
|
err = e
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
_, err = io.Copy(d, s)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-30 11:14:40 +09:00
|
|
|
func buildGoobj() error {
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
buildDir, err = ioutil.TempDir("", "TestGoobj")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
go1obj = filepath.Join(buildDir, "go1.o")
|
|
|
|
|
go2obj = filepath.Join(buildDir, "go2.o")
|
|
|
|
|
goarchive = filepath.Join(buildDir, "go.a")
|
|
|
|
|
|
|
|
|
|
gotool, err := testenv.GoTool()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
go1src := filepath.Join("testdata", "go1.go")
|
|
|
|
|
go2src := filepath.Join("testdata", "go2.go")
|
|
|
|
|
|
|
|
|
|
out, err := exec.Command(gotool, "tool", "compile", "-o", go1obj, go1src).CombinedOutput()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go1obj, go1src, err, out)
|
|
|
|
|
}
|
|
|
|
|
out, err = exec.Command(gotool, "tool", "compile", "-o", go2obj, go2src).CombinedOutput()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go2obj, go2src, err, out)
|
|
|
|
|
}
|
|
|
|
|
out, err = exec.Command(gotool, "tool", "pack", "c", goarchive, go1obj, go2obj).CombinedOutput()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("go tool pack c %s %s %s: %v\n%s", goarchive, go1obj, go2obj, err, out)
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-10 09:45:49 +09:00
|
|
|
if testenv.HasCGO() {
|
|
|
|
|
gopath := filepath.Join(buildDir, "gopath")
|
|
|
|
|
err = copyDir(filepath.Join(gopath, "src", "mycgo"), filepath.Join("testdata", "mycgo"))
|
2019-02-15 18:04:32 -05:00
|
|
|
if err == nil {
|
|
|
|
|
err = ioutil.WriteFile(filepath.Join(gopath, "src", "mycgo", "go.mod"), []byte("module mycgo\n"), 0666)
|
|
|
|
|
}
|
2017-09-10 09:45:49 +09:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2017-11-08 10:58:58 -05:00
|
|
|
cmd := exec.Command(gotool, "install", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "mycgo")
|
2019-02-15 18:04:32 -05:00
|
|
|
cmd.Dir = filepath.Join(gopath, "src", "mycgo")
|
2017-09-10 09:45:49 +09:00
|
|
|
cmd.Env = append(os.Environ(), "GOPATH="+gopath)
|
|
|
|
|
out, err = cmd.CombinedOutput()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("go install mycgo: %v\n%s", err, out)
|
|
|
|
|
}
|
|
|
|
|
pat := filepath.Join(gopath, "pkg", "*", "mycgo.a")
|
|
|
|
|
ms, err := filepath.Glob(pat)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if len(ms) == 0 {
|
|
|
|
|
return fmt.Errorf("cannot found paths for pattern %s", pat)
|
|
|
|
|
}
|
|
|
|
|
cgoarchive = ms[0]
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-30 11:14:40 +09:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
[dev.link] cmd/internal/goobj: add index to symbol name for indexed symbols
With old object files, when objdump an object file which, for
example, contains a call of fmt.Fprintf, it shows a symbol
reference like
R_CALL:fmt.Fprintf
With new object files, as the symbol reference is indexed, the
reference becomes
R_CALL:fmt.#33
The object file does not contain information of what symbol #33
in the fmt package is.
To make this more useful, print the index when dumping the symbol
definitions. This way, when dumping the fmt package, e.g.
"go tool nm fmt.a", it will print
6c705 T fmt.Fprintf#33
So we can find out what symbol #33 actually is.
Change-Id: I320776597d28615ce18dd0617c352d2b8180db49
Reviewed-on: https://go-review.googlesource.com/c/go/+/229246
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-04-21 13:07:22 -04:00
|
|
|
// Check that a symbol has a given name, accepting both
|
|
|
|
|
// new and old objects.
|
|
|
|
|
// TODO(go115newobj): remove.
|
|
|
|
|
func matchSymName(symname, want string) bool {
|
|
|
|
|
return symname == want ||
|
|
|
|
|
strings.HasPrefix(symname, want+"#") // new style, with index
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-30 11:14:40 +09:00
|
|
|
func TestParseGoobj(t *testing.T) {
|
|
|
|
|
path := go1obj
|
|
|
|
|
|
|
|
|
|
f, err := os.Open(path)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
|
|
p, err := Parse(f, "mypkg")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if p.Arch != runtime.GOARCH {
|
|
|
|
|
t.Errorf("%s: got %v, want %v", path, p.Arch, runtime.GOARCH)
|
|
|
|
|
}
|
|
|
|
|
var found bool
|
|
|
|
|
for _, s := range p.Syms {
|
[dev.link] cmd/internal/goobj: add index to symbol name for indexed symbols
With old object files, when objdump an object file which, for
example, contains a call of fmt.Fprintf, it shows a symbol
reference like
R_CALL:fmt.Fprintf
With new object files, as the symbol reference is indexed, the
reference becomes
R_CALL:fmt.#33
The object file does not contain information of what symbol #33
in the fmt package is.
To make this more useful, print the index when dumping the symbol
definitions. This way, when dumping the fmt package, e.g.
"go tool nm fmt.a", it will print
6c705 T fmt.Fprintf#33
So we can find out what symbol #33 actually is.
Change-Id: I320776597d28615ce18dd0617c352d2b8180db49
Reviewed-on: https://go-review.googlesource.com/c/go/+/229246
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-04-21 13:07:22 -04:00
|
|
|
if matchSymName(s.Name, "mypkg.go1") {
|
2017-08-30 11:14:40 +09:00
|
|
|
found = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
t.Errorf(`%s: symbol "mypkg.go1" not found`, path)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestParseArchive(t *testing.T) {
|
|
|
|
|
path := goarchive
|
|
|
|
|
|
|
|
|
|
f, err := os.Open(path)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
|
|
p, err := Parse(f, "mypkg")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if p.Arch != runtime.GOARCH {
|
|
|
|
|
t.Errorf("%s: got %v, want %v", path, p.Arch, runtime.GOARCH)
|
|
|
|
|
}
|
|
|
|
|
var found1 bool
|
|
|
|
|
var found2 bool
|
|
|
|
|
for _, s := range p.Syms {
|
[dev.link] cmd/internal/goobj: add index to symbol name for indexed symbols
With old object files, when objdump an object file which, for
example, contains a call of fmt.Fprintf, it shows a symbol
reference like
R_CALL:fmt.Fprintf
With new object files, as the symbol reference is indexed, the
reference becomes
R_CALL:fmt.#33
The object file does not contain information of what symbol #33
in the fmt package is.
To make this more useful, print the index when dumping the symbol
definitions. This way, when dumping the fmt package, e.g.
"go tool nm fmt.a", it will print
6c705 T fmt.Fprintf#33
So we can find out what symbol #33 actually is.
Change-Id: I320776597d28615ce18dd0617c352d2b8180db49
Reviewed-on: https://go-review.googlesource.com/c/go/+/229246
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-04-21 13:07:22 -04:00
|
|
|
if matchSymName(s.Name, "mypkg.go1") {
|
2017-08-30 11:14:40 +09:00
|
|
|
found1 = true
|
|
|
|
|
}
|
[dev.link] cmd/internal/goobj: add index to symbol name for indexed symbols
With old object files, when objdump an object file which, for
example, contains a call of fmt.Fprintf, it shows a symbol
reference like
R_CALL:fmt.Fprintf
With new object files, as the symbol reference is indexed, the
reference becomes
R_CALL:fmt.#33
The object file does not contain information of what symbol #33
in the fmt package is.
To make this more useful, print the index when dumping the symbol
definitions. This way, when dumping the fmt package, e.g.
"go tool nm fmt.a", it will print
6c705 T fmt.Fprintf#33
So we can find out what symbol #33 actually is.
Change-Id: I320776597d28615ce18dd0617c352d2b8180db49
Reviewed-on: https://go-review.googlesource.com/c/go/+/229246
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-04-21 13:07:22 -04:00
|
|
|
if matchSymName(s.Name, "mypkg.go2") {
|
2017-08-30 11:14:40 +09:00
|
|
|
found2 = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found1 {
|
|
|
|
|
t.Errorf(`%s: symbol "mypkg.go1" not found`, path)
|
|
|
|
|
}
|
|
|
|
|
if !found2 {
|
|
|
|
|
t.Errorf(`%s: symbol "mypkg.go2" not found`, path)
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-09-10 09:45:49 +09:00
|
|
|
|
|
|
|
|
func TestParseCGOArchive(t *testing.T) {
|
|
|
|
|
testenv.MustHaveCGO(t)
|
|
|
|
|
|
|
|
|
|
path := cgoarchive
|
|
|
|
|
|
|
|
|
|
f, err := os.Open(path)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
|
|
p, err := Parse(f, "mycgo")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if p.Arch != runtime.GOARCH {
|
|
|
|
|
t.Errorf("%s: got %v, want %v", path, p.Arch, runtime.GOARCH)
|
|
|
|
|
}
|
|
|
|
|
var found1 bool
|
|
|
|
|
var found2 bool
|
|
|
|
|
for _, s := range p.Syms {
|
[dev.link] cmd/internal/goobj: add index to symbol name for indexed symbols
With old object files, when objdump an object file which, for
example, contains a call of fmt.Fprintf, it shows a symbol
reference like
R_CALL:fmt.Fprintf
With new object files, as the symbol reference is indexed, the
reference becomes
R_CALL:fmt.#33
The object file does not contain information of what symbol #33
in the fmt package is.
To make this more useful, print the index when dumping the symbol
definitions. This way, when dumping the fmt package, e.g.
"go tool nm fmt.a", it will print
6c705 T fmt.Fprintf#33
So we can find out what symbol #33 actually is.
Change-Id: I320776597d28615ce18dd0617c352d2b8180db49
Reviewed-on: https://go-review.googlesource.com/c/go/+/229246
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-04-21 13:07:22 -04:00
|
|
|
if matchSymName(s.Name, "mycgo.go1") {
|
2017-09-10 09:45:49 +09:00
|
|
|
found1 = true
|
|
|
|
|
}
|
[dev.link] cmd/internal/goobj: add index to symbol name for indexed symbols
With old object files, when objdump an object file which, for
example, contains a call of fmt.Fprintf, it shows a symbol
reference like
R_CALL:fmt.Fprintf
With new object files, as the symbol reference is indexed, the
reference becomes
R_CALL:fmt.#33
The object file does not contain information of what symbol #33
in the fmt package is.
To make this more useful, print the index when dumping the symbol
definitions. This way, when dumping the fmt package, e.g.
"go tool nm fmt.a", it will print
6c705 T fmt.Fprintf#33
So we can find out what symbol #33 actually is.
Change-Id: I320776597d28615ce18dd0617c352d2b8180db49
Reviewed-on: https://go-review.googlesource.com/c/go/+/229246
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-04-21 13:07:22 -04:00
|
|
|
if matchSymName(s.Name, "mycgo.go2") {
|
2017-09-10 09:45:49 +09:00
|
|
|
found2 = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found1 {
|
|
|
|
|
t.Errorf(`%s: symbol "mycgo.go1" not found`, path)
|
|
|
|
|
}
|
|
|
|
|
if !found2 {
|
|
|
|
|
t.Errorf(`%s: symbol "mycgo.go2" not found`, path)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c1 := "c1"
|
|
|
|
|
c2 := "c2"
|
|
|
|
|
|
|
|
|
|
found1 = false
|
|
|
|
|
found2 = false
|
|
|
|
|
|
|
|
|
|
switch runtime.GOOS {
|
|
|
|
|
case "darwin":
|
|
|
|
|
c1 = "_" + c1
|
|
|
|
|
c2 = "_" + c2
|
|
|
|
|
for _, obj := range p.Native {
|
|
|
|
|
mf, err := macho.NewFile(obj)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
cmd/go: stop linking cgo objects together with ld -r
https://golang.org/cl/5822049 introduced the idea of linking together
all the cgo objects with -r, while also linking against -lgcc. This
was to fix http://golang.org/issue/3261: cgo code that requires libgcc
would break when using internal linking.
This approach introduced https://golang.org/issue/9510: multiple
different cgo packages could include the same libgcc object, leading
to a multiple definition error during the final link. That problem was
fixed by https://golang.org/cl/16741, as modified by
https://golang.org/cl/16993, which did the link against libgcc only
during the final link.
After https://golang.org/cl/16741, and, on Windows, the later
https://golang.org/cl/26670, ld -r no longer does anything useful.
So, remove it.
Doing this revealed that running ld -r on Darwin simplifies some
relocs by making them specific to a symbol rather than a section.
Correct the handling of unsigned relocations in internal linking mode
by offsetting by the symbol value. This only really comes up when
using the internal linker with C code that initializes a variable to
the address of a local constant, such as a C string (as in const char
*s = "str";). This change does not affect the normal case of external
linking, where the Add field is ignored. The test case is
misc/cgo/test/issue6612.go in internal linking mode.
The cmd/internal/goobj test can now see an external object with no
symbol table; fix it to not crash in that case.
Change-Id: I15e5b7b5a8f48136bc14bf4e1c4c473d5eb58062
Reviewed-on: https://go-review.googlesource.com/64793
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-09-19 13:53:20 -07:00
|
|
|
if mf.Symtab == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2017-09-10 09:45:49 +09:00
|
|
|
for _, s := range mf.Symtab.Syms {
|
|
|
|
|
switch s.Name {
|
|
|
|
|
case c1:
|
|
|
|
|
found1 = true
|
|
|
|
|
case c2:
|
|
|
|
|
found2 = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case "windows":
|
|
|
|
|
if runtime.GOARCH == "386" {
|
|
|
|
|
c1 = "_" + c1
|
|
|
|
|
c2 = "_" + c2
|
|
|
|
|
}
|
|
|
|
|
for _, obj := range p.Native {
|
|
|
|
|
pf, err := pe.NewFile(obj)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
for _, s := range pf.Symbols {
|
|
|
|
|
switch s.Name {
|
|
|
|
|
case c1:
|
|
|
|
|
found1 = true
|
|
|
|
|
case c2:
|
|
|
|
|
found2 = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-21 10:49:22 +01:00
|
|
|
case "aix":
|
|
|
|
|
c1 = "." + c1
|
|
|
|
|
c2 = "." + c2
|
|
|
|
|
for _, obj := range p.Native {
|
|
|
|
|
xf, err := xcoff.NewFile(obj)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
for _, s := range xf.Symbols {
|
|
|
|
|
switch s.Name {
|
|
|
|
|
case c1:
|
|
|
|
|
found1 = true
|
|
|
|
|
case c2:
|
|
|
|
|
found2 = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-10 09:45:49 +09:00
|
|
|
default:
|
|
|
|
|
for _, obj := range p.Native {
|
|
|
|
|
ef, err := elf.NewFile(obj)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
syms, err := ef.Symbols()
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
for _, s := range syms {
|
|
|
|
|
switch s.Name {
|
|
|
|
|
case c1:
|
|
|
|
|
found1 = true
|
|
|
|
|
case c2:
|
|
|
|
|
found2 = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !found1 {
|
|
|
|
|
t.Errorf(`%s: symbol %q not found`, path, c1)
|
|
|
|
|
}
|
|
|
|
|
if !found2 {
|
|
|
|
|
t.Errorf(`%s: symbol %q not found`, path, c2)
|
|
|
|
|
}
|
|
|
|
|
}
|