]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/objfile: emit better error for Go object of a different version
authorCherry Zhang <cherryyz@google.com>
Fri, 30 Apr 2021 01:49:15 +0000 (21:49 -0400)
committerCherry Zhang <cherryyz@google.com>
Fri, 30 Apr 2021 16:53:35 +0000 (16:53 +0000)
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>
src/cmd/internal/archive/archive.go
src/cmd/internal/objfile/objfile.go
src/cmd/objdump/objdump_test.go
src/cmd/objdump/testdata/go116.o [new file with mode: 0644]

index e9b25fe240a34941a0935464dcb0795d7cba37ff..d1d51b285554743a20f687d7bea53b9981a326ed 100644 (file)
@@ -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)
index a58e0e159c8a5b98d0500b75aed04d3b350579c2..dcfd158ec209274891640b0cd74fc35611fb0026 100644 (file)
@@ -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 {
index ac184441eaca429c18d434a8f0fd1e77ad0a21bb..f231a7c6e0e2e5c084cb162c1b6c3540d4677b85 100644 (file)
@@ -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 (file)
index 0000000..6434d5c
Binary files /dev/null and b/src/cmd/objdump/testdata/go116.o differ