Ground first infrastructure record prelude
This commit is contained in:
parent
1a0296ddd1
commit
dfd3204e9a
3 changed files with 413 additions and 3 deletions
|
|
@ -1829,6 +1829,16 @@ pub struct SmpSavePlacedStructureDynamicSideBufferProbe {
|
|||
pub owner_shared_dword_hex: String,
|
||||
pub owner_shared_dword_relative_offset: usize,
|
||||
pub owner_shared_dword_matches_first_compact_prefix_leading_dword: bool,
|
||||
#[serde(default)]
|
||||
pub first_record_child_count_after_owner_shared: Option<u16>,
|
||||
#[serde(default)]
|
||||
pub first_record_child_count_after_owner_shared_hex: Option<String>,
|
||||
#[serde(default)]
|
||||
pub first_record_saved_primary_child_byte_after_owner_shared: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub first_record_saved_primary_child_byte_after_owner_shared_hex: Option<String>,
|
||||
#[serde(default)]
|
||||
pub first_record_first_name_tag_relative_offset_after_owner_shared: Option<usize>,
|
||||
pub prefix_leading_dword: u32,
|
||||
pub prefix_leading_dword_hex: String,
|
||||
pub prefix_trailing_word: u16,
|
||||
|
|
@ -1858,6 +1868,9 @@ pub struct SmpSavePlacedStructureDynamicSideBufferProbe {
|
|||
#[serde(default)]
|
||||
pub payload_envelope_summary:
|
||||
Option<SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSummary>,
|
||||
#[serde(default)]
|
||||
pub live_entry_prelude_summary:
|
||||
Option<SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSummary>,
|
||||
pub evidence: Vec<String>,
|
||||
}
|
||||
|
||||
|
|
@ -2036,6 +2049,57 @@ pub struct SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSample {
|
|||
pub profile_chunk_len_to_next_name_or_end: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSummary {
|
||||
pub live_entry_directory_row_count: usize,
|
||||
pub decoded_live_entry_id_count: usize,
|
||||
pub payload_relative_offset_monotonic: bool,
|
||||
pub rows_with_payload_pointer_inside_records_span: usize,
|
||||
pub rows_with_zero_child_count: usize,
|
||||
pub rows_with_nonzero_child_count: usize,
|
||||
pub rows_with_first_name_tag_after_prelude: usize,
|
||||
pub rows_with_first_name_tag_at_offset_3: usize,
|
||||
#[serde(default)]
|
||||
pub unique_child_count_values: Vec<u16>,
|
||||
#[serde(default)]
|
||||
pub unique_first_name_tag_relative_offsets: Vec<usize>,
|
||||
#[serde(default)]
|
||||
pub dominant_child_count: Option<u16>,
|
||||
pub dominant_child_count_count: usize,
|
||||
#[serde(default)]
|
||||
pub dominant_saved_primary_child_byte: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub dominant_saved_primary_child_byte_hex: Option<String>,
|
||||
pub dominant_saved_primary_child_byte_count: usize,
|
||||
#[serde(default)]
|
||||
pub dominant_first_name_tag_relative_offset: Option<usize>,
|
||||
pub dominant_first_name_tag_relative_offset_count: usize,
|
||||
#[serde(default)]
|
||||
pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSample>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSample {
|
||||
pub sample_index: usize,
|
||||
pub live_entry_id: u32,
|
||||
pub payload_relative_offset: u32,
|
||||
pub payload_relative_offset_hex: String,
|
||||
pub payload_relative_to_records: usize,
|
||||
pub child_count: u16,
|
||||
pub child_count_hex: String,
|
||||
pub saved_primary_child_byte: u8,
|
||||
pub saved_primary_child_byte_hex: String,
|
||||
pub first_payload_dword_hex: String,
|
||||
#[serde(default)]
|
||||
pub first_name_tag_relative_offset: Option<usize>,
|
||||
#[serde(default)]
|
||||
pub first_primary_name: Option<String>,
|
||||
#[serde(default)]
|
||||
pub first_secondary_name: Option<String>,
|
||||
#[serde(default)]
|
||||
pub first_tertiary_name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SmpSavePlacedStructureDynamicSideBufferAlignmentProbe {
|
||||
pub unique_side_buffer_name_pair_count: usize,
|
||||
|
|
@ -4031,6 +4095,7 @@ fn build_infrastructure_asset_trace_report(
|
|||
"0x004133b0 placed-structure local-runtime refresh outer owner".to_string(),
|
||||
];
|
||||
let known_owner_bridge_fields = vec![
|
||||
"outer stream prelude [u16 child count, optional saved primary-child byte]".to_string(),
|
||||
"[this+0x248] cached primary-child slot".to_string(),
|
||||
"[this+0x206/+0x20a/+0x20e] route-entry resolver fields".to_string(),
|
||||
"[this+0x1e2/+0x1e6/+0x1ea] published anchor triplet".to_string(),
|
||||
|
|
@ -4055,7 +4120,7 @@ fn build_infrastructure_asset_trace_report(
|
|||
"0x0048e140 / 0x0048e160 / 0x0048e180 route-entry resolver helpers".to_string(),
|
||||
];
|
||||
let next_owner_questions = vec![
|
||||
"Which exact 0x38a5 rows or compact-prefix regimes feed the child count and optional primary-child ordinal that 0x0048dcf0 restores before the later rebuild loop runs?".to_string(),
|
||||
"How do the observed 0x55f3-to-next-0x55f1 gaps partition between child-local 0x52ebd0 flag bytes and the now-grounded next-record prelude [u16 child count, saved primary-child byte], starting from the first 0x38a6 record head 0x0001/0xff/0x55f1?".to_string(),
|
||||
"Which 0x38a5 embedded name-pair groups survive into the per-child vtable +0x40 payload callbacks dispatched through 0x00455a50?".to_string(),
|
||||
"Is cached primary-child slot [this+0x248] the first owner-visible bridge from the restored child stream into route-entry rebuild?".to_string(),
|
||||
];
|
||||
|
|
@ -4087,6 +4152,28 @@ fn build_infrastructure_asset_trace_report(
|
|||
"atlas already bounds these helpers under the literal Infrastructure owner".to_string(),
|
||||
"the side-buffer corpus is disjoint from the placed-structure triplet corpus, so a separate child/rebuild family is more plausible than a compact alias".to_string(),
|
||||
"direct disassembly now shows 0x00493be0 opening tag family 0x38a5/0x38a6/0x38a7, reading one shared dword into the owner-local 0x90/0x94 lane, iterating each live collection entry, and dispatching every loaded infrastructure record through 0x0048dcf0 before the later follow-on owners run".to_string(),
|
||||
side_buffer
|
||||
.and_then(|probe| probe.first_record_child_count_after_owner_shared)
|
||||
.map(|child_count| {
|
||||
format!(
|
||||
"grounded q.gms bytes now also show the first 0x38a6 record starting immediately after that shared dword with child_count={}, saved_primary_child_byte={}, and first 0x55f1 at offset +0x{:x}",
|
||||
child_count,
|
||||
side_buffer
|
||||
.and_then(|probe| {
|
||||
probe.first_record_saved_primary_child_byte_after_owner_shared_hex
|
||||
.as_deref()
|
||||
})
|
||||
.unwrap_or("0x00"),
|
||||
side_buffer
|
||||
.and_then(|probe| {
|
||||
probe.first_record_first_name_tag_relative_offset_after_owner_shared
|
||||
})
|
||||
.unwrap_or_default()
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
"no grounded first-record prelude summary was available after the shared 0x38a6 owner dword".to_string()
|
||||
}),
|
||||
"direct disassembly now shows 0x00518140 resolving a non-direct live entry through the tombstone bitset and then returning the first dword of a 12-byte row from [collection+0x3c] for the 0x38a5 path".to_string(),
|
||||
"direct disassembly now also shows 0x005181f0/0x00518260 treating the same 12-byte rows as a live-entry directory: dword +0 is the payload pointer, dword +4 is previous live id, and dword +8 is next live id, with collection head/tail caches alongside them".to_string(),
|
||||
"direct disassembly now also shows 0x00493be0 iterating live-entry ordinals through 0x00518380(ordinal, 0), converting each ordinal to a live id, then resolving that live id through 0x00518140 before handing the resulting payload pointer to 0x0048dcf0".to_string(),
|
||||
|
|
@ -4161,6 +4248,26 @@ fn build_infrastructure_asset_trace_report(
|
|||
.unwrap_or_default()
|
||||
),
|
||||
"direct disassembly now also shows 0x530720 publishing the first fixed-triplet lane into [this+0x1e2/+0x1e6/+0x1ea], while 0x52e8b0 publishes the second fixed-triplet lane into [this+0x4b/+0x4f/+0x53] and sets bit 0x02".to_string(),
|
||||
"direct disassembly now also shows the outer owner at 0x0048dcf0 reading one u16 child count through 0x531150 into the stream prelude, zeroing [this+0x08], and conditionally reading one saved primary-child byte before the per-child callback loop runs".to_string(),
|
||||
side_buffer
|
||||
.and_then(|probe| probe.live_entry_prelude_summary.as_ref())
|
||||
.map(|summary| {
|
||||
format!(
|
||||
"the widened save-side probe now also decodes {} live-entry payload starts inside the records span; dominant child count={} x{}, dominant saved primary-child byte={} x{}, and {} payloads reach the first 0x55f1 child callback at offset +0x3",
|
||||
summary.rows_with_payload_pointer_inside_records_span,
|
||||
summary.dominant_child_count.unwrap_or_default(),
|
||||
summary.dominant_child_count_count,
|
||||
summary
|
||||
.dominant_saved_primary_child_byte_hex
|
||||
.as_deref()
|
||||
.unwrap_or("0x00"),
|
||||
summary.dominant_saved_primary_child_byte_count,
|
||||
summary.rows_with_first_name_tag_at_offset_3
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
"no live-entry payload-start summary was available for the outer prelude".to_string()
|
||||
}),
|
||||
"local .rdata at 0x005cfd00 now also proves the infrastructure child table uses the shared tagged callback strip directly: slot +0x40 = 0x455fc0, slot +0x48 = 0x455870, and slot +0x4c = 0x455930".to_string(),
|
||||
"direct disassembly now shows 0x0048a1e0 cloning the first child triplet bands through 0x52e880/0x52e720, destroying the prior child, seeding a new literal Infrastructure child through 0x455b70 with payload seed 0x5c87a8, attaching through 0x5395d0 or 0x53a5d0, and republishing the two bands through 0x52e8b0/0x530720".to_string(),
|
||||
"direct disassembly now also shows the outer owner at 0x0048dcf0 reading a child count plus optional primary-child ordinal from the tagged stream through 0x531150, zeroing [this+0x08], dispatching each fresh child through 0x455a50 -> vtable slot +0x40, culling ordinals above 5, and restoring cached primary-child slot [this+0x248] from the saved ordinal".to_string(),
|
||||
|
|
@ -4168,7 +4275,7 @@ fn build_infrastructure_asset_trace_report(
|
|||
],
|
||||
blockers: vec![
|
||||
"how the payload streams reached through 0x00518380 -> 0x00518140 align with the embedded 0x55f1 name-pair groups and compact-prefix regimes surfaced by the save-side probe".to_string(),
|
||||
"which outer-stream tagged values, outside the now-spoken-for fixed 0x55f2 triplets and short trailing flag bytes, correspond to the child count and optional primary-child ordinal consumed by 0x0048dcf0".to_string(),
|
||||
"how the observed 0x55f3-to-next-0x55f1 gaps partition between the two 0x52ebd0 flag bytes and the next-record prelude now that the first 0x38a6 record head is grounded as child_count=1, saved_primary_child_byte=0xff, first 0x55f1 at +0x3".to_string(),
|
||||
"which restored child fields or grouped rows retain the 0x38a5 embedded name-pair semantics before route/local-runtime follow-ons take over".to_string(),
|
||||
],
|
||||
},
|
||||
|
|
@ -12120,6 +12227,13 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe(
|
|||
continue;
|
||||
};
|
||||
let owner_shared_dword_relative_offset = 0usize;
|
||||
let first_record_child_count_after_owner_shared = read_u16_at(records_payload, 4);
|
||||
let first_record_saved_primary_child_byte_after_owner_shared =
|
||||
read_u8_at(records_payload, 6);
|
||||
let first_record_first_name_tag_relative_offset_after_owner_shared = (3usize..=16usize)
|
||||
.find(|offset| {
|
||||
read_u16_at(records_payload, 4 + *offset) == Some(SAVE_REGION_RECORD_NAME_TAG)
|
||||
});
|
||||
let prefix_leading_dword = owner_shared_dword;
|
||||
let Some(prefix_trailing_word) = read_u16_at(prefix_payload, 4) else {
|
||||
continue;
|
||||
|
|
@ -12716,6 +12830,190 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe(
|
|||
.collect(),
|
||||
},
|
||||
);
|
||||
let bitset_len = ((usize::try_from(summary.live_id_bound).ok()?).saturating_add(8)) / 8;
|
||||
let live_entry_prelude_summary = payload
|
||||
.get(
|
||||
INDEXED_COLLECTION_SERIALIZED_HEADER_LEN
|
||||
..INDEXED_COLLECTION_SERIALIZED_HEADER_LEN + bitset_len,
|
||||
)
|
||||
.and_then(|bitset| {
|
||||
let live_entry_ids =
|
||||
decode_live_entry_ids_from_tombstone_bitset(bitset, summary.live_id_bound)?;
|
||||
if live_entry_ids.len() != usize::try_from(summary.live_record_count).ok()? {
|
||||
return None;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
struct LiveEntryPreludeRow {
|
||||
live_entry_id: u32,
|
||||
payload_relative_offset: usize,
|
||||
child_count: u16,
|
||||
saved_primary_child_byte: u8,
|
||||
first_payload_dword: u32,
|
||||
first_name_tag_relative_offset: Option<usize>,
|
||||
first_primary_name: Option<String>,
|
||||
first_secondary_name: Option<String>,
|
||||
first_tertiary_name: Option<String>,
|
||||
}
|
||||
let mut rows = Vec::new();
|
||||
let mut cursor = 0usize;
|
||||
for live_entry_id in live_entry_ids.iter().copied() {
|
||||
let payload_len = usize::from(read_u16_at(records_payload, cursor)?);
|
||||
let payload_relative_offset = cursor.checked_add(2)?;
|
||||
let payload_end = payload_relative_offset.checked_add(payload_len)?;
|
||||
let payload_bytes =
|
||||
records_payload.get(payload_relative_offset..payload_end)?;
|
||||
let child_count = read_u16_at(payload_bytes, 0)?;
|
||||
let saved_primary_child_byte = read_u8_at(payload_bytes, 2)?;
|
||||
let first_payload_dword = read_u32_at(payload_bytes, 0)?;
|
||||
let first_name_tag_relative_offset = (0usize..=16usize).find(|offset| {
|
||||
read_u16_at(payload_bytes, *offset) == Some(SAVE_REGION_RECORD_NAME_TAG)
|
||||
});
|
||||
let (first_primary_name, first_secondary_name, first_tertiary_name) =
|
||||
first_name_tag_relative_offset
|
||||
.and_then(|relative_offset| {
|
||||
let name_payload =
|
||||
payload_bytes.get(relative_offset.checked_add(4)?..)?;
|
||||
parse_save_len_prefixed_ascii_name_triplet(name_payload)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
rows.push(LiveEntryPreludeRow {
|
||||
live_entry_id,
|
||||
payload_relative_offset,
|
||||
child_count,
|
||||
saved_primary_child_byte,
|
||||
first_payload_dword,
|
||||
first_name_tag_relative_offset,
|
||||
first_primary_name: (!first_primary_name.is_empty())
|
||||
.then_some(first_primary_name),
|
||||
first_secondary_name: (!first_secondary_name.is_empty())
|
||||
.then_some(first_secondary_name),
|
||||
first_tertiary_name,
|
||||
});
|
||||
cursor = payload_end;
|
||||
}
|
||||
let payload_relative_offset_monotonic = rows.windows(2).all(|window| {
|
||||
window[0].payload_relative_offset < window[1].payload_relative_offset
|
||||
});
|
||||
let mut child_count_counts = BTreeMap::<u16, usize>::new();
|
||||
let mut saved_primary_child_byte_counts = BTreeMap::<u8, usize>::new();
|
||||
let mut first_name_tag_relative_offset_counts = BTreeMap::<usize, usize>::new();
|
||||
for row in &rows {
|
||||
*child_count_counts.entry(row.child_count).or_default() += 1;
|
||||
*saved_primary_child_byte_counts
|
||||
.entry(row.saved_primary_child_byte)
|
||||
.or_default() += 1;
|
||||
if let Some(first_name_tag_relative_offset) = row.first_name_tag_relative_offset
|
||||
{
|
||||
*first_name_tag_relative_offset_counts
|
||||
.entry(first_name_tag_relative_offset)
|
||||
.or_default() += 1;
|
||||
}
|
||||
}
|
||||
let dominant_child_count = child_count_counts
|
||||
.iter()
|
||||
.max_by(|(left_key, left_count), (right_key, right_count)| {
|
||||
left_count
|
||||
.cmp(right_count)
|
||||
.then_with(|| right_key.cmp(left_key))
|
||||
})
|
||||
.map(|(value, count)| (*value, *count));
|
||||
let dominant_saved_primary_child_byte = saved_primary_child_byte_counts
|
||||
.iter()
|
||||
.max_by(|(left_key, left_count), (right_key, right_count)| {
|
||||
left_count
|
||||
.cmp(right_count)
|
||||
.then_with(|| right_key.cmp(left_key))
|
||||
})
|
||||
.map(|(value, count)| (*value, *count));
|
||||
let dominant_first_name_tag_relative_offset = first_name_tag_relative_offset_counts
|
||||
.iter()
|
||||
.max_by(|(left_key, left_count), (right_key, right_count)| {
|
||||
left_count
|
||||
.cmp(right_count)
|
||||
.then_with(|| right_key.cmp(left_key))
|
||||
})
|
||||
.map(|(value, count)| (*value, *count));
|
||||
Some(
|
||||
SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSummary {
|
||||
live_entry_directory_row_count: rows.len(),
|
||||
decoded_live_entry_id_count: live_entry_ids.len(),
|
||||
payload_relative_offset_monotonic,
|
||||
rows_with_payload_pointer_inside_records_span: rows.len(),
|
||||
rows_with_zero_child_count: rows
|
||||
.iter()
|
||||
.filter(|row| row.child_count == 0)
|
||||
.count(),
|
||||
rows_with_nonzero_child_count: rows
|
||||
.iter()
|
||||
.filter(|row| row.child_count != 0)
|
||||
.count(),
|
||||
rows_with_first_name_tag_after_prelude: rows
|
||||
.iter()
|
||||
.filter(|row| row.first_name_tag_relative_offset.is_some())
|
||||
.count(),
|
||||
rows_with_first_name_tag_at_offset_3: rows
|
||||
.iter()
|
||||
.filter(|row| row.first_name_tag_relative_offset == Some(3))
|
||||
.count(),
|
||||
unique_child_count_values: child_count_counts.keys().copied().collect(),
|
||||
unique_first_name_tag_relative_offsets:
|
||||
first_name_tag_relative_offset_counts
|
||||
.keys()
|
||||
.copied()
|
||||
.collect(),
|
||||
dominant_child_count: dominant_child_count.map(|(value, _)| value),
|
||||
dominant_child_count_count: dominant_child_count
|
||||
.map(|(_, count)| count)
|
||||
.unwrap_or_default(),
|
||||
dominant_saved_primary_child_byte: dominant_saved_primary_child_byte
|
||||
.map(|(value, _)| value),
|
||||
dominant_saved_primary_child_byte_hex: dominant_saved_primary_child_byte
|
||||
.map(|(value, _)| format!("0x{value:02x}")),
|
||||
dominant_saved_primary_child_byte_count: dominant_saved_primary_child_byte
|
||||
.map(|(_, count)| count)
|
||||
.unwrap_or_default(),
|
||||
dominant_first_name_tag_relative_offset:
|
||||
dominant_first_name_tag_relative_offset.map(|(value, _)| value),
|
||||
dominant_first_name_tag_relative_offset_count:
|
||||
dominant_first_name_tag_relative_offset
|
||||
.map(|(_, count)| count)
|
||||
.unwrap_or_default(),
|
||||
sample_rows: rows
|
||||
.iter()
|
||||
.take(8)
|
||||
.enumerate()
|
||||
.map(|(sample_index, row)| {
|
||||
SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSample {
|
||||
sample_index,
|
||||
live_entry_id: row.live_entry_id,
|
||||
payload_relative_offset: row.payload_relative_offset as u32,
|
||||
payload_relative_offset_hex: format!(
|
||||
"0x{:08x}",
|
||||
row.payload_relative_offset
|
||||
),
|
||||
payload_relative_to_records: row.payload_relative_offset,
|
||||
child_count: row.child_count,
|
||||
child_count_hex: format!("0x{:04x}", row.child_count),
|
||||
saved_primary_child_byte: row.saved_primary_child_byte,
|
||||
saved_primary_child_byte_hex: format!(
|
||||
"0x{:02x}",
|
||||
row.saved_primary_child_byte
|
||||
),
|
||||
first_payload_dword_hex: format!(
|
||||
"0x{:08x}",
|
||||
row.first_payload_dword
|
||||
),
|
||||
first_name_tag_relative_offset: row
|
||||
.first_name_tag_relative_offset,
|
||||
first_primary_name: row.first_primary_name.clone(),
|
||||
first_secondary_name: row.first_secondary_name.clone(),
|
||||
first_tertiary_name: row.first_tertiary_name.clone(),
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
},
|
||||
)
|
||||
});
|
||||
let unique_embedded_name_pair_count = name_pair_summaries.len();
|
||||
let dominant_compact_prefix_pattern = compact_prefix_pattern_summaries.first().cloned();
|
||||
let decoded_embedded_name_row_count = embedded_name_rows
|
||||
|
|
@ -12749,6 +13047,14 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe(
|
|||
owner_shared_dword_relative_offset,
|
||||
owner_shared_dword_matches_first_compact_prefix_leading_dword:
|
||||
owner_shared_dword == prefix_leading_dword,
|
||||
first_record_child_count_after_owner_shared,
|
||||
first_record_child_count_after_owner_shared_hex: first_record_child_count_after_owner_shared
|
||||
.map(|value| format!("0x{value:04x}")),
|
||||
first_record_saved_primary_child_byte_after_owner_shared,
|
||||
first_record_saved_primary_child_byte_after_owner_shared_hex:
|
||||
first_record_saved_primary_child_byte_after_owner_shared
|
||||
.map(|value| format!("0x{value:02x}")),
|
||||
first_record_first_name_tag_relative_offset_after_owner_shared,
|
||||
prefix_leading_dword,
|
||||
prefix_leading_dword_hex: format!("0x{prefix_leading_dword:08x}"),
|
||||
prefix_trailing_word,
|
||||
|
|
@ -12769,11 +13075,21 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe(
|
|||
compact_prefix_pattern_summaries,
|
||||
name_pair_summaries,
|
||||
payload_envelope_summary,
|
||||
live_entry_prelude_summary: live_entry_prelude_summary.clone(),
|
||||
evidence: vec![
|
||||
"exact little-endian u32 tag family 0x38a5/0x38a6/0x38a7 appears as a separate save-side tagged collection on grounded saves".to_string(),
|
||||
format!(
|
||||
"direct disassembly now shows 0x00493be0 consuming shared owner-local dword 0x{owner_shared_dword:08x} from the 0x38a6 stream before iterating live infrastructure records"
|
||||
),
|
||||
format!(
|
||||
"grounded 0x38a6 record stream then starts the first infrastructure payload with child_count={}, saved_primary_child_byte={}, and first 0x55f1 at relative offset {:?} after that shared dword",
|
||||
first_record_child_count_after_owner_shared.unwrap_or_default(),
|
||||
first_record_saved_primary_child_byte_after_owner_shared
|
||||
.map(|value| format!("0x{value:02x}"))
|
||||
.as_deref()
|
||||
.unwrap_or("0x00"),
|
||||
first_record_first_name_tag_relative_offset_after_owner_shared
|
||||
),
|
||||
"records payload begins with a compact 6-byte prefix plus one separator byte before the first embedded 0x55f1 name row".to_string(),
|
||||
"first embedded 0x55f1 row decodes with placed-structure-style dual names, which makes this the strongest current candidate for the separate placed-structure dynamic side-buffer owner seam".to_string(),
|
||||
format!(
|
||||
|
|
@ -12856,6 +13172,29 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe(
|
|||
.unwrap_or_else(|| {
|
||||
"no fixed 0x55f2 policy summary was available".to_string()
|
||||
}),
|
||||
live_entry_prelude_summary
|
||||
.as_ref()
|
||||
.map(|summary| {
|
||||
format!(
|
||||
"decoded {} live-entry directory rows with payload pointers inside the records span; dominant child count={} x{}, dominant saved primary-child byte={} x{}, dominant first 0x55f1 offset={} x{}, and {} rows start the first child callback immediately at payload +0x3",
|
||||
summary.rows_with_payload_pointer_inside_records_span,
|
||||
summary.dominant_child_count.unwrap_or_default(),
|
||||
summary.dominant_child_count_count,
|
||||
summary
|
||||
.dominant_saved_primary_child_byte_hex
|
||||
.as_deref()
|
||||
.unwrap_or("0x00"),
|
||||
summary.dominant_saved_primary_child_byte_count,
|
||||
summary
|
||||
.dominant_first_name_tag_relative_offset
|
||||
.unwrap_or_default(),
|
||||
summary.dominant_first_name_tag_relative_offset_count,
|
||||
summary.rows_with_first_name_tag_at_offset_3
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
"no live-entry prelude summary was available".to_string()
|
||||
}),
|
||||
dominant_compact_prefix_pattern
|
||||
.map(|pattern| {
|
||||
format!(
|
||||
|
|
@ -20970,6 +21309,17 @@ mod tests {
|
|||
assert_eq!(probe.owner_shared_dword_hex, "0x0005d368");
|
||||
assert_eq!(probe.owner_shared_dword_relative_offset, 0);
|
||||
assert!(probe.owner_shared_dword_matches_first_compact_prefix_leading_dword);
|
||||
assert_eq!(probe.first_record_child_count_after_owner_shared, Some(1));
|
||||
assert_eq!(
|
||||
probe
|
||||
.first_record_saved_primary_child_byte_after_owner_shared_hex
|
||||
.as_deref(),
|
||||
Some("0xff")
|
||||
);
|
||||
assert_eq!(
|
||||
probe.first_record_first_name_tag_relative_offset_after_owner_shared,
|
||||
Some(3)
|
||||
);
|
||||
assert_eq!(probe.prefix_leading_dword_hex, "0x0005d368");
|
||||
assert_eq!(probe.prefix_trailing_word_hex, "0x0001");
|
||||
assert_eq!(probe.prefix_separator_byte_hex, "0xff");
|
||||
|
|
@ -21196,6 +21546,11 @@ mod tests {
|
|||
owner_shared_dword_hex: "0x00000000".to_string(),
|
||||
owner_shared_dword_relative_offset: 0,
|
||||
owner_shared_dword_matches_first_compact_prefix_leading_dword: true,
|
||||
first_record_child_count_after_owner_shared: None,
|
||||
first_record_child_count_after_owner_shared_hex: None,
|
||||
first_record_saved_primary_child_byte_after_owner_shared: None,
|
||||
first_record_saved_primary_child_byte_after_owner_shared_hex: None,
|
||||
first_record_first_name_tag_relative_offset_after_owner_shared: None,
|
||||
prefix_leading_dword: 0,
|
||||
prefix_leading_dword_hex: "0x00000000".to_string(),
|
||||
prefix_trailing_word: 1,
|
||||
|
|
@ -21245,6 +21600,7 @@ mod tests {
|
|||
},
|
||||
],
|
||||
payload_envelope_summary: None,
|
||||
live_entry_prelude_summary: None,
|
||||
evidence: vec![],
|
||||
};
|
||||
let triplets = SmpSavePlacedStructureRecordTripletProbe {
|
||||
|
|
@ -22851,6 +23207,13 @@ mod tests {
|
|||
owner_shared_dword_hex: "0xff000000".to_string(),
|
||||
owner_shared_dword_relative_offset: 0,
|
||||
owner_shared_dword_matches_first_compact_prefix_leading_dword: true,
|
||||
first_record_child_count_after_owner_shared: Some(1),
|
||||
first_record_child_count_after_owner_shared_hex: Some("0x0001".to_string()),
|
||||
first_record_saved_primary_child_byte_after_owner_shared: Some(0xff),
|
||||
first_record_saved_primary_child_byte_after_owner_shared_hex: Some(
|
||||
"0xff".to_string(),
|
||||
),
|
||||
first_record_first_name_tag_relative_offset_after_owner_shared: Some(3),
|
||||
prefix_leading_dword: 0xff000000,
|
||||
prefix_leading_dword_hex: "0xff000000".to_string(),
|
||||
prefix_trailing_word: 1,
|
||||
|
|
@ -22930,6 +23293,28 @@ mod tests {
|
|||
sample_rows: Vec::new(),
|
||||
},
|
||||
),
|
||||
live_entry_prelude_summary: Some(
|
||||
SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSummary {
|
||||
live_entry_directory_row_count: 3865,
|
||||
decoded_live_entry_id_count: 3865,
|
||||
payload_relative_offset_monotonic: true,
|
||||
rows_with_payload_pointer_inside_records_span: 138,
|
||||
rows_with_zero_child_count: 0,
|
||||
rows_with_nonzero_child_count: 138,
|
||||
rows_with_first_name_tag_after_prelude: 138,
|
||||
rows_with_first_name_tag_at_offset_3: 138,
|
||||
unique_child_count_values: vec![1],
|
||||
unique_first_name_tag_relative_offsets: vec![3],
|
||||
dominant_child_count: Some(1),
|
||||
dominant_child_count_count: 138,
|
||||
dominant_saved_primary_child_byte: Some(0),
|
||||
dominant_saved_primary_child_byte_hex: Some("0x00".to_string()),
|
||||
dominant_saved_primary_child_byte_count: 138,
|
||||
dominant_first_name_tag_relative_offset: Some(3),
|
||||
dominant_first_name_tag_relative_offset_count: 138,
|
||||
sample_rows: Vec::new(),
|
||||
},
|
||||
),
|
||||
evidence: Vec::new(),
|
||||
});
|
||||
analysis.placed_structure_dynamic_side_buffer_alignment =
|
||||
|
|
@ -22949,7 +23334,7 @@ mod tests {
|
|||
let trace = build_infrastructure_asset_trace_report(&analysis);
|
||||
assert!(trace.side_buffer_present);
|
||||
assert_eq!(trace.triplet_alignment_overlap_count, 0);
|
||||
assert_eq!(trace.known_owner_bridge_fields.len(), 6);
|
||||
assert_eq!(trace.known_owner_bridge_fields.len(), 7);
|
||||
assert_eq!(trace.known_bridge_helpers.len(), 13);
|
||||
assert_eq!(trace.next_owner_questions.len(), 3);
|
||||
assert_eq!(trace.candidate_consumer_hypotheses.len(), 3);
|
||||
|
|
@ -23009,6 +23394,13 @@ mod tests {
|
|||
&& line.contains("[this+0x4b/+0x4f/+0x53]")
|
||||
})
|
||||
);
|
||||
assert!(
|
||||
trace.candidate_consumer_hypotheses[0]
|
||||
.evidence
|
||||
.iter()
|
||||
.any(|line| line.contains("u16 child count")
|
||||
&& line.contains("saved primary-child byte"))
|
||||
);
|
||||
assert_eq!(trace.branches[0].status, "grounded_separate_owner_seam");
|
||||
assert_eq!(trace.branches[1].status, "disproved_by_grounded_probe");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2966,6 +2966,15 @@ The low helper strip beneath that shared family is tighter now too: `0x0052ecd0`
|
|||
infrastructure question is no longer whether the fixed `0x55f2` row hides the child count or
|
||||
saved primary-child ordinal at all. Those values now have to live outside the fixed row, most
|
||||
likely in the surrounding payload-stream header or compact-prefix regime above `0x0048dcf0`.
|
||||
The outer prelude is explicit now too: direct disassembly of `0x0048dcf0` shows it reading one
|
||||
`u16` child count through `0x00531150`, zeroing `[this+0x08]`, and conditionally reading one
|
||||
saved primary-child byte before the per-child callback loop begins. Grounded `q.gms` bytes now
|
||||
also show the first `0x38a6` record starting immediately after the shared owner-local dword with
|
||||
`child_count = 1`, `saved_primary_child_byte = 0xff`, and the first child `0x55f1` opening at
|
||||
offset `+0x3`. So the remaining infrastructure question is no longer “what kind of value should
|
||||
the save-side probe be looking for above the fixed rows?”; it is the narrower partitioning
|
||||
problem of how the observed `0x55f3`-to-next-`0x55f1` gaps divide between the two `0x52ebd0`
|
||||
flag bytes and the next record’s `u16 + byte` prelude.
|
||||
The child loader family is explicit now too: local `.rdata` at `0x005cfd00` proves the
|
||||
`Infrastructure` child vtable uses the shared tagged callback strip directly, with
|
||||
`+0x40 = 0x00455fc0`, `+0x48 = 0x00455870`, and `+0x4c = 0x00455930`. So the remaining
|
||||
|
|
|
|||
|
|
@ -116,6 +116,15 @@ Working rule:
|
|||
primary-child ordinal at all; those outer-header values now have to live outside the fixed row,
|
||||
most likely in the surrounding payload-stream header or compact-prefix regime above
|
||||
`0x0048dcf0`.
|
||||
- The outer prelude itself is tighter now too: direct disassembly of `0x0048dcf0` shows it reading
|
||||
one `u16` child count through `0x00531150`, zeroing `[this+0x08]`, and conditionally reading one
|
||||
saved primary-child byte before the per-child callback loop runs. Grounded `q.gms` bytes now also
|
||||
show the first `0x38a6` record starting immediately after the shared owner-local dword with
|
||||
`child_count = 1`, `saved_primary_child_byte = 0xff`, and the first child `0x55f1` opening at
|
||||
offset `+0x3`. So the next infrastructure question is no longer “what kind of values are we
|
||||
looking for above the fixed rows?”; it is the narrower partitioning problem of how the observed
|
||||
`0x55f3`-to-next-`0x55f1` gaps divide between the two `0x52ebd0` flag bytes and the next
|
||||
record’s `u16 + byte` prelude.
|
||||
- Reconstruct the save-side region record body on top of the newly corrected non-direct tagged
|
||||
region seam (`0x5209/0x520a/0x520b`, stride hint `0x06`, `Marker09` record stems) now that the
|
||||
`0x55f3` payload is known to be fully consumed by the embedded profile collection on grounded
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue