[Lldb-commits] [lldb] [lldb] fix LR/SC handling in lldb-server (PR #127505)

via lldb-commits lldb-commits at lists.llvm.org
Mon Feb 17 07:36:00 PST 2025


https://github.com/dlav-sc updated https://github.com/llvm/llvm-project/pull/127505

>From 244a67ec597d74df382825fce475b269e27a18ef Mon Sep 17 00:00:00 2001
From: Daniil Avdeev <daniil.avdeev at syntacore.com>
Date: Tue, 11 Feb 2025 16:38:53 +0000
Subject: [PATCH] [lldb][RISCV] 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..34c259a8e6a09 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);
 }



More information about the lldb-commits mailing list