Skip to content

Commit dc1e255

Browse files
limeidanabner-chenc
authored andcommitted
runtime, internal/fuzz: add comparison tracing for libFuzzer on loong64
Change-Id: I212330962453139fa353db29928786b64c9ff063 Reviewed-on: https://go-review.googlesource.com/c/go/+/667455 Reviewed-by: abner chenc <[email protected]> Reviewed-by: Junyang Shao <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent fb2c881 commit dc1e255

File tree

5 files changed

+117
-3
lines changed

5 files changed

+117
-3
lines changed

src/cmd/cgo/internal/testsanitizers/libfuzzer_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ func libFuzzerSupported(goos, goarch string) bool {
9595
default:
9696
return false
9797
}
98+
case "loong64":
99+
return true
98100
default:
99101
return false
100102
}

src/internal/fuzz/counters_supported.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build (darwin || linux || windows || freebsd || openbsd) && (amd64 || arm64)
5+
//go:build ((darwin || linux || windows || freebsd || openbsd) && (amd64 || arm64)) || loong64
66

77
package fuzz
88

src/internal/fuzz/counters_unsupported.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
//
99
// If you update this constraint, also update internal/platform.FuzzInstrumented.
1010
//
11-
//go:build !((darwin || linux || windows || freebsd || openbsd) && (amd64 || arm64))
11+
//go:build !((darwin || linux || windows || freebsd || openbsd) && (amd64 || arm64)) && !loong64
1212

1313
package fuzz
1414

src/internal/platform/supported.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func FuzzSupported(goos, goarch string) bool {
7272
// instrumentation. (FuzzInstrumented implies FuzzSupported.)
7373
func FuzzInstrumented(goos, goarch string) bool {
7474
switch goarch {
75-
case "amd64", "arm64":
75+
case "amd64", "arm64", "loong64":
7676
// TODO(#14565): support more architectures.
7777
return FuzzSupported(goos, goarch)
7878
default:

src/runtime/libfuzzer_loong64.s

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build libfuzzer
6+
7+
#include "go_asm.h"
8+
#include "textflag.h"
9+
10+
// Based on race_loong64.s; see commentary there.
11+
12+
#define RARG0 R4
13+
#define RARG1 R5
14+
#define RARG2 R6
15+
#define RARG3 R7
16+
17+
#define REPEAT_2(a) a a
18+
#define REPEAT_8(a) REPEAT_2(REPEAT_2(REPEAT_2(a)))
19+
#define REPEAT_128(a) REPEAT_2(REPEAT_8(REPEAT_8(a)))
20+
21+
// void runtime·libfuzzerCall4(fn, hookId int, s1, s2 unsafe.Pointer, result uintptr)
22+
// Calls C function fn from libFuzzer and passes 4 arguments to it.
23+
TEXT runtime·libfuzzerCall4<ABIInternal>(SB), NOSPLIT, $0-0
24+
MOVV R4, R12 // fn
25+
MOVV R5, RARG0 // hookId
26+
MOVV R6, RARG1 // s1
27+
MOVV R7, RARG2 // s2
28+
MOVV R8, RARG3 // result
29+
30+
MOVV g_m(g), R13
31+
32+
// Switch to g0 stack.
33+
MOVV R3, R23 // callee-saved, preserved across the CALL
34+
MOVV m_g0(R13), R14
35+
BEQ R14, g, call // already on g0
36+
MOVV (g_sched+gobuf_sp)(R14), R3
37+
38+
call:
39+
JAL (R12)
40+
MOVV R23, R3
41+
RET
42+
43+
// void runtime·libfuzzerCallWithTwoByteBuffers(fn, start, end *byte)
44+
// Calls C function fn from libFuzzer and passes 2 arguments of type *byte to it.
45+
TEXT runtime·libfuzzerCallWithTwoByteBuffers<ABIInternal>(SB), NOSPLIT, $0-0
46+
MOVV R4, R12 // fn
47+
MOVV R5, RARG0 // start
48+
MOVV R6, RARG1 // end
49+
50+
MOVV g_m(g), R13
51+
52+
// Switch to g0 stack.
53+
MOVV R3, R23 // callee-saved, preserved across the CALL
54+
MOVV m_g0(R13), R14
55+
BEQ R14, g, call // already on g0
56+
MOVV (g_sched+gobuf_sp)(R14), R3
57+
58+
call:
59+
JAL (R12)
60+
MOVV R23, R3
61+
RET
62+
63+
// void runtime·libfuzzerCallTraceIntCmp(fn, arg0, arg1, fakePC uintptr)
64+
// Calls C function fn from libFuzzer and passes 2 arguments to it after
65+
// manipulating the return address so that libfuzzer's integer compare hooks
66+
// work.
67+
// The problem statement and solution are documented in detail in libfuzzer_amd64.s.
68+
// See commentary there.
69+
TEXT runtime·libfuzzerCallTraceIntCmp<ABIInternal>(SB), NOSPLIT, $0-0
70+
MOVV R4, R12 // fn
71+
MOVV R5, RARG0 // arg0
72+
MOVV R6, RARG1 // arg1
73+
// Save the original return address in a local variable
74+
MOVV R1, savedRetAddr-8(SP)
75+
76+
MOVV g_m(g), R13
77+
78+
// Switch to g0 stack.
79+
MOVV R3, R23 // callee-saved, preserved across the CALL
80+
MOVV m_g0(R13), R14
81+
BEQ R14, g, call // already on g0
82+
MOVV (g_sched+gobuf_sp)(R14), R3
83+
84+
call:
85+
// Load address of the ret sled into the default register for the return
86+
// address.
87+
MOVV $ret_sled(SB), R1
88+
// Clear the lowest 2 bits of fakePC. All Loong64 instructions are four
89+
// bytes long, so we cannot get better return address granularity than
90+
// multiples of 4.
91+
AND $-4, R7
92+
// Load the address of the i'th return instruction from the return sled.
93+
// The index is given in the fakePC argument.
94+
ADDV R7, R1
95+
// Call the function by jumping to it and reusing all registers except
96+
// for the modified return address register R1.
97+
JMP (R12)
98+
99+
// The ret sled for Loong64 consists of 128 br instructions jumping to the
100+
// end of the function. Each instruction is 4 bytes long. The sled thus has
101+
// the same byte length of 4 * 128 = 512 as the x86_64 sled, but coarser
102+
// granularity.
103+
#define RET_SLED \
104+
JMP end_of_function;
105+
106+
TEXT ret_sled(SB), NOSPLIT, $0-0
107+
REPEAT_128(RET_SLED);
108+
109+
end_of_function:
110+
MOVV R23, R3
111+
MOVV savedRetAddr-8(SP), R1
112+
RET

0 commit comments

Comments
 (0)