From 59254cd1e7ef3bd02c6f680de5f8cbcfe99f21a4 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sun, 29 Mar 2026 13:57:49 +0200 Subject: [PATCH] [dynarmic] restore proper backtraces for A64 (#3794) trivial changes, fixes hard crashes Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3794 Reviewed-by: Maufeat Reviewed-by: MaranBr Co-authored-by: lizzie Co-committed-by: lizzie --- src/core/arm/nce/interpreter_visitor.cpp | 6 +++++- .../src/dynarmic/frontend/A64/decoder/a64.h | 7 ++++--- .../frontend/A64/translate/a64_translate.cpp | 14 ++++++++++---- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/core/arm/nce/interpreter_visitor.cpp b/src/core/arm/nce/interpreter_visitor.cpp index be6fee8613..077a696cc8 100644 --- a/src/core/arm/nce/interpreter_visitor.cpp +++ b/src/core/arm/nce/interpreter_visitor.cpp @@ -773,7 +773,11 @@ std::optional MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, m bool was_executed = false; auto decoder = Dynarmic::A64::Decode(instruction); - was_executed = decoder.get().call(visitor, instruction); + if (decoder) { + was_executed = decoder->get().call(visitor, instruction); + } else { + was_executed = false; + } return was_executed ? std::optional(pc + 4) : std::nullopt; } diff --git a/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h b/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h index 4ac04731ea..eba9d73942 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h +++ b/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h @@ -70,14 +70,15 @@ constexpr DecodeTable GetDecodeTable() { /// In practice it must always suceed, otherwise something else unrelated would have gone awry template -std::reference_wrapper> Decode(u32 instruction) { +std::optional>> Decode(u32 instruction) { alignas(64) static const auto table = GetDecodeTable(); const auto& subtable = table[detail::ToFastLookupIndex(instruction)]; auto iter = std::find_if(subtable.begin(), subtable.end(), [instruction](const auto& matcher) { return matcher.Matches(instruction); }); - DEBUG_ASSERT(iter != subtable.end()); - return std::reference_wrapper>(*iter); + return iter != subtable.end() + ? std::optional{ std::reference_wrapper>(*iter) } + : std::nullopt; } template diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp index 6778d13890..4afce6bd29 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp @@ -25,7 +25,11 @@ void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFu const u64 pc = visitor.ir.current_location->PC(); if (const auto instruction = memory_read_code(pc)) { auto decoder = Decode(*instruction); - should_continue = decoder.get().call(visitor, *instruction); + if (decoder) { + should_continue = decoder->get().call(visitor, *instruction); + } else { + should_continue = visitor.RaiseException(Exception::UnallocatedEncoding); + } } else { should_continue = visitor.RaiseException(Exception::NoExecuteFault); } @@ -45,13 +49,15 @@ bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, bool should_continue = true; auto const decoder = Decode(instruction); - should_continue = decoder.get().call(visitor, instruction); + if (decoder) { + should_continue = decoder->get().call(visitor, instruction); + } else { + should_continue = false; + } visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4); block.CycleCount()++; - block.SetEndLocation(*visitor.ir.current_location); - return should_continue; }