From 89bf297b2486adaaff04be154a066ea9f5e63994 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Thu, 29 Apr 2021 21:49:15 -0400 Subject: [PATCH] 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 Run-TryBot: Cherry Zhang TryBot-Result: Go Bot Reviewed-by: Than McIntosh --- src/cmd/internal/archive/archive.go | 11 ++++++++++- src/cmd/internal/objfile/objfile.go | 3 +++ src/cmd/objdump/objdump_test.go | 15 +++++++++++++++ src/cmd/objdump/testdata/go116.o | Bin 0 -> 478 bytes 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/cmd/objdump/testdata/go116.o 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 { diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go index ac184441ea..f231a7c6e0 100644 --- a/src/cmd/objdump/objdump_test.go +++ b/src/cmd/objdump/objdump_test.go @@ -345,3 +345,18 @@ func TestGoobjFileNumber(t *testing.T) { 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) + } +} diff --git a/src/cmd/objdump/testdata/go116.o b/src/cmd/objdump/testdata/go116.o new file mode 100644 index 0000000000000000000000000000000000000000..6434d5c8cffe54de18af70cf255f2da061e4b1cb GIT binary patch literal 478 zcmY$iNi0gvu;Yr4*9-7=cX4%7fB*w14Wb}y2x(?w0+um{D@fo<&sWG#%1TWxQAkNF zD$mSQNX$(!Gf_y-H`FsU(=%3xu*%ENOXcF?Qc-c@%4B3_U|=j@WME`qU=Td5_D9-$ z@d2O=SA2SYyk0)STDS!`Twr8w2~|vj3lzB+fX*^B%SnM*%>;DDGALdLr1zoW%RoLl zz6}(648*UI@Eaf-hST%)l1nr5((?5R5|gtN(^K;jb5r%w^V2eOQuXv~5=%?+fnupe zi6yBib}(W6lH3CQ)ZBuSN}x)hVGJoiEDpp~Kr9Nx6M={F!wo>P1q=YK CtYzK+ literal 0 HcmV?d00001