Skip to content

Commit

Permalink
cmd/internal/obj/riscv: fix the offset of JALR transformed from JAL
Browse files Browse the repository at this point in the history
Currently, the offset of JALR is zero all the time, which is transformed
from JAL with over ±1MB offset. This causes the segment fault for the
wrong address.

Change-Id: I4dcb3eb13bd1ea71e9eb27f07c03ffec376608ab
Reviewed-on: https://go-review.googlesource.com/c/go/+/538135
Run-TryBot: M Zhuo <mzh@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: M Zhuo <mzh@golangcn.org>
Reviewed-by: Joel Sing <joel@sing.id.au>
Reviewed-by: Cherry Mui <cherryyz@google.com>
  • Loading branch information
MouseSplinter authored and mengzhuo committed Nov 7, 2023
1 parent b54cae2 commit d33548d
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
66 changes: 66 additions & 0 deletions src/cmd/internal/obj/riscv/asm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,72 @@ func genLargeCall(buf *bytes.Buffer) {
fmt.Fprintln(buf, "RET")
}

// TestLargeJump generates a large jump (>1MB of text) with a JMP to the
// end of the function, in order to ensure that it assembles correctly.
func TestLargeJump(t *testing.T) {
if testing.Short() {
t.Skip("Skipping test in short mode")
}
if runtime.GOARCH != "riscv64" {
t.Skip("Require riscv64 to run")
}
testenv.MustHaveGoBuild(t)

dir := t.TempDir()

if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module largejump"), 0644); err != nil {
t.Fatalf("Failed to write file: %v\n", err)
}
main := `package main
import "fmt"
func main() {
fmt.Print(x())
}
func x() uint64
`
if err := os.WriteFile(filepath.Join(dir, "x.go"), []byte(main), 0644); err != nil {
t.Fatalf("failed to write main: %v\n", err)
}

// Generate a very large jump instruction.
buf := bytes.NewBuffer(make([]byte, 0, 7000000))
genLargeJump(buf)

if err := os.WriteFile(filepath.Join(dir, "x.s"), buf.Bytes(), 0644); err != nil {
t.Fatalf("Failed to write file: %v\n", err)
}

// Build generated files.
cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "x.exe")
cmd.Dir = dir
out, err := cmd.CombinedOutput()
if err != nil {
t.Errorf("Build failed: %v, output: %s", err, out)
}

cmd = testenv.Command(t, filepath.Join(dir, "x.exe"))
out, err = cmd.CombinedOutput()
if string(out) != "1" {
t.Errorf(`Got test output %q, want "1"`, string(out))
}
}

func genLargeJump(buf *bytes.Buffer) {
fmt.Fprintln(buf, "TEXT ·x(SB),0,$0-8")
fmt.Fprintln(buf, "MOV X0, X10")
fmt.Fprintln(buf, "JMP end")
for i := 0; i < 1<<18; i++ {
fmt.Fprintln(buf, "ADD $1, X10, X10")
}
fmt.Fprintln(buf, "end:")
fmt.Fprintln(buf, "ADD $1, X10, X10")
fmt.Fprintln(buf, "MOV X10, r+0(FP)")
fmt.Fprintln(buf, "RET")
}

// Issue 20348.
func TestNoRet(t *testing.T) {
dir, err := os.MkdirTemp("", "testnoret")
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/internal/obj/riscv/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
ctxt.Diag("%v: jump displacement %d too large", p, p.To.Target().Pc-p.Pc)
}
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: high, Sym: cursym}
p.Link.From.Offset = low
p.Link.To.Offset = low
}
}
}
Expand Down

0 comments on commit d33548d

Please sign in to comment.