]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/asm: fix assembling return jump
authorCherry Zhang <cherryyz@google.com>
Thu, 15 Feb 2018 00:35:03 +0000 (19:35 -0500)
committerCherry Zhang <cherryyz@google.com>
Thu, 1 Mar 2018 21:11:16 +0000 (21:11 +0000)
In RET instruction, the operand is the return jump's target,
which should be put in Prog.To.

Add an action "buildrundir" to the test driver, which builds
(compile+assemble+link) the code in a directory and runs the
resulting binary.

Fixes #23838.

Change-Id: I7ebe7eda49024b40a69a24857322c5ca9c67babb
Reviewed-on: https://go-review.googlesource.com/94175
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
13 files changed:
src/cmd/asm/internal/asm/asm.go
src/cmd/asm/internal/asm/testdata/386.s
src/cmd/asm/internal/asm/testdata/amd64.s
src/cmd/asm/internal/asm/testdata/arm.s
src/cmd/asm/internal/asm/testdata/arm64.s
src/cmd/asm/internal/asm/testdata/mips.s
src/cmd/asm/internal/asm/testdata/mips64.s
src/cmd/asm/internal/asm/testdata/ppc64.s
src/cmd/asm/internal/asm/testdata/s390x.s
test/retjmp.dir/a.s [new file with mode: 0644]
test/retjmp.dir/main.go [new file with mode: 0644]
test/retjmp.go [new file with mode: 0644]
test/run.go

index 19f930d802ea6c8440f2ede5a4107ab54a695905..8f24895b05d77dafe751048f35f976e37038a93d 100644 (file)
@@ -486,7 +486,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
        case 0:
                // Nothing to do.
        case 1:
