(bin: &[u8], dump: &str)
| 66 | |
| 67 | #[cfg_attr(target_family = "wasm", wasm_bindgen)] |
| 68 | pub fn decode(bin: &[u8], dump: &str) -> ReturnType { |
| 69 | // Prepare vector for output data |
| 70 | let mut decoded_data = Vec::<DecodedAddress>::new(); |
| 71 | #[cfg(target_family = "wasm")] |
| 72 | let format_return = |decoded_data: Vec::<DecodedAddress>| { |
| 73 | decoded_data.into_iter().map(JsValue::from).collect() |
| 74 | }; |
| 75 | #[cfg(not(target_family = "wasm"))] |
| 76 | let format_return = |decoded_data| { |
| 77 | decoded_data |
| 78 | }; |
| 79 | |
| 80 | // Used to keep slices from uncompressed section data |
| 81 | let arena_data = Arena::new(); |
| 82 | |
| 83 | // Parse the binary as an object file |
| 84 | let object = &object::File::parse(bin); |
| 85 | let object = match object { |
| 86 | Ok(object) => object, |
| 87 | Err(_) => return format_return(decoded_data), |
| 88 | }; |
| 89 | let endianness = match object.endianness() { |
| 90 | Endianness::Little => gimli::RunTimeEndian::Little, |
| 91 | Endianness::Big => gimli::RunTimeEndian::Big |
| 92 | }; |
| 93 | |
| 94 | // Wrapper for the Dwarf loader |
| 95 | let mut load_section = |id: gimli::SectionId| -> Result<_, _> { |
| 96 | load_file_section(id, object, endianness, &arena_data) |
| 97 | }; |
| 98 | |
| 99 | // Load the Dwarf sections |
| 100 | let dwarf = gimli::Dwarf::load(&mut load_section); |
| 101 | let dwarf = match dwarf { |
| 102 | Ok(dwarf) => dwarf, |
| 103 | Err(_) => return format_return(decoded_data), |
| 104 | }; |
| 105 | let ctx = Context::from_dwarf(dwarf); |
| 106 | let ctx = match ctx { |
| 107 | Ok(ctx) => ctx, |
| 108 | Err(_) => return format_return(decoded_data), |
| 109 | }; |
| 110 | |
| 111 | // Match everything that looks like a program address |
| 112 | let re = Regex::new(r"(4[0-9a-fA-F]{7})\b").unwrap(); |
| 113 | for cap in re.captures_iter(dump) { |
| 114 | let address = u64::from_str_radix(&cap[0], 16).unwrap(); |
| 115 | // Look for frame that contains the address |
| 116 | let mut frames = match ctx.find_frames(address) { |
| 117 | Ok(frames) => frames.enumerate(), |
| 118 | Err(_) => continue, |
| 119 | }; |
| 120 | while let Some((_, frame)) = frames.next().unwrap() { |
| 121 | // Skip if it doesn't point to a function |
| 122 | if frame.function.is_none() { |
| 123 | continue; |
| 124 | } |
| 125 | // Extract function name |
no test coverage detected