The verified mapping is the flat memory image, not section indexing
The fixe6b3e0bcalled for, with the verification that six commits kept deferring. First attempt assumed OverlaySection::data had a fixed 16-byte header to skip and added section_content() plus section_bytes_at() accordingly. The verification test caught it immediately: section 0 read "syst" at data[16], which is a string, not code. The embedded header contains variable-length strings -- "crap", "system", "isc" in level 0 -- so there is no fixed header size to skip. What is actually true: the overlay lump is a MEMORY IMAGE. Its first word is 0x001A7C80, the load address of .lit, and overlay[addr - LIT_BASE] is the byte at addr. That is what tools/overlay-anchors has been using all along, and it is correct. So overlay_bytes_at(overlay, addr) replaces the section-indexing approach entirely. Bounds-checked, so it cannot read past the image. THE TEST, and it pins the word that exposed everything overlay_section_index_agrees_with_the_flat_blob asserts u32 at 0x2ee138 == 0x4bc00083 (what capstone reports) u32 at overlay[0] == LIT_BASE (it is a memory image) every section dest is addressable via the flat mapping 105 words checked, passing. The 0x2ee138 assertion is the one that matters: it is the disagreement that started this, now recorded as a fact the build checks. What this does not do: re-read 0x2ee138, or redo any of the sixteen probes. Those need redoing on correct bytes, and until they are the immediate-frequency and disassembly results from3ea5ab7throughf2d7e7eremain invalid as exact claims. Worth recording the order of events, because it is the whole arc of this investigation in miniature. I wrote a helper with an assumed constant, wrote the test that would catch it being wrong, the test failed, and the assumption was wrong. That sequence -- implement, then verify against a known word, then correct -- took about three minutes at the end and would have saved sixteen probes at the start. 285 passing with the disc present (23 + 19 + 65 + 156 + 22; disc binary 34.94s), clippy clean.
This commit is contained in:
@@ -63,6 +63,28 @@ pub struct OverlaySection {
|
||||
}
|
||||
|
||||
/// Splits the raw `overlay` lump into its sections.
|
||||
/// RAM address at which the overlay's `.lit` section is loaded.
|
||||
pub const LIT_BASE: u32 = 0x001A_7C80;
|
||||
|
||||
/// The bytes of the overlay at load address `addr`.
|
||||
///
|
||||
/// The overlay lump is a **memory image**: its first word is `0x001A7C80`, the
|
||||
/// load address of `.lit`, and `overlay[addr - LIT_BASE]` is the byte at `addr`.
|
||||
///
|
||||
/// This, not [`OverlaySection`] indexing, is the correct way to read code out of
|
||||
/// the overlay. `OverlaySection::data` is a slice of the *section table* entry and
|
||||
/// begins with an embedded header containing variable-length strings ("crap",
|
||||
/// "system", "isc" in level 0), so there is no fixed header size to skip and no
|
||||
/// offset from `dest` that lands on loadable content.
|
||||
///
|
||||
/// Bounds-checked. Sixteen probes indexed `secs[n].data` by `addr - dest` and read
|
||||
/// displaced bytes; this function exists so that cannot recur.
|
||||
#[must_use]
|
||||
pub fn overlay_bytes_at(overlay: &[u8], addr: u32) -> Option<&[u8]> {
|
||||
let off = addr.checked_sub(LIT_BASE)? as usize;
|
||||
overlay.get(off..)
|
||||
}
|
||||
|
||||
pub fn parse_overlay_sections(overlay: &[u8]) -> Result<Vec<OverlaySection>> {
|
||||
let b = Buf::new(overlay);
|
||||
let mut out: Vec<OverlaySection> = Vec::new();
|
||||
|
||||
Reference in New Issue
Block a user