-               if p.arch.UnaryDst[op] {
+               if p.arch.UnaryDst[op] || op == obj.ARET {
                        // prog.From is no address.
                        prog.To = a[0]
                } else {
index ad8affd854b532dcb0d66f1717eb13e9e69e49ad..90a66167a1f56483028786c9cb36665c47f402bc 100644 (file)
@@ -91,3 +91,4 @@ loop:
 
 // LTYPE0 nonnon       { outcode(int($1), &$2); }
        RET
+       RET     foo(SB)
index d07cf0d21371894cf4dc58968875790949f8a5d2..680d8eff388a509b28b566d3a657c17d4635be91 100644 (file)
@@ -145,3 +145,4 @@ loop:
 
 // LTYPE0 nonnon       { outcode($1, &$2); }
        RET // c3
+       RET     foo(SB)
index bc6cf07e83a5a2d11c01e70e4d9cb3f772460168..0b3363e17e46359d8600b0052de14c4d852d4e5f 100644 (file)
@@ -1579,6 +1579,8 @@ jmp_label_3:
        MOVHU   R5@>16, R1                                        // 7518ffe6
        MOVHU   R5@>24, R1                                        // 751cffe6
 
+       RET     foo(SB)
+
 //
 // END
 //
index 456e46158d6740707b1627a8e88264a5f9e21ac5..06435b4582f34bcad335f041094a47e16f9f00bd 100644 (file)
@@ -426,6 +426,7 @@ again:
 //     }
        BEQ     2(PC)
        RET
+       RET     foo(SB)
 
 // More B/BL cases, and canonical names JMP, CALL.
 
index 6d62c4324251d49582251377ed9448b9e579c13e..0c6f7fd5526d731837169018b775ab595d463234 100644 (file)
@@ -422,6 +422,7 @@ label4:
        BEQ     R1, 2(PC)
        JMP     foo(SB)
        CALL    foo(SB)
+       RET     foo(SB)
 
        NEGW    R1, R2 // 00011023
 
index a945e590ab7656ea1125656de18b4812e77e3a4c..2d1bc18cec9d3d8ea0d05d813438f5fed9008540 100644 (file)
@@ -402,6 +402,7 @@ label4:
        BEQ     R1, 2(PC)
        JMP     foo(SB)
        CALL    foo(SB)
+       RET     foo(SB)
 
        NEGW    R1, R2 // 00011023
        NEGV    R1, R2 // 0001102f
index dca574f90b540f8f1dd7fa056e33f6f22097f043..e34671231fcb2e6a2fab85788157a03237087d34 100644 (file)
@@ -1197,6 +1197,7 @@ label1:
        BEQ     2(PC)
        JMP     foo(SB)
        CALL    foo(SB)
+       RET     foo(SB)
 
 // END
 //
index 884f6b23cf86adea9d4998a67d316befe4931d0d..867fe40a725d24633152f6fcf93aab6bfc936718 100644 (file)
@@ -365,6 +365,7 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
        VSTEB   $15, V29, 4094(R12)     // e7d0cffef808
 
        RET
+       RET     foo(SB)
 
 TEXT main·init(SB),DUPOK|NOSPLIT,$0 // TEXT main.init(SB), DUPOK|NOSPLIT, $0
        RET
diff --git a/test/retjmp.dir/a.s b/test/retjmp.dir/a.s
new file mode 100644 (file)
index 0000000..c67a066
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+TEXT   ·f(SB), 4, $8-0
+       CALL    ·f1(SB)
+       RET     ·f2(SB)
+       CALL    ·unreachable(SB)
+
+TEXT   ·leaf(SB), 4, $0-0
+       RET     ·f3(SB)
+       JMP     ·unreachable(SB)
diff --git a/test/retjmp.dir/main.go b/test/retjmp.dir/main.go
new file mode 100644 (file)
index 0000000..cb4bd01
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func f()
+func leaf()
+
+var f1called, f2called, f3called bool
+
+func main() {
+       f()
+       if !f1called {
+               panic("f1 not called")
+       }
+       if !f2called {
+               panic("f2 not called")
+       }
+       leaf()
+       if !f3called {
+               panic("f3 not called")
+       }
+}
+
+func f1() { f1called = true }
+func f2() { f2called = true }
+func f3() { f3called = true }
+
+func unreachable() {
+       panic("unreachable function called")
+}
diff --git a/test/retjmp.go b/test/retjmp.go
new file mode 100644 (file)
index 0000000..778d903
--- /dev/null
@@ -0,0 +1,9 @@
+// buildrundir
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that return jump works correctly in assembly code.
+
+package ignored
index fd53095ab4bcb38c3e18795f917c6b43941a89e8..a991c92462dcf4de586b081429a103784c4a1fa1 100644 (file)
@@ -488,7 +488,7 @@ func (t *test) run() {
                action = "rundir"
        case "cmpout":
                action = "run" // the run case already looks for <dir>/<test>.out files
-       case "compile", "compiledir", "build", "builddir", "run", "buildrun", "runoutput", "rundir", "asmcheck":
+       case "compile", "compiledir", "build", "builddir", "buildrundir", "run", "buildrun", "runoutput", "rundir", "asmcheck":
                // nothing to do
        case "errorcheckandrundir":
                wantError = false // should be no error if also will run
@@ -735,7 +735,7 @@ func (t *test) run() {
                        t.err = err
                }
 
-       case "builddir":
+       case "builddir", "buildrundir":
                // Build an executable from all the .go and .s files in a subdirectory.
                useTmp = true
                longdir := filepath.Join(cwd, t.goDirName())
@@ -788,12 +788,23 @@ func (t *test) run() {
                        t.err = err
                        break
                }
-               cmd = []string{"go", "tool", "link", "all.a"}
+               cmd = []string{"go", "tool", "link", "-o", "a.exe", "all.a"}
                _, err = runcmd(cmd...)
                if err != nil {
                        t.err = err
                        break
                }
+               if action == "buildrundir" {
+                       cmd = append(findExecCmd(), filepath.Join(t.tempDir, "a.exe"))
+                       out, err := runcmd(cmd...)
+                       if err != nil {
+                               t.err = err
+                               break
+                       }
+                       if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
+                               t.err = fmt.Errorf("incorrect output\n%s", out)
+                       }
+               }
 
        case "buildrun": // build binary, then run binary, instead of go run. Useful for timeout tests where failure mode is infinite loop.
                // TODO: not supported on NaCl