Decode infrastructure fixed policy lanes
This commit is contained in:
parent
9f43a27e07
commit
3c09482b71
3 changed files with 193 additions and 0 deletions
|
|
@ -1935,9 +1935,40 @@ pub struct SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSummary {
|
||||||
pub short_profile_flag_pair_summary:
|
pub short_profile_flag_pair_summary:
|
||||||
Option<SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSummary>,
|
Option<SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSummary>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
pub fixed_policy_summary: Option<SmpSavePlacedStructureDynamicSideBufferFixedPolicySummary>,
|
||||||
|
#[serde(default)]
|
||||||
pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSample>,
|
pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSample>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SmpSavePlacedStructureDynamicSideBufferFixedPolicySummary {
|
||||||
|
pub row_count_with_0x1a_policy_chunk: usize,
|
||||||
|
pub unique_trailing_word_count: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub dominant_trailing_word: Option<u16>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub dominant_trailing_word_hex: Option<String>,
|
||||||
|
pub dominant_trailing_word_count: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferFixedPolicySample>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SmpSavePlacedStructureDynamicSideBufferFixedPolicySample {
|
||||||
|
pub sample_index: usize,
|
||||||
|
pub name_tag_relative_offset: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub primary_name: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub secondary_name: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub first_triplet_dwords_hex: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub second_triplet_dwords_hex: Vec<String>,
|
||||||
|
pub trailing_word: u16,
|
||||||
|
pub trailing_word_hex: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSummary {
|
pub struct SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSummary {
|
||||||
pub row_count_with_0x06_profile_span: usize,
|
pub row_count_with_0x06_profile_span: usize,
|
||||||
|
|
@ -4108,6 +4139,25 @@ fn build_infrastructure_asset_trace_report(
|
||||||
.map(|pair| pair.count)
|
.map(|pair| pair.count)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
),
|
),
|
||||||
|
"direct disassembly now also shows 0x455870 consuming six 4-byte lanes from the fixed 0x55f2 chunk and forwarding them into 0x530720 then 0x52e8b0, while 0x455930 serializes the same six dword lanes back through 0x531030".to_string(),
|
||||||
|
format!(
|
||||||
|
"current save-side probe reports {} fixed 0x1a policy rows; dominant trailing word is {} x{}",
|
||||||
|
side_buffer
|
||||||
|
.and_then(|probe| probe.payload_envelope_summary.as_ref())
|
||||||
|
.and_then(|summary| summary.fixed_policy_summary.as_ref())
|
||||||
|
.map(|summary| summary.row_count_with_0x1a_policy_chunk)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
side_buffer
|
||||||
|
.and_then(|probe| probe.payload_envelope_summary.as_ref())
|
||||||
|
.and_then(|summary| summary.fixed_policy_summary.as_ref())
|
||||||
|
.and_then(|summary| summary.dominant_trailing_word_hex.as_deref())
|
||||||
|
.unwrap_or("0x0000"),
|
||||||
|
side_buffer
|
||||||
|
.and_then(|probe| probe.payload_envelope_summary.as_ref())
|
||||||
|
.and_then(|summary| summary.fixed_policy_summary.as_ref())
|
||||||
|
.map(|summary| summary.dominant_trailing_word_count)
|
||||||
|
.unwrap_or_default()
|
||||||
|
),
|
||||||
"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(),
|
"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 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(),
|
"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(),
|
||||||
|
|
@ -12536,6 +12586,92 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe(
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
let fixed_policy_rows = payload_envelope_rows
|
||||||
|
.iter()
|
||||||
|
.filter(|row| row.policy_chunk_len == Some(0x1a))
|
||||||
|
.filter_map(|row| {
|
||||||
|
let policy_tag_relative_offset = row.policy_tag_relative_offset?;
|
||||||
|
let policy_payload = records_payload
|
||||||
|
.get(policy_tag_relative_offset + 4..policy_tag_relative_offset + 4 + 0x1a)?;
|
||||||
|
let first_triplet_dwords = [0usize, 4, 8]
|
||||||
|
.into_iter()
|
||||||
|
.map(|offset| read_u32_at(policy_payload, offset))
|
||||||
|
.collect::<Option<Vec<_>>>()?;
|
||||||
|
let second_triplet_dwords = [12usize, 16, 20]
|
||||||
|
.into_iter()
|
||||||
|
.map(|offset| read_u32_at(policy_payload, offset))
|
||||||
|
.collect::<Option<Vec<_>>>()?;
|
||||||
|
let trailing_word = read_u16_at(policy_payload, 24)?;
|
||||||
|
Some((
|
||||||
|
row.name_tag_relative_offset,
|
||||||
|
row.primary_name.clone(),
|
||||||
|
row.secondary_name.clone(),
|
||||||
|
first_triplet_dwords,
|
||||||
|
second_triplet_dwords,
|
||||||
|
trailing_word,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let mut fixed_policy_trailing_word_counts = BTreeMap::<u16, usize>::new();
|
||||||
|
for (_, _, _, _, _, trailing_word) in &fixed_policy_rows {
|
||||||
|
*fixed_policy_trailing_word_counts
|
||||||
|
.entry(*trailing_word)
|
||||||
|
.or_default() += 1;
|
||||||
|
}
|
||||||
|
let dominant_fixed_policy_trailing_word = fixed_policy_trailing_word_counts
|
||||||
|
.iter()
|
||||||
|
.max_by(|(left_word, left_count), (right_word, right_count)| {
|
||||||
|
left_count
|
||||||
|
.cmp(right_count)
|
||||||
|
.then_with(|| right_word.cmp(left_word))
|
||||||
|
})
|
||||||
|
.map(|(word, count)| (*word, *count));
|
||||||
|
let fixed_policy_summary =
|
||||||
|
Some(SmpSavePlacedStructureDynamicSideBufferFixedPolicySummary {
|
||||||
|
row_count_with_0x1a_policy_chunk: fixed_policy_rows.len(),
|
||||||
|
unique_trailing_word_count: fixed_policy_trailing_word_counts.len(),
|
||||||
|
dominant_trailing_word: dominant_fixed_policy_trailing_word.map(|(word, _)| word),
|
||||||
|
dominant_trailing_word_hex: dominant_fixed_policy_trailing_word
|
||||||
|
.map(|(word, _)| format!("0x{word:04x}")),
|
||||||
|
dominant_trailing_word_count: dominant_fixed_policy_trailing_word
|
||||||
|
.map(|(_, count)| count)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
sample_rows: fixed_policy_rows
|
||||||
|
.iter()
|
||||||
|
.take(8)
|
||||||
|
.enumerate()
|
||||||
|
.map(
|
||||||
|
|(
|
||||||
|
sample_index,
|
||||||
|
(
|
||||||
|
name_tag_relative_offset,
|
||||||
|
primary_name,
|
||||||
|
secondary_name,
|
||||||
|
first_triplet_dwords,
|
||||||
|
second_triplet_dwords,
|
||||||
|
trailing_word,
|
||||||
|
),
|
||||||
|
)| {
|
||||||
|
SmpSavePlacedStructureDynamicSideBufferFixedPolicySample {
|
||||||
|
sample_index,
|
||||||
|
name_tag_relative_offset: *name_tag_relative_offset,
|
||||||
|
primary_name: primary_name.clone(),
|
||||||
|
secondary_name: secondary_name.clone(),
|
||||||
|
first_triplet_dwords_hex: first_triplet_dwords
|
||||||
|
.iter()
|
||||||
|
.map(|value| format!("0x{value:08x}"))
|
||||||
|
.collect(),
|
||||||
|
second_triplet_dwords_hex: second_triplet_dwords
|
||||||
|
.iter()
|
||||||
|
.map(|value| format!("0x{value:08x}"))
|
||||||
|
.collect(),
|
||||||
|
trailing_word: *trailing_word,
|
||||||
|
trailing_word_hex: format!("0x{trailing_word:04x}"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.collect(),
|
||||||
|
});
|
||||||
let payload_envelope_summary = Some(
|
let payload_envelope_summary = Some(
|
||||||
SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSummary {
|
SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSummary {
|
||||||
row_count_with_policy_tag_before_next_name,
|
row_count_with_policy_tag_before_next_name,
|
||||||
|
|
@ -12553,6 +12689,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe(
|
||||||
.map(|(_, count)| count)
|
.map(|(_, count)| count)
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
short_profile_flag_pair_summary: short_profile_flag_pair_summary.clone(),
|
short_profile_flag_pair_summary: short_profile_flag_pair_summary.clone(),
|
||||||
|
fixed_policy_summary: fixed_policy_summary.clone(),
|
||||||
sample_rows: payload_envelope_rows
|
sample_rows: payload_envelope_rows
|
||||||
.iter()
|
.iter()
|
||||||
.take(8)
|
.take(8)
|
||||||
|
|
@ -12700,6 +12837,22 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe(
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
"no dominant short trailing flag-byte pair was available".to_string()
|
"no dominant short trailing flag-byte pair was available".to_string()
|
||||||
}),
|
}),
|
||||||
|
fixed_policy_summary
|
||||||
|
.as_ref()
|
||||||
|
.map(|summary| {
|
||||||
|
format!(
|
||||||
|
"direct disassembly now bounds the fixed 0x55f2 lane through 0x455870/0x455930 as six serialized dwords plus one trailing u16; grounded rows currently keep trailing word {} across {} of {} fixed-policy rows",
|
||||||
|
summary
|
||||||
|
.dominant_trailing_word_hex
|
||||||
|
.as_deref()
|
||||||
|
.unwrap_or("0x0000"),
|
||||||
|
summary.dominant_trailing_word_count,
|
||||||
|
summary.row_count_with_0x1a_policy_chunk
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
"no fixed 0x55f2 policy summary was available".to_string()
|
||||||
|
}),
|
||||||
dominant_compact_prefix_pattern
|
dominant_compact_prefix_pattern
|
||||||
.map(|pattern| {
|
.map(|pattern| {
|
||||||
format!(
|
format!(
|
||||||
|
|
@ -22761,6 +22914,16 @@ mod tests {
|
||||||
sample_rows: Vec::new(),
|
sample_rows: Vec::new(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
fixed_policy_summary: Some(
|
||||||
|
SmpSavePlacedStructureDynamicSideBufferFixedPolicySummary {
|
||||||
|
row_count_with_0x1a_policy_chunk: 118,
|
||||||
|
unique_trailing_word_count: 1,
|
||||||
|
dominant_trailing_word: Some(1),
|
||||||
|
dominant_trailing_word_hex: Some("0x0001".to_string()),
|
||||||
|
dominant_trailing_word_count: 118,
|
||||||
|
sample_rows: Vec::new(),
|
||||||
|
},
|
||||||
|
),
|
||||||
sample_rows: Vec::new(),
|
sample_rows: Vec::new(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -22823,6 +22986,16 @@ mod tests {
|
||||||
&& (line.contains("bits 0x20/0x40") || line.contains("bits 0x20 and 0x40"))
|
&& (line.contains("bits 0x20/0x40") || line.contains("bits 0x20 and 0x40"))
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
assert!(
|
||||||
|
trace.candidate_consumer_hypotheses[0]
|
||||||
|
.evidence
|
||||||
|
.iter()
|
||||||
|
.any(|line| {
|
||||||
|
(line.contains("0x455870/0x455930")
|
||||||
|
|| (line.contains("0x455870") && line.contains("0x455930")))
|
||||||
|
&& (line.contains("six 4-byte lanes") || line.contains("six dword lanes"))
|
||||||
|
})
|
||||||
|
);
|
||||||
assert_eq!(trace.branches[0].status, "grounded_separate_owner_seam");
|
assert_eq!(trace.branches[0].status, "grounded_separate_owner_seam");
|
||||||
assert_eq!(trace.branches[1].status, "disproved_by_grounded_probe");
|
assert_eq!(trace.branches[1].status, "disproved_by_grounded_probe");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2952,6 +2952,14 @@ The low helper strip beneath that shared family is tighter now too: `0x0052ecd0`
|
||||||
infrastructure question is no longer whether a short trailing lane exists; it is how those
|
infrastructure question is no longer whether a short trailing lane exists; it is how those
|
||||||
compact-prefix regimes and short flag-byte pairs feed the child-count / primary-child restore
|
compact-prefix regimes and short flag-byte pairs feed the child-count / primary-child restore
|
||||||
state above `0x0048dcf0`.
|
state above `0x0048dcf0`.
|
||||||
|
The fixed policy lane is tighter now too: direct disassembly of
|
||||||
|
`0x00455870/0x00455930` shows the `+0x48/+0x4c` strip loading and serializing six `u32` lanes
|
||||||
|
from the fixed `0x55f2` chunk, forwarding them through `0x00530720` and `0x0052e8b0`. Grounded
|
||||||
|
`q.gms` save-side probes now show every embedded `0x55f2` row using the same trailing word
|
||||||
|
`0x0101` while the six dword lanes vary by asset row. So the remaining infrastructure question
|
||||||
|
is no longer whether `0x55f2` is a fixed-format child lane; it is which of those two dword
|
||||||
|
triplets correspond to the later child-count / primary-child restore state and which only seed
|
||||||
|
published anchor or position bands.
|
||||||
The child loader family is explicit now too: local `.rdata` at `0x005cfd00` proves the
|
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
|
`Infrastructure` child vtable uses the shared tagged callback strip directly, with
|
||||||
`+0x40 = 0x00455fc0`, `+0x48 = 0x00455870`, and `+0x4c = 0x00455930`. So the remaining
|
`+0x40 = 0x00455fc0`, `+0x48 = 0x00455870`, and `+0x4c = 0x00455930`. So the remaining
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,13 @@ Working rule:
|
||||||
concrete infrastructure question is no longer “is there a short trailing flag lane?”; it is how
|
concrete infrastructure question is no longer “is there a short trailing flag lane?”; it is how
|
||||||
the compact-prefix regimes and those flag-byte pairs feed the child-count / primary-child restore
|
the compact-prefix regimes and those flag-byte pairs feed the child-count / primary-child restore
|
||||||
state above `0x0048dcf0`.
|
state above `0x0048dcf0`.
|
||||||
|
- The fixed `0x55f2` lane is tighter now too: direct disassembly of `0x00455870/0x00455930` shows
|
||||||
|
the `+0x48/+0x4c` strip loading and serializing six `u32` lanes from the fixed `0x1a` chunk,
|
||||||
|
forwarding them through `0x00530720` and `0x0052e8b0`. Grounded `q.gms` probes now show every
|
||||||
|
embedded `0x55f2` row using the same trailing word `0x0101` while those six dword lanes vary by
|
||||||
|
asset row. So the next infrastructure question is no longer whether `0x55f2` is a fixed-format
|
||||||
|
child lane; it is which of those two dword triplets correspond to child-count / primary-child
|
||||||
|
restore state and which only seed published anchor or position bands.
|
||||||
- Reconstruct the save-side region record body on top of the newly corrected non-direct tagged
|
- 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
|
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
|
`0x55f3` payload is known to be fully consumed by the embedded profile collection on grounded
|
||||||
|
|
@ -239,6 +246,11 @@ Working rule:
|
||||||
`0x0052ebd0/0x0052ec50` helper seam. That means the next pass can aim directly at how those
|
`0x0052ebd0/0x0052ec50` helper seam. That means the next pass can aim directly at how those
|
||||||
flags combine with compact-prefix regimes and primary-child restore state instead of treating the
|
flags combine with compact-prefix regimes and primary-child restore state instead of treating the
|
||||||
short lane as anonymous payload.
|
short lane as anonymous payload.
|
||||||
|
- That same probe now also exports the fixed `0x55f2` six-dword policy samples and the grounded
|
||||||
|
shared trailing word `0x0101` for all embedded rows, while the infrastructure trace carries the
|
||||||
|
matching `0x00455870/0x00455930` helper seam. That means the next pass can focus on which of the
|
||||||
|
two restored dword triplets actually bridge into child-count / primary-child state instead of
|
||||||
|
rediscovering the fixed `0x55f2` row shape.
|
||||||
- That same trace now also ranks those consumers into explicit hypotheses, so the next
|
- That same trace now also ranks those consumers into explicit hypotheses, so the next
|
||||||
infrastructure pass should start with the attach/rebuild strip instead of treating all
|
infrastructure pass should start with the attach/rebuild strip instead of treating all
|
||||||
candidate owners as equally likely.
|
candidate owners as equally likely.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue