diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ffe79b2..d6a10693 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] - [#399] Update link shown in error message +- [#398] Handle reset vector not pointing to ELF symbol [#399]: https://github.com/knurling-rs/probe-run/pull/399 +[#398]: https://github.com/knurling-rs/probe-run/pull/398 ## [v0.3.8] - 2023-04-12 diff --git a/src/backtrace/unwind.rs b/src/backtrace/unwind.rs index c625d03a..b209c8ba 100644 --- a/src/backtrace/unwind.rs +++ b/src/backtrace/unwind.rs @@ -98,8 +98,11 @@ pub fn target(core: &mut Core, elf: &Elf, target_info: &TargetInfo) -> Output { // If the frame didn't move, and the program counter didn't change, bail out // (otherwise we might print the same frame over and over). if !cfa_changed && !program_counter_changed { - // If we do not end up in the reset function the stack is corrupted - output.corrupted = !elf.reset_fn_range().contains(&pc); + // If we do not end up in the reset function the stack is corrupted. + // If reset_fn_range is empty, we can't detect this and just assume that + // the stack was not corrupted. + let reset_fn_range = elf.reset_fn_range(); + output.corrupted = !(reset_fn_range.contains(&pc) || reset_fn_range.is_empty()); break; } diff --git a/src/elf.rs b/src/elf.rs index ba045385..10c14529 100644 --- a/src/elf.rs +++ b/src/elf.rs @@ -216,13 +216,16 @@ fn extract_symbols(elf: &ObjectFile, reset_fn_address: u32) -> anyhow::Result reset_symbols.remove(0), - _ => bail!("unable to determine reset handler"), - }; - let addr = reset.address().try_into().expect("expected 32-bit ELF"); - let size: u32 = reset.size().try_into().expect("expected 32-bit ELF"); - addr..addr + size + if reset_symbols.len() == 1 { + let reset = reset_symbols.remove(0); + let addr = reset.address().try_into().expect("expected 32-bit ELF"); + let size: u32 = reset.size().try_into().expect("expected 32-bit ELF"); + addr..addr + size + } else { + log::debug!("unable to determine reset handler"); + // The length of the reset handler is not known as it's not part of the ELF file + reset_fn_address..reset_fn_address + } }; Ok(Symbols {