diff --git a/src/util/dwarf.rs b/src/util/dwarf.rs index acc60c5..5230d77 100644 --- a/src/util/dwarf.rs +++ b/src/util/dwarf.rs @@ -1421,9 +1421,9 @@ struct AnonUnionGroup { } fn get_anon_unions(info: &DwarfInfo, members: &[StructureMember]) -> Result> { - let mut unions = Vec::new(); + let mut unions = Vec::::new(); let mut offset = u32::MAX; - for (prev, member) in members.iter().skip(1).enumerate() { + 'member: for (prev, member) in members.iter().skip(1).enumerate() { if let Some(bit) = &member.bit { if bit.bit_offset != 0 { continue; @@ -1433,6 +1433,11 @@ fn get_anon_unions(info: &DwarfInfo, members: &[StructureMember]) -> Result Result Result Result max_size { + if member.offset + size > max_offset || member.offset < anon.offset { break; } anon.member_count += 1; @@ -1569,8 +1566,8 @@ pub fn struct_def_string( let mut indent = 4; let unions = get_anon_unions(info, &t.members)?; let groups = get_anon_union_groups(&t.members, &unions); - let mut in_union = false; - let mut in_group = false; + let mut in_union = 0; + let mut in_group = 0; for (i, member) in t.members.iter().enumerate() { if vis != member.visibility { vis = member.visibility; @@ -1584,28 +1581,28 @@ pub fn struct_def_string( if i == anon.member_index + anon.member_count { indent -= 4; out.push_str(&indent_all_by(indent, "};\n")); - in_group = false; + in_group -= 1; } } for anon in &unions { if i == anon.member_index + anon.member_count { indent -= 4; out.push_str(&indent_all_by(indent, "};\n")); - in_union = false; + in_union -= 1; } } for anon in &unions { if i == anon.member_index { out.push_str(&indent_all_by(indent, "union { // inferred\n")); indent += 4; - in_union = true; + in_union += 1; } } for anon in &groups { if i == anon.member_index { out.push_str(&indent_all_by(indent, "struct { // inferred\n")); indent += 4; - in_group = true; + in_group += 1; } } let mut var_out = String::new(); @@ -1618,13 +1615,15 @@ pub fn struct_def_string( writeln!(var_out, "; // offset {:#X}, size {:#X}", member.offset, size)?; out.push_str(&indent_all_by(indent, var_out)); } - if in_group { + while in_group > 0 { indent -= 4; out.push_str(&indent_all_by(indent, "};\n")); + in_group -= 1; } - if in_union { + while in_union > 0 { indent -= 4; out.push_str(&indent_all_by(indent, "};\n")); + in_union -= 1; } out.push('}'); Ok(out)