diff options
Diffstat (limited to 'rsnix/src/memory.rs')
| -rw-r--r-- | rsnix/src/memory.rs | 39 |
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 | ||
| 94 | fn 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. | ||
| 97 | pub 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. | ||
| 112 | pub 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. |
| 105 | const HEAP_GROW_PAGES: usize = 64; | 142 | const HEAP_GROW_PAGES: usize = 64; |
| 106 | 143 | ||
