summaryrefslogtreecommitdiffstats
path: root/rsnix/src/memory.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-02 16:06:40 +0200
committersalmonik <salmonik@tuta.io>2026-08-02 16:06:40 +0200
commita459dd3fb267bfba24c3fad1e3dc789bf50ee20b (patch)
treef2d541f442d9fec5cf6ecb210c5b89710870ecfb /rsnix/src/memory.rs
parentv0.5.5: on-screen boot markers for disk/fs stage (diff)
downloadrs-dos-a459dd3fb267bfba24c3fad1e3dc789bf50ee20b.tar.gz
rs-dos-a459dd3fb267bfba24c3fad1e3dc789bf50ee20b.zip
v0.5.6: fault dumps carry kernel image base + stack backtrace
- fault_dump prints img= (kernel image base) on the serial line and the on-screen band, so a real-hardware repro can be resolved against the PDB without serial - backtrace: rbp-chain walk then a raw scan of the stack above the interrupted rsp; both filter to the .text range (PE-header parse via memory::text_range) so only code addresses are collected - on-screen boot marker shows the kernel image range at every boot - crash.log now records img= + bt= lines alongside rip/rsp
Diffstat (limited to '')
-rw-r--r--rsnix/src/memory.rs39
1 files changed, 38 insertions, 1 deletions
diff --git a/rsnix/src/memory.rs b/rsnix/src/memory.rs
index e6896f2..35f3464 100644
--- a/rsnix/src/memory.rs
+++ b/rsnix/src/memory.rs
@@ -91,7 +91,10 @@ pub fn set_kernel_image_range(base: usize, size: usize) {
91 } 91 }
92} 92}
93 93
94fn kernel_image_range() -> Option<(usize, usize)> { 94/// The loaded kernel image range `(start, end)`, if known. Used to
95/// resolve fault RIPs against the symbol table and to filter stack
96/// scans for return addresses.
97pub fn kernel_image_range() -> Option<(usize, usize)> {
95 unsafe { 98 unsafe {
96 if KERNEL_IMAGE_END > KERNEL_IMAGE_START { 99 if KERNEL_IMAGE_END > KERNEL_IMAGE_START {
97 Some((KERNEL_IMAGE_START, KERNEL_IMAGE_END)) 100 Some((KERNEL_IMAGE_START, KERNEL_IMAGE_END))
@@ -101,6 +104,40 @@ fn kernel_image_range() -> Option<(usize, usize)> {
101 } 104 }
102} 105}
103 106
107/// The in-memory `.text` section range `(start, end)`, parsed from the
108/// loaded PE headers. Used to filter fault backtraces: only code
109/// addresses are meaningful return addresses (the rest of the image
110/// range is .rdata/.data pointers). Falls back to the full image
111/// range if the headers are unreadable.
112pub fn text_range() -> Option<(usize, usize)> {
113 let (base, _end) = kernel_image_range()?;
114 unsafe {
115 let base = base as *const u8;
116 if base.read() != b'M' || base.add(1).read() != b'Z' {
117 return kernel_image_range();
118 }
119 let e_lfanew = (base.add(0x3c) as *const u32).read() as usize;
120 let pe = base.add(e_lfanew);
121 if (pe as *const u32).read() != 0x4550 {
122 return kernel_image_range();
123 }
124 let fh = pe.add(4); // COFF file header (20 bytes)
125 let size_opt = (fh.add(16) as *const u16).read() as usize;
126 let nsec = (fh.add(2) as *const u16).read() as usize;
127 let sec = fh.add(20).add(size_opt);
128 for i in 0..nsec {
129 let s = sec.add(i * 40);
130 let nm = core::slice::from_raw_parts(s, 8);
131 if nm.starts_with(b".text") {
132 let vsz = (s.add(8) as *const u32).read() as usize;
133 let va = (s.add(12) as *const u32).read() as usize;
134 return Some((base as usize + va, base as usize + va + vsz));
135 }
136 }
137 kernel_image_range()
138 }
139}
140
104/// Minimum pages `grow_heap` takes from the page allocator per growth. 141/// Minimum pages `grow_heap` takes from the page allocator per growth.
105const HEAP_GROW_PAGES: usize = 64; 142const HEAP_GROW_PAGES: usize = 64;
106 143