diff options
| author | Mason Reed <mason@vector35.com> | 2025-09-21 21:51:37 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-10-23 14:29:15 -0400 |
| commit | c35849163319ee606a28eb4d8bfd585b1f4eddcf (patch) | |
| tree | b6e2269effe50de773aecf71fca3f71801067ead /plugins/pdb-ng | |
| parent | 24e66649863d724aa532ff884c6f27c141a0eede (diff) | |
Support bitfields in type system
Also adds support for parsing bitfields in PDB, DWARF and SVD plugins
WIP: API needs to be considered more, also need to find type related apis that may need to be rethought.
Diffstat (limited to 'plugins/pdb-ng')
| -rw-r--r-- | plugins/pdb-ng/src/struct_grouper.rs | 87 | ||||
| -rw-r--r-- | plugins/pdb-ng/src/type_parser.rs | 86 |
2 files changed, 59 insertions, 114 deletions
diff --git a/plugins/pdb-ng/src/struct_grouper.rs b/plugins/pdb-ng/src/struct_grouper.rs index ff911afd..fcaf88ef 100644 --- a/plugins/pdb-ng/src/struct_grouper.rs +++ b/plugins/pdb-ng/src/struct_grouper.rs @@ -340,8 +340,10 @@ pub fn group_structure( .enumerate() .map(|(i, member)| MemberSize { index: i, - offset: member.offset, - width: member.ty.contents.width(), + offset: member.bitfield_position.unwrap_or(member.offset * 8), + width: member + .bitfield_size + .unwrap_or(member.ty.contents.width() * 8), }) .collect::<Vec<_>>(); @@ -359,14 +361,29 @@ pub fn group_structure( Err(e) => { warn!("{} Could not resolve structure groups: {}", name, e); for member in members { - structure.insert( - &member.ty, - &member.name, - member.offset, - false, - member.access, - member.scope, - ); + match (member.bitfield_position, member.bitfield_size) { + (Some(bit_pos), bit_width) => { + structure.insert_bitwise( + &member.ty, + &member.name, + bit_pos, + bit_width.map(|w| w as u8), + false, + member.access, + member.scope, + ); + } + (None, _) => { + structure.insert( + &member.ty, + &member.name, + member.offset, + false, + member.access, + member.scope, + ); + } + } } } } @@ -387,24 +404,38 @@ fn apply_groups( // TODO : Fix inner-offset being larger than `member.offset` - if offset > member.offset { - structure.insert( - &member.ty, - &member.name, - 0, - false, - member.access, - member.scope, - ); - } else { - structure.insert( - &member.ty, - &member.name, - member.offset - offset, - false, - member.access, - member.scope, - ); + match (member.bitfield_position, member.bitfield_size) { + (Some(bit_pos), bit_width) => { + structure.insert_bitwise( + &member.ty, + &member.name, + bit_pos, + bit_width.map(|w| w as u8), + false, + member.access, + member.scope, + ); + } + (None, _) if offset > member.offset => { + structure.insert( + &member.ty, + &member.name, + 0, + false, + member.access, + member.scope, + ); + } + (None, _) => { + structure.insert( + &member.ty, + &member.name, + member.offset - offset, + false, + member.access, + member.scope, + ); + } } } ResolvedGroup::Struct(inner_offset, children) => { diff --git a/plugins/pdb-ng/src/type_parser.rs b/plugins/pdb-ng/src/type_parser.rs index ba7f3cc9..dcb7234b 100644 --- a/plugins/pdb-ng/src/type_parser.rs +++ b/plugins/pdb-ng/src/type_parser.rs @@ -848,92 +848,6 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { None => {} } - // Combine bitfields into structures - let mut combined_bitfield_members = vec![]; - let mut last_bitfield_offset = u64::MAX; - let mut last_bitfield_pos = u64::MAX; - let mut last_bitfield_idx = 0; - let mut bitfield_builder: Option<StructureBuilder> = None; - - fn bitfield_name(offset: u64, idx: u64) -> String { - if idx > 0 { - format!("__bitfield{:x}_{}", offset, idx) - } else { - format!("__bitfield{:x}", offset) - } - } - - for m in members { - match (m.bitfield_position, m.bitfield_size) { - (Some(pos), Some(_size)) => { - if last_bitfield_offset != m.offset || last_bitfield_pos >= pos { - if let Some(builder) = bitfield_builder.take() { - combined_bitfield_members.push(ParsedMember { - ty: Conf::new( - Type::structure(builder.finalize().as_ref()), - MAX_CONFIDENCE, - ), - name: bitfield_name(last_bitfield_offset, last_bitfield_idx), - offset: last_bitfield_offset, - access: MemberAccess::PublicAccess, - scope: MemberScope::NoScope, - bitfield_size: None, - bitfield_position: None, - }); - } - let mut new_builder = StructureBuilder::new(); - new_builder.structure_type(StructureType::UnionStructureType); - new_builder.width(m.ty.contents.width()); - bitfield_builder = Some(new_builder); - - if last_bitfield_offset != m.offset { - last_bitfield_idx = 0; - } else { - last_bitfield_idx += 1; - } - } - - last_bitfield_pos = pos; - last_bitfield_offset = m.offset; - bitfield_builder - .as_mut() - .expect("Invariant") - .insert(&m.ty, &m.name, 0, false, m.access, m.scope); - } - (None, None) => { - if let Some(builder) = bitfield_builder.take() { - combined_bitfield_members.push(ParsedMember { - ty: Conf::new( - Type::structure(builder.finalize().as_ref()), - MAX_CONFIDENCE, - ), - name: bitfield_name(last_bitfield_offset, last_bitfield_idx), - offset: last_bitfield_offset, - access: MemberAccess::PublicAccess, - scope: MemberScope::NoScope, - bitfield_size: None, - bitfield_position: None, - }); - } - last_bitfield_offset = u64::MAX; - last_bitfield_pos = u64::MAX; - combined_bitfield_members.push(m); - } - e => return Err(anyhow!("Unexpected bitfield parameters {:?}", e)), - } - } - if let Some(builder) = bitfield_builder.take() { - combined_bitfield_members.push(ParsedMember { - ty: Conf::new(Type::structure(builder.finalize().as_ref()), MAX_CONFIDENCE), - name: bitfield_name(last_bitfield_offset, last_bitfield_idx), - offset: last_bitfield_offset, - access: MemberAccess::PublicAccess, - scope: MemberScope::NoScope, - bitfield_size: None, - bitfield_position: None, - }); - } - members = combined_bitfield_members; group_structure( &format!( "`{}`", |
