Text file src/runtime/libfuzzer_arm64.s

     1  // Copyright 2019 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_arm64.s; see commentary there.
    11  
    12  #define RARG0 R0
    13  #define RARG1 R1
    14  #define RARG2 R2
    15  #define RARG3 R3
    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·libfuzzerCallTraceIntCmp(fn, arg0, arg1, fakePC uintptr)
    22  // Calls C function fn from libFuzzer and passes 2 arguments to it after
    23  // manipulating the return address so that libfuzzer's integer compare hooks
    24  // work.
    25  // The problem statement and solution are documented in detail in libfuzzer_amd64.s.
    26  // See commentary there.
    27  TEXT	runtime·libfuzzerCallTraceIntCmp(SB), NOSPLIT, $8-32
    28  	MOVD	fn+0(FP), R9
    29  	MOVD	arg0+8(FP), RARG0
    30  	MOVD	arg1+16(FP), RARG1
    31  	MOVD	fakePC+24(FP), R8
    32  	// Save the original return address in a local variable
    33  	MOVD	R30, savedRetAddr-8(SP)
    34  
    35  	MOVD	g_m(g), R10
    36  
    37  	// Switch to g0 stack.
    38  	MOVD	RSP, R19	// callee-saved, preserved across the CALL
    39  	MOVD	m_g0(R10), R11
    40  	CMP	R11, g
    41  	BEQ	call	// already on g0
    42  	MOVD	(g_sched+gobuf_sp)(R11), R12
    43  	MOVD	R12, RSP
    44  call:
    45  	// Load address of the ret sled into the default register for the return
    46  	// address.
    47  	ADR	ret_sled, R30
    48  	// Clear the lowest 2 bits of fakePC. All ARM64 instructions are four
    49  	// bytes long, so we cannot get better return address granularity than
    50  	// multiples of 4.
    51  	AND	$-4, R8, R8
    52  	// Add the offset of the fake_pc-th ret.
    53  	ADD	R8, R30, R30
    54  	// Call the function by jumping to it and reusing all registers except
    55  	// for the modified return address register R30.
    56  	JMP	(R9)
    57  
    58  // The ret sled for ARM64 consists of 128 br instructions jumping to the
    59  // end of the function. Each instruction is 4 bytes long. The sled thus
    60  // has the same byte length of 4 * 128 = 512 as the x86_64 sled, but
    61  // coarser granularity.
    62  #define RET_SLED \
    63  	JMP	end_of_function;
    64  
    65  ret_sled:
    66  	REPEAT_128(RET_SLED);
    67  
    68  end_of_function:
    69  	MOVD	R19, RSP
    70  	MOVD	savedRetAddr-8(SP), R30
    71  	RET
    72  
    73  // void runtime·libfuzzerCall4(fn, hookId int, s1, s2 unsafe.Pointer, result uintptr)
    74  // Calls C function fn from libFuzzer and passes 4 arguments to it.
    75  TEXT	runtime·libfuzzerCall4(SB), NOSPLIT, $0-40
    76  	MOVD	fn+0(FP), R9
    77  	MOVD	hookId+8(FP), RARG0
    78  	MOVD	s1+16(FP), RARG1
    79  	MOVD	s2+24(FP), RARG2
    80  	MOVD	result+32(FP), RARG3
    81  
    82  	MOVD	g_m(g), R10
    83  
    84  	// Switch to g0 stack.
    85  	MOVD	RSP, R19	// callee-saved, preserved across the CALL
    86  	MOVD	m_g0(R10), R11
    87  	CMP	R11, g
    88  	BEQ	call	// already on g0
    89  	MOVD	(g_sched+gobuf_sp)(R11), R12
    90  	MOVD	R12, RSP
    91  call:
    92  	BL	R9
    93  	MOVD	R19, RSP
    94  	RET
    95  
    96  // void runtime·libfuzzerCallWithTwoByteBuffers(fn, start, end *byte)
    97  // Calls C function fn from libFuzzer and passes 2 arguments of type *byte to it.
    98  TEXT	runtime·libfuzzerCallWithTwoByteBuffers(SB), NOSPLIT, $0-24
    99  	MOVD	fn+0(FP), R9
   100  	MOVD	start+8(FP), R0
   101  	MOVD	end+16(FP), R1
   102  
   103  	MOVD	g_m(g), R10
   104  
   105  	// Switch to g0 stack.
   106  	MOVD	RSP, R19	// callee-saved, preserved across the CALL
   107  	MOVD	m_g0(R10), R11
   108  	CMP	R11, g
   109  	BEQ	call	// already on g0
   110  	MOVD	(g_sched+gobuf_sp)(R11), R12
   111  	MOVD	R12, RSP
   112  call:
   113  	BL	R9
   114  	MOVD	R19, RSP
   115  	RET
   116  

View as plain text