diff options
| author | Cherry Zhang <cherryyz@google.com> | 2021-04-29 21:49:15 -0400 |
|---|---|---|
| committer | Cherry Zhang <cherryyz@google.com> | 2021-04-30 16:53:35 +0000 |
| commit | 89bf297b2486adaaff04be154a066ea9f5e63994 (patch) | |
| tree | 963fcadec69c72502ec012864304b7e78eb530d5 /src/cmd/internal | |
| parent | a893682d83760a9f9bb6f5d543b907ee6467cc6e (diff) | |
| download | go-89bf297b2486adaaff04be154a066ea9f5e63994.tar.xz | |
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>
Diffstat (limited to 'src/cmd/internal')
| -rw-r--r-- | src/cmd/internal/archive/archive.go | 11 | ||||
| -rw-r--r-- | src/cmd/internal/objfile/objfile.go | 3 |
2 files changed, 13 insertions, 1 deletions
diff --git a/src/cmd/internal/archive/archive.go b/src/cmd/internal/archive/archive.go index e9b25fe240..d1d51b2855 100644 --- a/src/cmd/internal/archive/archive.go +++ b/src/cmd/internal/archive/archive.go @@ -106,6 +106,12 @@ var ( 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. type objReader struct { 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" // and then the part we want to parse begins. // 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 { h := make([]byte, 0, 256) var c1, c2, c3 byte @@ -418,6 +424,9 @@ func (r *objReader) parseObject(o *GoObj, size int64) error { return err } 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) } r.skip(o.Size) diff --git a/src/cmd/internal/objfile/objfile.go b/src/cmd/internal/objfile/objfile.go index a58e0e159c..dcfd158ec2 100644 --- a/src/cmd/internal/objfile/objfile.go +++ b/src/cmd/internal/objfile/objfile.go @@ -6,6 +6,7 @@ package objfile import ( + "cmd/internal/archive" "debug/dwarf" "debug/gosym" "fmt" @@ -73,6 +74,8 @@ func Open(name string) (*File, error) { } if f, err := openGoFile(r); err == nil { return f, nil + } else if _, ok := err.(archive.ErrGoObjOtherVersion); ok { + return nil, fmt.Errorf("open %s: %v", name, err) } for _, try := range openers { if raw, err := try(r); err == nil { |
