Skip to content

Commit 22cedb2

Browse files
authored
Add initial support for riscv64 (#102)
* crash-context: add riscv64 support getcontext ported from Breakpad and portable context structs from libc crate. * sadness-generator: add riscv64 support * crash-handler: add riscv64 support
1 parent 33b75f5 commit 22cedb2

File tree

6 files changed

+173
-3
lines changed

6 files changed

+173
-3
lines changed

crash-context/src/linux.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,61 @@ cfg_if::cfg_if! {
256256
pub arm_cpsr: u32,
257257
pub fault_address: u32,
258258
}
259+
} else if #[cfg(target_arch = "riscv64")] {
260+
#[repr(C)]
261+
#[derive(Clone)]
262+
#[doc(hidden)]
263+
pub struct ucontext_t {
264+
pub __uc_flags: u64,
265+
pub uc_link: *mut ucontext_t,
266+
pub uc_stack: stack_t,
267+
pub uc_sigmask: sigset_t,
268+
pub uc_mcontext: mcontext_t,
269+
}
270+
271+
#[repr(C, align(16))]
272+
#[derive(Clone)]
273+
#[doc(hidden)]
274+
pub struct mcontext_t {
275+
pub __gregs: [u64; 32],
276+
pub __fpregs: __riscv_mc_fp_state,
277+
}
278+
279+
#[repr(C)]
280+
#[derive(Clone, Copy)]
281+
#[doc(hidden)]
282+
pub union __riscv_mc_fp_state {
283+
pub __f: __riscv_mc_f_ext_state,
284+
pub __d: __riscv_mc_d_ext_state,
285+
pub __q: __riscv_mc_q_ext_state,
286+
}
287+
288+
#[repr(C)]
289+
#[derive(Clone, Copy)]
290+
#[doc(hidden)]
291+
pub struct __riscv_mc_f_ext_state {
292+
pub __f: [u32; 32],
293+
pub __fcsr: u32,
294+
}
295+
296+
#[repr(C)]
297+
#[derive(Clone, Copy)]
298+
#[doc(hidden)]
299+
pub struct __riscv_mc_d_ext_state {
300+
pub __f: [u64; 32],
301+
pub __fcsr: u32,
302+
}
303+
304+
#[repr(C, align(16))]
305+
#[derive(Clone, Copy)]
306+
#[doc(hidden)]
307+
pub struct __riscv_mc_q_ext_state {
308+
pub __f: [u64; 64],
309+
pub __fcsr: u32,
310+
pub __reserved: [u32; 3],
311+
}
312+
313+
pub type fpregset_t = __riscv_mc_fp_state;
259314
}
260315
}
261316

crash-context/src/linux/getcontext.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ cfg_if::cfg_if! {
2020
mod aarch64;
2121
} else if #[cfg(target_arch = "arm")] {
2222
mod arm;
23+
} else if #[cfg(target_arch = "riscv64")] {
24+
mod riscv64;
2325
}
2426
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// UCONTEXT_SIGMASK_OFFSET = 40
2+
// MCONTEXT_GREGS_OFFSET = 168
3+
// MCONTEXT_GREGS_SIZE = 8
4+
5+
std::arch::global_asm! {
6+
".text",
7+
".globl crash_context_getcontext",
8+
".hidden crash_context_getcontext",
9+
".type crash_context_getcontext, @function",
10+
".align 0",
11+
".cfi_startproc",
12+
"crash_context_getcontext:",
13+
14+
// Save general registers
15+
"sd ra, 0xa8(a0)",
16+
"sd ra, 0xb0(a0)",
17+
"sd sp, 0xb8(a0)",
18+
"sd gp, 0xc0(a0)",
19+
"sd tp, 0xc8(a0)",
20+
"sd t0, 0xd0(a0)",
21+
"sd t1, 0xd8(a0)",
22+
"sd t2, 0xe0(a0)",
23+
"sd s0, 0xe8(a0)",
24+
"sd s1, 0xf0(a0)",
25+
"sd a0, 0xf8(a0)",
26+
"sd a1, 0x100(a0)",
27+
"sd a2, 0x108(a0)",
28+
"sd a3, 0x110(a0)",
29+
"sd a4, 0x118(a0)",
30+
"sd a5, 0x120(a0)",
31+
"sd a6, 0x128(a0)",
32+
"sd a7, 0x130(a0)",
33+
"sd s2, 0x138(a0)",
34+
"sd s3, 0x140(a0)",
35+
"sd s4, 0x148(a0)",
36+
"sd s5, 0x150(a0)",
37+
"sd s6, 0x158(a0)",
38+
"sd s7, 0x160(a0)",
39+
"sd s8, 0x168(a0)",
40+
"sd s9, 0x170(a0)",
41+
"sd s10, 0x178(a0)",
42+
"sd s11, 0x180(a0)",
43+
"sd t3, 0x188(a0)",
44+
"sd t4, 0x190(a0)",
45+
"sd t5, 0x198(a0)",
46+
"sd t6 , 0x1a0(a0)",
47+
48+
// Save floating point registers
49+
"frsr a1", // Save CSR
50+
"fsd ft0, 0x1a8(a0)",
51+
"fsd ft1, 0x1b0(a0)",
52+
"fsd ft2, 0x1b8(a0)",
53+
"fsd ft3, 0x1c0(a0)",
54+
"fsd ft4, 0x1c8(a0)",
55+
"fsd ft5, 0x1d0(a0)",
56+
"fsd ft6, 0x1d8(a0)",
57+
"fsd ft7, 0x1e0(a0)",
58+
"fsd fs0, 0x1e8(a0)",
59+
"fsd fs1, 0x1f0(a0)",
60+
"fsd fa0, 0x1f8(a0)",
61+
"fsd fa1, 0x200(a0)",
62+
"fsd fa2, 0x208(a0)",
63+
"fsd fa3, 0x210(a0)",
64+
"fsd fa4, 0x218(a0)",
65+
"fsd fa5, 0x220(a0)",
66+
"fsd fa6, 0x228(a0)",
67+
"fsd fa7, 0x230(a0)",
68+
"fsd fs2, 0x238(a0)",
69+
"fsd fs3, 0x240(a0)",
70+
"fsd fs4, 0x248(a0)",
71+
"fsd fs5, 0x250(a0)",
72+
"fsd fs6, 0x258(a0)",
73+
"fsd fs7, 0x260(a0)",
74+
"fsd fs8, 0x268(a0)",
75+
"fsd fs9, 0x270(a0)",
76+
"fsd fs10, 0x278(a0)",
77+
"fsd fs11, 0x280(a0)",
78+
"fsd ft8, 0x288(a0)",
79+
"fsd ft9, 0x290(a0)",
80+
"fsd ft10, 0x298(a0)",
81+
"fsd ft11, 0x2a0(a0)",
82+
"sw a1, 0x2a8(a0)",
83+
84+
"mv a1, zero",
85+
"add a2, a0, 40", // UCONTEXT_SIGMASK_OFFSET
86+
"li a3, 8", // _NSIG8
87+
"mv a0, zero",
88+
"li a7, 135", // __NR_rt_sigprocmask
89+
"ecall",
90+
91+
"mv a0, zero",
92+
"ret",
93+
94+
".cfi_endproc",
95+
".size crash_context_getcontext, . - crash_context_getcontext",
96+
}

crash-handler/src/linux/jmp.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ cfg_if::cfg_if! {
3737
#[doc(hidden)]
3838
#[allow(non_camel_case_types)]
3939
pub struct __jmp_buf([u64; 22]);
40+
} else if #[cfg(target_arch = "riscv64")] {
41+
#[repr(C)]
42+
#[doc(hidden)]
43+
#[allow(non_camel_case_types)]
44+
pub struct __jmp_buf {
45+
__pc: u64,
46+
__regs: [u64; 12],
47+
__sp: u64,
48+
__fpregs: [f64; 12],
49+
}
4050
}
4151
}
4252

crash-handler/src/linux/state.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ impl HandlerInner {
457457
if (*fp_ptr).head.magic == crash_context::FPSIMD_MAGIC {
458458
ptr::copy_nonoverlapping(fp_ptr, &mut cc.float_state, 1);
459459
}
460+
} else if #[cfg(target_arch = "riscv64")] {
461+
cc.float_state = uc_ptr.uc_mcontext.__fpregs;
460462
} else if #[cfg(not(target_arch = "arm"))] {
461463
if !uc_ptr.uc_mcontext.fpregs.is_null() {
462464
ptr::copy_nonoverlapping(uc_ptr.uc_mcontext.fpregs, ((&mut cc.float_state) as *mut crash_context::fpregset_t).cast(), 1);

sadness-generator/src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,11 @@ pub unsafe fn raise_floating_point_exception() -> ! {
159159
);
160160
divisor
161161
}
162-
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
162+
#[cfg(any(target_arch = "arm", target_arch = "aarch64", target_arch = "riscv64"))]
163163
{
164-
// Unfortunately ARM by default will not raise SIGFPE on divide
165-
// by 0 and just return 0, so we just explicitly raise here for now
164+
// Unfortunately ARM and RISC-V by default will not raise SIGFPE on
165+
// divide by 0 and just return 0, so we just explicitly raise here
166+
// for now
166167
libc::raise(libc::SIGFPE);
167168
0
168169
}
@@ -184,6 +185,8 @@ pub unsafe fn raise_illegal_instruction() -> ! {
184185
asm!("ud2");
185186
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
186187
asm!("udf #0");
188+
#[cfg(target_arch = "riscv64")]
189+
asm!(".word 0x00000000");
187190
}
188191

189192
std::process::abort()
@@ -247,6 +250,8 @@ pub unsafe fn raise_trap() -> ! {
247250
asm!(".inst 0xe7f001f0");
248251
#[cfg(target_arch = "aarch64")]
249252
asm!(".inst 0xd4200000");
253+
#[cfg(target_arch = "riscv64")]
254+
asm!("ebreak");
250255
}
251256

252257
std::process::abort()

0 commit comments

Comments
 (0)