Decodes the provided trap information section and attempts to find the trap code corresponding to the `offset` specified. The `section` provided is expected to have been built by `TrapEncodingBuilder` above. Additionally the `offset` should be a relative offset within the text section of the compilation image.
(section: &[u8], offset: usize)
| 289 | /// `TrapEncodingBuilder` above. Additionally the `offset` should be a relative |
| 290 | /// offset within the text section of the compilation image. |
| 291 | pub fn lookup_trap_code(section: &[u8], offset: usize) -> Option<CompiledTrap> { |
| 292 | let (offsets, traps) = parse(section)?; |
| 293 | |
| 294 | // The `offsets` table is sorted in the trap section so perform a binary |
| 295 | // search of the contents of this section to find whether `offset` is an |
| 296 | // entry in the section. Note that this is a precise search because trap pcs |
| 297 | // should always be precise as well as our metadata about them, which means |
| 298 | // we expect an exact match to correspond to a trap opcode. |
| 299 | // |
| 300 | // Once an index is found within the `offsets` array then that same index is |
| 301 | // used to lookup from the `traps` list of bytes to get the trap code byte |
| 302 | // corresponding to this offset. |
| 303 | let offset = u32::try_from(offset).ok()?; |
| 304 | let index = offsets |
| 305 | .binary_search_by_key(&offset, |val| val.get(LittleEndian)) |
| 306 | .ok()?; |
| 307 | debug_assert!(index < traps.len()); |
| 308 | let byte = *traps.get(index)?; |
| 309 | |
| 310 | let trap = CompiledTrap::from_u8(byte); |
| 311 | debug_assert!(trap.is_some(), "missing mapping for {byte}"); |
| 312 | trap |
| 313 | } |
| 314 | |
| 315 | fn parse(section: &[u8]) -> Option<(&[U32<LittleEndian>], &[u8])> { |
| 316 | let mut section = Bytes(section); |
no test coverage detected