mirror of
https://github.com/golang/go
synced 2024-11-23 00:20:12 -07:00
cmd/internal/objfile: emit better error for Go object of a different version
The Go object file format can change from version to version. Tools like cmd/objdump and cmd/nm only onderstand the current version of the object file. Currently, when it encounters an object built with a different version of the toolchain, it emits a generic error "unrecognized object file", which is not very helpful for users. This CL makes it emit a clearer error. Now it emits objdump: open go116.o: go object of a different version: go116ld Change-Id: I063c6078ed1da78f97cea65796779ae093a1a8cb Reviewed-on: https://go-review.googlesource.com/c/go/+/315609 Trust: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
a893682d83
commit
89bf297b24
@ -106,6 +106,12 @@ var (
|
|||||||
errNotObject = errors.New("unrecognized object file format")
|
errNotObject = errors.New("unrecognized object file format")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ErrGoObjOtherVersion struct{ magic []byte }
|
||||||
|
|
||||||
|
func (e ErrGoObjOtherVersion) Error() string {
|
||||||
|
return fmt.Sprintf("go object of a different version: %s", e.magic)
|
||||||
|
}
|
||||||
|
|
||||||
// An objReader is an object file reader.
|
// An objReader is an object file reader.
|
||||||
type objReader struct {
|
type objReader struct {
|
||||||
a *Archive
|
a *Archive
|
||||||
@ -389,7 +395,7 @@ func (r *objReader) parseArchive(verbose bool) error {
|
|||||||
// The object file consists of a textual header ending in "\n!\n"
|
// The object file consists of a textual header ending in "\n!\n"
|
||||||
// and then the part we want to parse begins.
|
// and then the part we want to parse begins.
|
||||||
// The format of that part is defined in a comment at the top
|
// The format of that part is defined in a comment at the top
|
||||||
// of src/liblink/objfile.c.
|
// of cmd/internal/goobj/objfile.go.
|
||||||
func (r *objReader) parseObject(o *GoObj, size int64) error {
|
func (r *objReader) parseObject(o *GoObj, size int64) error {
|
||||||
h := make([]byte, 0, 256)
|
h := make([]byte, 0, 256)
|
||||||
var c1, c2, c3 byte
|
var c1, c2, c3 byte
|
||||||
@ -418,6 +424,9 @@ func (r *objReader) parseObject(o *GoObj, size int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !bytes.Equal(p, []byte(goobj.Magic)) {
|
if !bytes.Equal(p, []byte(goobj.Magic)) {
|
||||||
|
if bytes.HasPrefix(p, []byte("\x00go1")) && bytes.HasSuffix(p, []byte("ld")) {
|
||||||
|
return r.error(ErrGoObjOtherVersion{p})
|
||||||
|
}
|
||||||
return r.error(errCorruptObject)
|
return r.error(errCorruptObject)
|
||||||
}
|
}
|
||||||
r.skip(o.Size)
|
r.skip(o.Size)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package objfile
|
package objfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/internal/archive"
|
||||||
"debug/dwarf"
|
"debug/dwarf"
|
||||||
"debug/gosym"
|
"debug/gosym"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -73,6 +74,8 @@ func Open(name string) (*File, error) {
|
|||||||
}
|
}
|
||||||
if f, err := openGoFile(r); err == nil {
|
if f, err := openGoFile(r); err == nil {
|
||||||
return f, nil
|
return f, nil
|
||||||
|
} else if _, ok := err.(archive.ErrGoObjOtherVersion); ok {
|
||||||
|
return nil, fmt.Errorf("open %s: %v", name, err)
|
||||||
}
|
}
|
||||||
for _, try := range openers {
|
for _, try := range openers {
|
||||||
if raw, err := try(r); err == nil {
|
if raw, err := try(r); err == nil {
|
||||||
|
@ -345,3 +345,18 @@ func TestGoobjFileNumber(t *testing.T) {
|
|||||||
t.Logf("output:\n%s", text)
|
t.Logf("output:\n%s", text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGoObjOtherVersion(t *testing.T) {
|
||||||
|
testenv.MustHaveExec(t)
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
obj := filepath.Join("testdata", "go116.o")
|
||||||
|
cmd := exec.Command(exe, obj)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("objdump go116.o succeeded unexpectly")
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(out), "go object of a different version") {
|
||||||
|
t.Errorf("unexpected error message:\n%s", out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BIN
src/cmd/objdump/testdata/go116.o
vendored
Normal file
BIN
src/cmd/objdump/testdata/go116.o
vendored
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user