rudy_dwarf/parser/
hashmap.rs1use rudy_types::MapVariant;
4
5use super::{
6 children::parse_children,
7 primitives::{attr, data_offset, entry_type, generic, is_member, is_member_offset, member},
8 Parser,
9};
10use crate::{Die, DwarfDb};
11
12type Result<T> = anyhow::Result<T>;
13
14pub fn hashbrown_map() -> impl Parser<MapVariant> {
16 struct HashBrownMapParser;
17
18 impl Parser<MapVariant> for HashBrownMapParser {
19 fn parse(&self, db: &dyn DwarfDb, entry: Die) -> Result<MapVariant> {
20 let (mut table_offset, inner_table_type) = member("table")
22 .then(data_offset().and(entry_type()))
23 .parse(db, entry)?;
24
25 let ((pair_size, (key_offset, value_offset)), (inner_table_offset, raw_table_type)) =
26 parse_children((
27 generic("T").then(attr(gimli::DW_AT_byte_size).and(parse_children((
29 is_member_offset("__0"),
30 is_member_offset("__1"),
31 )))),
32 is_member("table").then(data_offset().and(entry_type())),
34 ))
35 .parse(db, inner_table_type)?;
36
37 table_offset += inner_table_offset;
38
39 let (bucket_mask_offset, ctrl_offset, items_offset) = parse_children((
40 is_member_offset("bucket_mask"),
41 is_member_offset("ctrl"),
42 is_member_offset("items"),
43 ))
44 .parse(db, raw_table_type)?;
45
46 let bucket_mask_offset = table_offset + bucket_mask_offset;
48 let ctrl_offset = table_offset + ctrl_offset;
49 let items_offset = table_offset + items_offset;
50
51 Ok(MapVariant::HashMap {
52 bucket_mask_offset,
53 ctrl_offset,
54 items_offset,
55 pair_size,
56 key_offset,
57 value_offset,
58 })
59 }
60 }
61
62 HashBrownMapParser
63}