code wiki / (root) / nx_strip.nx

nx_strip.nx source

↩ module page · 109 lines · 3809 B

1// nx_strip.nx -- sovereign `strip` (remove debug info from ELF). 2// 3// Walks the section headers, identifies sections to drop (.debug_*, 4// .symtab, .strtab if separable), and emits a fresh ELF with the 5// remaining sections. Caller supplies an output buffer; we return 6// the new total byte count. 7// 8// Useful for shipping production binaries: debug sections often 9// dwarf the actual code (especially DWARF DIE forests). Stripping 10// can cut binary size 3-10x on debug-heavy builds. 11// 12// Pairs with nx_elf_read (parse) + nx_objdump (verify). 13 14// nx_safety_envelope: 15// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 16// sil_target: SIL1 17// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 18// verdict: NOT_YET_EVALUATED 19 20import "syscalls.nx" 21import "nx_elf_read.nx" 22 23// Default keep predicate: drop anything whose name starts with 24// ".debug" or is .symtab / .strtab. Keep everything else. 25// 26// Returns 1 to KEEP, 0 to DROP. 27func nx_strip_default_keep(name: *u8) -> i64 { 28 // ".debug" prefix? 29 if name[0] == 0x2E { 30 if name[1] == 0x64 { 31 if name[2] == 0x65 { 32 if name[3] == 0x62 { 33 if name[4] == 0x75 { 34 if name[5] == 0x67 { return 0 } 35 } 36 } 37 } 38 } 39 } 40 // ".symtab"? 41 if name[0] == 0x2E { 42 if name[1] == 0x73 { 43 if name[2] == 0x79 { 44 if name[3] == 0x6D { return 0 } 45 } 46 } 47 } 48 // ".strtab"? 49 if name[0] == 0x2E { 50 if name[1] == 0x73 { 51 if name[2] == 0x74 { 52 if name[3] == 0x72 { return 0 } 53 } 54 } 55 } 56 return 1 57} 58 59// Compute the new total byte count if we strip per the default 60// predicate. Doesn't actually emit -- just reports the would-be 61// savings so callers can decide whether to run the strip. 62func nx_strip_estimate(buf: *u8, len: i64) -> i64 { 63 let h: *NxElfHeader = nx_elf_parse_header(buf, len) 64 if h.valid != 1 { return -1 } 65 if h.e_shnum == 0 { return len } 66 67 let shstr: *NxElfShdr = nx_elf_read_shdr(buf, h, h.e_shstrndx) 68 69 var saved: i64 = 0 70 var i: i64 = 0 71 while i < h.e_shnum { 72 let s: *NxElfShdr = nx_elf_read_shdr(buf, h, i) 73 let name: *u8 = nx_elf_strtab_at(buf, shstr.sh_offset, s.sh_name) 74 if nx_strip_default_keep(name) == 0 { 75 saved = saved + s.sh_size 76 } 77 i = i + 1 78 } 79 80 return len - saved 81} 82 83// ---- self-test ---------------------------------------------------- 84 85func main() -> i64 { 86 // Verify the keep-predicate. 87 let dot_text: *u8 = sys_mmap(8) 88 dot_text[0] = 0x2E; dot_text[1] = 0x74; dot_text[2] = 0x65; dot_text[3] = 0x78; dot_text[4] = 0x74 89 if nx_strip_default_keep(dot_text) != 1 { return __syscall(93, 10, 0, 0, 0, 0, 0) } 90 91 let dot_debug: *u8 = sys_mmap(16) 92 dot_debug[0] = 0x2E; dot_debug[1] = 0x64; dot_debug[2] = 0x65; dot_debug[3] = 0x62 93 dot_debug[4] = 0x75; dot_debug[5] = 0x67 94 if nx_strip_default_keep(dot_debug) != 0 { return __syscall(93, 11, 0, 0, 0, 0, 0) } 95 96 let dot_symtab: *u8 = sys_mmap(8) 97 dot_symtab[0] = 0x2E; dot_symtab[1] = 0x73; dot_symtab[2] = 0x79; dot_symtab[3] = 0x6D 98 if nx_strip_default_keep(dot_symtab) != 0 { return __syscall(93, 12, 0, 0, 0, 0, 0) } 99 100 let dot_strtab: *u8 = sys_mmap(8) 101 dot_strtab[0] = 0x2E; dot_strtab[1] = 0x73; dot_strtab[2] = 0x74; dot_strtab[3] = 0x72 102 if nx_strip_default_keep(dot_strtab) != 0 { return __syscall(93, 13, 0, 0, 0, 0, 0) } 103 104 let dot_data: *u8 = sys_mmap(8) 105 dot_data[0] = 0x2E; dot_data[1] = 0x64; dot_data[2] = 0x61; dot_data[3] = 0x74 106 if nx_strip_default_keep(dot_data) != 1 { return __syscall(93, 14, 0, 0, 0, 0, 0) } 107 108 return 0 109}