https://github.com/dlav-sc created https://github.com/llvm/llvm-project/pull/127505
lldb-server didn't consider that LR instruction may be followed not only by BNE instruction (takes 4 bytes), but by BNEZ too, which is a compressed instruction (takes 2 bytes). As a result, after BNEZ lldb-server reseived an incorrect PC value and couldn't parse the next instruction opcode. >From 2ab6cea7391b00ec865e6b7838452511320a2eee Mon Sep 17 00:00:00 2001 From: Daniil Avdeev <daniil.avd...@syntacore.com> Date: Tue, 11 Feb 2025 16:38:53 +0000 Subject: [PATCH] [lldb] fix LR/SC handling in lldb-server lldb-server didn't consider that LR instruction may be followed not only by BNE instruction (takes 4 bytes), but by BNEZ too, which is a compressed instruction (takes 2 bytes). As a result, after BNEZ lldb-server reseived an incorrect PC value and couldn't parse the next instruction opcode. --- .../RISCV/EmulateInstructionRISCV.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp b/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp index badc7ba36f011..e4de28d97d1ff 100644 --- a/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp +++ b/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp @@ -349,9 +349,10 @@ bool AtomicSequence(EmulateInstructionRISCV &emulator) { if (!inst || (!std::holds_alternative<LR_W>(inst->decoded) && !std::holds_alternative<LR_D>(inst->decoded))) return false; + current_pc += 4; - // The second instruction should be BNE to exit address - inst = emulator.ReadInstructionAt(current_pc += 4); + // The second instruction should be BNE or C.BNEZ to exit address + inst = emulator.ReadInstructionAt(current_pc); if (!inst || !std::holds_alternative<B>(inst->decoded)) return false; auto bne_exit = std::get<B>(inst->decoded); @@ -359,15 +360,18 @@ bool AtomicSequence(EmulateInstructionRISCV &emulator) { return false; // save the exit address to check later const auto exit_pc = current_pc + SextW(bne_exit.imm); + // Can be C.BNEZ (2 bytes) or BNE (4 bytes) + current_pc += inst->is_rvc ? 2 : 4; // The third instruction should be SC.W or SC.D - inst = emulator.ReadInstructionAt(current_pc += 4); + inst = emulator.ReadInstructionAt(current_pc); if (!inst || (!std::holds_alternative<SC_W>(inst->decoded) && !std::holds_alternative<SC_D>(inst->decoded))) return false; + current_pc += 4; - // The fourth instruction should be BNE to entry address - inst = emulator.ReadInstructionAt(current_pc += 4); + // The fourth instruction should be BNE or C.BNEZ to entry address + inst = emulator.ReadInstructionAt(current_pc); if (!inst || !std::holds_alternative<B>(inst->decoded)) return false; auto bne_start = std::get<B>(inst->decoded); @@ -375,8 +379,9 @@ bool AtomicSequence(EmulateInstructionRISCV &emulator) { return false; if (entry_pc != current_pc + SextW(bne_start.imm)) return false; + // Can be C.BNEZ (2 bytes) or BNE (4 bytes) + current_pc += inst->is_rvc ? 2 : 4; - current_pc += 4; // check the exit address and jump to it return exit_pc == current_pc && emulator.WritePC(current_pc); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits