code wiki / (root) / _offc_probe_callchain.nx

_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}