]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/objfile: use pe.FileHeader.Machine to reliably determine GOARCH
authorAlex Brainman <alex.brainman@gmail.com>
Sun, 28 Jun 2020 06:28:52 +0000 (16:28 +1000)
committerAlex Brainman <alex.brainman@gmail.com>
Sat, 22 Aug 2020 00:56:53 +0000 (00:56 +0000)
Current peFile.goarch looks for symbols like "_rt0_386_windows" to
determine GOARCH. But "_rt0_386_windows" is not present in executables
built with cgo.

Use pe.FileHeader.Machine instead. This should work with any Windows
executable, not just with Go built executable.

Fixes #39682

Change-Id: Ie0ffce664f4b8b8fed69b2ecc482425b042a38d5
Reviewed-on: https://go-review.googlesource.com/c/go/+/240957
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
src/cmd/internal/objfile/pe.go
src/cmd/objdump/objdump_test.go
src/cmd/objdump/testdata/fmthellocgo.go [new file with mode: 0644]

index 259b59a4f4aeb2f6f66f50b8eb661ace6e5da717..b20cda9a44be994e4e225eccf2c205a65c77a187 100644 (file)
@@ -182,18 +182,16 @@ func loadPETable(f *pe.File, sname, ename string) ([]byte, error) {
 }
 
 func (f *peFile) goarch() string {
-       // Not sure how to get the info we want from PE header.
-       // Look in symbol table for telltale rt0 symbol.
-       if _, err := findPESymbol(f.pe, "_rt0_386_windows"); err == nil {
+       switch f.pe.Machine {
+       case pe.IMAGE_FILE_MACHINE_I386:
                return "386"
-       }
-       if _, err := findPESymbol(f.pe, "_rt0_amd64_windows"); err == nil {
+       case pe.IMAGE_FILE_MACHINE_AMD64:
                return "amd64"
-       }
-       if _, err := findPESymbol(f.pe, "_rt0_arm_windows"); err == nil {
+       case pe.IMAGE_FILE_MACHINE_ARMNT:
                return "arm"
+       default:
+               return ""
        }
-       return ""
 }
 
 func (f *peFile) loadAddress() (uint64, error) {
index a9dc7d1a5e26c6ef5c661105cdf840e0ef70a2f7..d9c1660ffd61d8acff1c2d85c128a67d79d5cd30 100644 (file)
@@ -117,8 +117,7 @@ var target = flag.String("target", "", "test disassembly of `goos/goarch` binary
 // binary for the current system (only) and test that objdump
 // can handle that one.
 
-func testDisasm(t *testing.T, printCode bool, printGnuAsm bool, flags ...string) {
-       t.Parallel()
+func testDisasm(t *testing.T, srcfname string, printCode bool, printGnuAsm bool, flags ...string) {
        goarch := runtime.GOARCH
        if *target != "" {
                f := strings.Split(*target, "/")
@@ -132,11 +131,11 @@ func testDisasm(t *testing.T, printCode bool, printGnuAsm bool, flags ...string)
                goarch = f[1]
        }
 
-       hash := md5.Sum([]byte(fmt.Sprintf("%v-%v-%v", flags, printCode, printGnuAsm)))
+       hash := md5.Sum([]byte(fmt.Sprintf("%v-%v-%v-%v", srcfname, flags, printCode, printGnuAsm)))
        hello := filepath.Join(tmp, fmt.Sprintf("hello-%x.exe", hash))
        args := []string{"build", "-o", hello}
        args = append(args, flags...)
-       args = append(args, "fmthello.go")
+       args = append(args, srcfname)
        cmd := exec.Command(testenv.GoToolPath(t), args...)
        // "Bad line" bug #36683 is sensitive to being run in the source directory.
        cmd.Dir = "testdata"
@@ -146,7 +145,7 @@ func testDisasm(t *testing.T, printCode bool, printGnuAsm bool, flags ...string)
        t.Logf("Running %v", cmd.Args)
        out, err := cmd.CombinedOutput()
        if err != nil {
-               t.Fatalf("go build fmthello.go: %v\n%s", err, out)
+               t.Fatalf("go build %s: %v\n%s", srcfname, err, out)
        }
        need := []string{
                "TEXT main.main(SB)",
@@ -155,7 +154,7 @@ func testDisasm(t *testing.T, printCode bool, printGnuAsm bool, flags ...string)
        if printCode {
                need = append(need, `   Println("hello, world")`)
        } else {
-               need = append(need, "fmthello.go:6")
+               need = append(need, srcfname+":6")
        }
 
        switch goarch {
@@ -199,7 +198,8 @@ func testDisasm(t *testing.T, printCode bool, printGnuAsm bool, flags ...string)
        t.Logf("Running %v", cmd.Args)
 
        if err != nil {
-               t.Fatalf("objdump fmthello.exe: %v\n%s", err, out)
+               exename := srcfname[:len(srcfname)-len(filepath.Ext(srcfname))] + ".exe"
+               t.Fatalf("objdump %q: %v\n%s", exename, err, out)
        }
 
        text := string(out)
@@ -222,6 +222,14 @@ func testDisasm(t *testing.T, printCode bool, printGnuAsm bool, flags ...string)
        }
 }
 
+func testGoAndCgoDisasm(t *testing.T, printCode bool, printGnuAsm bool) {
+       t.Parallel()
+       testDisasm(t, "fmthello.go", printCode, printGnuAsm)
+       if build.Default.CgoEnabled {
+               testDisasm(t, "fmthellocgo.go", printCode, printGnuAsm)
+       }
+}
+
 func TestDisasm(t *testing.T) {
        switch runtime.GOARCH {
        case "mips", "mipsle", "mips64", "mips64le":
@@ -231,7 +239,7 @@ func TestDisasm(t *testing.T) {
        case "s390x":
                t.Skipf("skipping on %s, issue 15255", runtime.GOARCH)
        }
-       testDisasm(t, false, false)
+       testGoAndCgoDisasm(t, false, false)
 }
 
 func TestDisasmCode(t *testing.T) {
@@ -239,7 +247,7 @@ func TestDisasmCode(t *testing.T) {
        case "mips", "mipsle", "mips64", "mips64le", "riscv64", "s390x":
                t.Skipf("skipping on %s, issue 19160", runtime.GOARCH)
        }
-       testDisasm(t, true, false)
+       testGoAndCgoDisasm(t, true, false)
 }
 
 func TestDisasmGnuAsm(t *testing.T) {
@@ -247,7 +255,7 @@ func TestDisasmGnuAsm(t *testing.T) {
        case "mips", "mipsle", "mips64", "mips64le", "riscv64", "s390x":
                t.Skipf("skipping on %s, issue 19160", runtime.GOARCH)
        }
-       testDisasm(t, false, true)
+       testGoAndCgoDisasm(t, false, true)
 }
 
 func TestDisasmExtld(t *testing.T) {
@@ -268,7 +276,8 @@ func TestDisasmExtld(t *testing.T) {
        if !build.Default.CgoEnabled {
                t.Skip("skipping because cgo is not enabled")
        }
-       testDisasm(t, false, false, "-ldflags=-linkmode=external")
+       t.Parallel()
+       testDisasm(t, "fmthello.go", false, false, "-ldflags=-linkmode=external")
 }
 
 func TestDisasmGoobj(t *testing.T) {
diff --git a/src/cmd/objdump/testdata/fmthellocgo.go b/src/cmd/objdump/testdata/fmthellocgo.go
new file mode 100644 (file)
index 0000000..6555c3b
--- /dev/null
@@ -0,0 +1,21 @@
+package main
+
+import "fmt"
+import "C"
+
+func main() {
+       Println("hello, world")
+       if flag {
+//line fmthello.go:999999
+               Println("bad line")
+               for {
+               }
+       }
+}
+
+//go:noinline
+func Println(s string) {
+       fmt.Println(s)
+}
+
+var flag bool