Skip to content

Commit d33548d

Browse files
MouseSplintermengzhuo
authored andcommitted
cmd/internal/obj/riscv: fix the offset of JALR transformed from JAL
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>
1 parent b54cae2 commit d33548d

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

src/cmd/internal/obj/riscv/asm_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,72 @@ func genLargeCall(buf *bytes.Buffer) {
126126
fmt.Fprintln(buf, "RET")
127127
}
128128

129+
// TestLargeJump generates a large jump (>1MB of text) with a JMP to the
130+
// end of the function, in order to ensure that it assembles correctly.
131+
func TestLargeJump(t *testing.T) {
132+
if testing.Short() {
133+
t.Skip("Skipping test in short mode")
134+
}
135+
if runtime.GOARCH != "riscv64" {
136+
t.Skip("Require riscv64 to run")
137+
}
138+
testenv.MustHaveGoBuild(t)
139+
140+
dir := t.TempDir()
141+
142+
if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module largejump"), 0644); err != nil {
143+
t.Fatalf("Failed to write file: %v\n", err)
144+
}
145+
main := `package main
146+
147+
import "fmt"
148+
149+
func main() {
150+
fmt.Print(x())
151+
}
152+
153+
func x() uint64
154+
`
155+
if err := os.WriteFile(filepath.Join(dir, "x.go"), []byte(main), 0644); err != nil {
156+
t.Fatalf("failed to write main: %v\n", err)
157+
}
158+
159+
// Generate a very large jump instruction.
160+
buf := bytes.NewBuffer(make([]byte, 0, 7000000))
161+
genLargeJump(buf)
162+
163+
if err := os.WriteFile(filepath.Join(dir, "x.s"), buf.Bytes(), 0644); err != nil {
164+
t.Fatalf("Failed to write file: %v\n", err)
165+
}
166+
167+
// Build generated files.
168+
cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "x.exe")
169+
cmd.Dir = dir
170+
out, err := cmd.CombinedOutput()
171+
if err != nil {
172+
t.Errorf("Build failed: %v, output: %s", err, out)
173+
}
174+
175+
cmd = testenv.Command(t, filepath.Join(dir, "x.exe"))
176+
out, err = cmd.CombinedOutput()
177+
if string(out) != "1" {
178+
t.Errorf(`Got test output %q, want "1"`, string(out))
179+
}
180+
}
181+
182+
func genLargeJump(buf *bytes.Buffer) {
183+
fmt.Fprintln(buf, "TEXT ·x(SB),0,$0-8")
184+
fmt.Fprintln(buf, "MOV X0, X10")
185+
fmt.Fprintln(buf, "JMP end")
186+
for i := 0; i < 1<<18; i++ {
187+
fmt.Fprintln(buf, "ADD $1, X10, X10")
188+
}
189+
fmt.Fprintln(buf, "end:")
190+
fmt.Fprintln(buf, "ADD $1, X10, X10")
191+
fmt.Fprintln(buf, "MOV X10, r+0(FP)")
192+
fmt.Fprintln(buf, "RET")
193+
}
194+
129195
// Issue 20348.
130196
func TestNoRet(t *testing.T) {
131197
dir, err := os.MkdirTemp("", "testnoret")

src/cmd/internal/obj/riscv/obj.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
727727
ctxt.Diag("%v: jump displacement %d too large", p, p.To.Target().Pc-p.Pc)
728728
}
729729
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: high, Sym: cursym}
730-
p.Link.From.Offset = low
730+
p.Link.To.Offset = low
731731
}
732732
}
733733
}

0 commit comments

Comments
 (0)