arch-riscv: fix GDB breakpoint issue for RV32 (#1470)
Since PR #1316, we use sign-extend for all address generation, including PC, to match the ISA specification for modifiable XLEN. However, when we set a breakpoint using remote GDB, our address is not sign-extended. This causes the breakpoint to be set at the wrong address, as specified in Issue #1463. This PR fixes the issue by sign-extending the address when setting a breakpoint. This also matches the RISC-V ISA Specification that "must sign-extend results to fill the entire widest supported XLEN in the destination register." Change-Id: I9b493bf8ad5b1ef45a9728bb40fc5e38250fe9c3 Signed-off-by: Yangyu Chen <cyy@cyyself.name>
This commit is contained in:
@@ -233,6 +233,20 @@ RemoteGDB::acc(Addr va, size_t len)
|
||||
return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
RemoteGDB::insertHardBreak(Addr addr, size_t kind)
|
||||
{
|
||||
Addr realAddr = getRvType(context()) == RV64 ? addr : sext(addr, 32);
|
||||
BaseRemoteGDB::insertHardBreak(realAddr, kind);
|
||||
}
|
||||
|
||||
void
|
||||
RemoteGDB::removeHardBreak(Addr addr, size_t kind)
|
||||
{
|
||||
Addr realAddr = getRvType(context()) == RV64 ? addr : sext(addr, 32);
|
||||
BaseRemoteGDB::removeHardBreak(realAddr, kind);
|
||||
}
|
||||
|
||||
void
|
||||
RemoteGDB::Riscv32GdbRegCache::getRegs(ThreadContext *context)
|
||||
{
|
||||
|
||||
@@ -57,6 +57,8 @@ class RemoteGDB : public BaseRemoteGDB
|
||||
bool acc(Addr addr, size_t len) override;
|
||||
// A breakpoint will be 2 bytes if it is compressed and 4 if not
|
||||
bool checkBpKind(size_t kind) override { return kind == 2 || kind == 4; }
|
||||
void insertHardBreak(Addr addr, size_t kind) override;
|
||||
void removeHardBreak(Addr addr, size_t kind) override;
|
||||
|
||||
class Riscv32GdbRegCache : public BaseGdbRegCache
|
||||
{
|
||||
|
||||
@@ -321,10 +321,10 @@ class BaseRemoteGDB
|
||||
void descheduleInstCommitEvent(Event *ev);
|
||||
|
||||
// Breakpoints.
|
||||
void insertSoftBreak(Addr addr, size_t kind);
|
||||
void removeSoftBreak(Addr addr, size_t kind);
|
||||
void insertHardBreak(Addr addr, size_t kind);
|
||||
void removeHardBreak(Addr addr, size_t kind);
|
||||
virtual void insertSoftBreak(Addr addr, size_t kind);
|
||||
virtual void removeSoftBreak(Addr addr, size_t kind);
|
||||
virtual void insertHardBreak(Addr addr, size_t kind);
|
||||
virtual void removeHardBreak(Addr addr, size_t kind);
|
||||
|
||||
void sendTPacket(GDBSignal sig, ContextID id,
|
||||
const std::string& stopReason);
|
||||
|
||||
Reference in New Issue
Block a user