_offc_probe_callchain.nx source
↩ module page · 75 lines · 2556 B
1// Bisects which IR-construction call clobbers `f` (the s-reg that
2// holds the Function pointer returned by ir_function_new). After
3// each call, print a marker character; if f is corrupted by an
4// intermediate call, the run will SIGSEGV at the next f-dereference
5// and we'll know the boundary from the last marker printed.
6
7import "nx_syscalls.nx"
8import "nx_types.nx"
9import "nx_ir.nx"
10
11func mark(c: i64) -> i64 {
12 let m: *u8 = sys_mmap(8)
13 m[0] = c
14 m[1] = 0x0A
15 sys_write(1, m, 2)
16 return 0
17}
18
19func probe_f(f: *Function, c: i64) -> i64 {
20 // Read f.n_values; if f is broken this will SIGSEGV.
21 let n: i64 = f.n_values
22 let m: *u8 = sys_mmap(8)
23 m[0] = c
24 m[1] = 0x30 + n
25 m[2] = 0x0A
26 sys_write(1, m, 3)
27 return n
28}
29
30func main() -> i64 {
31 let m_raw: *u8 = sys_mmap(256)
32 let m: *Module = m_raw as *Module
33 m.name = "test" as *u8
34 m.functions = 0 as *Function
35 m.n_functions = 0
36
37 let f: *Function = ir_function_new(m, "main" as *u8, 4, ir_type_i64())
38 probe_f(f, 0x41) // A: after ir_function_new
39 let b: *BasicBlock = ir_block_new(f)
40 probe_f(f, 0x42) // B: after ir_block_new
41 let c10: i64 = ir_const_i64(f, 10)
42 probe_f(f, 0x43) // C: after ir_const_i64 x1
43 let c20: i64 = ir_const_i64(f, 20)
44 probe_f(f, 0x44) // D: after ir_const_i64 x2
45 let sum: i64 = ir_emit_binop(b, OP_ADD, c10, c20, ir_type_i64())
46 probe_f(f, 0x45) // E: after ir_emit_binop
47 ir_emit_return(b, sum)
48 probe_f(f, 0x46) // F: after ir_emit_return
49
50 let locs_raw: *u8 = sys_mmap(f.n_values * 16 + 16)
51 probe_f(f, 0x47) // G: after locs_raw alloc
52
53 let mask_raw: *u8 = sys_mmap(16)
54 let mask: *i64 = mask_raw as *i64
55 *mask = 0
56 probe_f(f, 0x48) // H: after mask alloc + init
57
58 let sb_raw: *u8 = sys_mmap(16)
59 let sb: *i64 = sb_raw as *i64
60 *sb = 0
61 probe_f(f, 0x49) // I: after sb alloc + init
62
63 let mask_fpr_raw: *u8 = sys_mmap(16)
64 let mask_fpr: *i64 = mask_fpr_raw as *i64
65 *mask_fpr = 0
66 probe_f(f, 0x4A) // J: after mask_fpr alloc + init
67
68 sys_write(1, "before call\n" as *u8, 12)
69 let locs: *ValueLoc = locs_raw as *ValueLoc
70 regalloc_function(f, locs, mask, mask_fpr, sb)
71 sys_write(1, "after call\n" as *u8, 11)
72
73 sys_write(1, "ok\n" as *u8, 3)
74 return 0
75}