summaryrefslogtreecommitdiff
path: root/plugins/pdb-ng
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-09-21 21:51:37 -0400
committerMason Reed <mason@vector35.com>2025-10-23 14:29:15 -0400
commitc35849163319ee606a28eb4d8bfd585b1f4eddcf (patch)
treeb6e2269effe50de773aecf71fca3f71801067ead /plugins/pdb-ng
parent24e66649863d724aa532ff884c6f27c141a0eede (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.rs87
-rw-r--r--plugins/pdb-ng/src/type_parser.rs86
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!(
"`{}`",