Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GDB stub #1583

Merged
merged 28 commits into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2f67161
gdbstub beginnings
PoroCYon Dec 5, 2022
4a9456c
gdbstub: finish gdb impl things, next up is integration with melonDS
PoroCYon Dec 5, 2022
300bc37
holy fuck the gdbstub works
PoroCYon Dec 6, 2022
7059dee
gdb breakpoints work, but there's a mysterious crash on continue
PoroCYon Dec 8, 2022
358dfb1
fix memory corruption that sometimes happened, and make resetting the…
PoroCYon Dec 8, 2022
448848d
remove some gdb debug printing
PoroCYon Dec 8, 2022
857f574
fix things in gdbstub
PoroCYon Dec 13, 2022
f35a807
separate option for enabling gdbstub
PoroCYon Dec 13, 2022
160ee42
add mode-dependent CPU registers
PoroCYon Jul 8, 2023
e17cda7
C++ize the GDBstub code
PoroCYon Jul 9, 2023
e2b9e9a
add gdbstub config in emu settings dialog
PoroCYon Jul 9, 2023
c41bad1
make sure gdb is disabled when jit is enabled
PoroCYon Jul 9, 2023
071e588
Remove unnecessary compiler flags, mark ARMJIT assembly code as no-ex…
PoroCYon Jul 9, 2023
24cc71d
add option to wait for debugger attach on startup
PoroCYon Jul 9, 2023
0eebcdf
only insert GNU stack notes on linux
PoroCYon Jul 9, 2023
c71d47b
disable gdbstub enable checkbox when jit is enabled
PoroCYon Jul 9, 2023
c489593
fix non-linux incompatibilities
PoroCYon Jul 9, 2023
3ddb384
enable gdbstub by default
PoroCYon Jul 9, 2023
242c035
fix issues with gdbstub settings disable stuff
PoroCYon Jul 9, 2023
0503b19
format stuff
PoroCYon Jul 15, 2023
a94d924
update gdb test code
PoroCYon Jul 16, 2023
60cd6c1
Fix segfault when calling StubCallbacks->GetCPU()
PoroCYon Jul 18, 2023
34218ef
fix packet size not being sent correctly
PoroCYon Jul 20, 2023
30bb773
fix select(2) calls (i should read docs more properly)
PoroCYon Jul 24, 2023
223043c
fix GDB command sequencing/parsing issue (hopefully)
PoroCYon Aug 20, 2023
73d2c5f
[GDB] implement no-ack mode
PoroCYon Aug 21, 2023
fae3642
fix sending ack on handshake
PoroCYon Aug 21, 2023
7305cb3
get lldb to work
PoroCYon Aug 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
format stuff
  • Loading branch information
PoroCYon committed Jul 16, 2023
commit 0503b192801bec8bf56315360217889972719e73
376 changes: 184 additions & 192 deletions src/ARM.cpp

Large diffs are not rendered by default.

106 changes: 58 additions & 48 deletions src/ARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ const u32 ITCMPhysicalSize = 0x8000;
const u32 DTCMPhysicalSize = 0x4000;

class ARM
#ifdef GDBSTUB_ENABLED
: public Gdb::StubCallbacks
#endif
{
public:
ARM(u32 num);
Expand Down Expand Up @@ -99,7 +102,7 @@ class ARM

inline bool ModeIs(u32 mode)
{
uint32_t cm = CPSR & 0x1f;
u32 cm = CPSR & 0x1f;
mode &= 0x1f;

if (mode == cm) return true;
Expand Down Expand Up @@ -173,7 +176,7 @@ class ARM

static u32 ConditionTable[16];
#ifdef GDBSTUB_ENABLED
Gdb::GdbStub gdbstub;
Gdb::GdbStub GdbStub;
#endif

protected:
Expand All @@ -185,18 +188,22 @@ class ARM
void (*BusWrite32)(u32 addr, u32 val);

#ifdef GDBSTUB_ENABLED
bool is_single_step;
bool break_req;
bool break_on_startup;
bool IsSingleStep;
bool BreakReq;
bool BreakOnStartup;

static u32 GdbReadReg(void* ud, Gdb::Register reg);
static void GdbWriteReg(void* ud, Gdb::Register reg, u32 v);
static u32 GdbReadMem(void* ud, u32 addr, int size);
static void GdbWriteMem(void* ud, u32 addr, int size, u32 v);
u32 ReadReg(Gdb::Register reg) override;
void WriteReg(Gdb::Register reg, u32 v) override;
u32 ReadMem(u32 addr, int size) override;
void WriteMem(u32 addr, int size, u32 v) override;

static void GdbReset(void* ud);
static int GdbRemoteCmd(void* ud, const u8* cmd, size_t len);
void ResetGdb() override;
int RemoteCmd(const u8* cmd, size_t len) override;
#endif

void GdbCheckA();
void GdbCheckB();
void GdbCheckC();
};

class ARMv5 : public ARM
Expand All @@ -205,51 +212,51 @@ class ARMv5 : public ARM
ARMv5();
~ARMv5();

void Reset();
void Reset() override;

void DoSavestate(Savestate* file);
void DoSavestate(Savestate* file) override;

void UpdateRegionTimings(u32 addrstart, u32 addrend);

void FillPipeline();
void FillPipeline() override;

void JumpTo(u32 addr, bool restorecpsr = false);
void JumpTo(u32 addr, bool restorecpsr = false) override;

void PrefetchAbort();
void DataAbort();

void Execute();
void Execute() override;
#ifdef JIT_ENABLED
void ExecuteJIT();
void ExecuteJIT() override;
#endif

// all code accesses are forced nonseq 32bit
u32 CodeRead32(u32 addr, bool branch);

void DataRead8(u32 addr, u32* val);
void DataRead16(u32 addr, u32* val);
void DataRead32(u32 addr, u32* val);
void DataRead32S(u32 addr, u32* val);
void DataWrite8(u32 addr, u8 val);
void DataWrite16(u32 addr, u16 val);
void DataWrite32(u32 addr, u32 val);
void DataWrite32S(u32 addr, u32 val);
void DataRead8(u32 addr, u32* val) override;
void DataRead16(u32 addr, u32* val) override;
void DataRead32(u32 addr, u32* val) override;
void DataRead32S(u32 addr, u32* val) override;
void DataWrite8(u32 addr, u8 val) override;
void DataWrite16(u32 addr, u16 val) override;
void DataWrite32(u32 addr, u32 val) override;
void DataWrite32S(u32 addr, u32 val) override;

void AddCycles_C()
void AddCycles_C() override
{
// code only. always nonseq 32-bit for ARM9.
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
Cycles += numC;
}

void AddCycles_CI(s32 numI)
void AddCycles_CI(s32 numI) override
{
// code+internal
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
Cycles += numC + numI;
}

void AddCycles_CDI()
void AddCycles_CDI() override
{
// LDR/LDM cycles. ARM9 seems to skip the internal cycle there.
// TODO: ITCM data fetches shouldn't be parallelized, they say
Expand All @@ -262,7 +269,7 @@ class ARMv5 : public ARM
// Cycles += numC + numD;
}

void AddCycles_CD()
void AddCycles_CD() override
{
// TODO: ITCM data fetches shouldn't be parallelized, they say
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
Expand Down Expand Up @@ -338,7 +345,10 @@ class ARMv5 : public ARM
bool (*GetMemRegion)(u32 addr, bool write, NDS::MemRegion* region);

#ifdef GDBSTUB_ENABLED
static const Gdb::StubCallbacks GdbStubCallbacks;
int GetCPU() const override { return 9; }

u32 ReadMem(u32 addr, int size) override;
void WriteMem(u32 addr, int size, u32 v) override;
#endif
};

Expand All @@ -347,15 +357,15 @@ class ARMv4 : public ARM
public:
ARMv4();

void Reset();
void Reset() override;

void FillPipeline();
void FillPipeline() override;

void JumpTo(u32 addr, bool restorecpsr = false);
void JumpTo(u32 addr, bool restorecpsr = false) override;

void Execute();
void Execute() override;
#ifdef JIT_ENABLED
void ExecuteJIT();
void ExecuteJIT() override;
#endif

u16 CodeRead16(u32 addr)
Expand All @@ -368,14 +378,14 @@ class ARMv4 : public ARM
return BusRead32(addr);
}

void DataRead8(u32 addr, u32* val)
void DataRead8(u32 addr, u32* val) override
{
*val = BusRead8(addr);
DataRegion = addr;
DataCycles = NDS::ARM7MemTimings[addr >> 15][0];
}

void DataRead16(u32 addr, u32* val)
void DataRead16(u32 addr, u32* val) override
{
addr &= ~1;

Expand All @@ -384,7 +394,7 @@ class ARMv4 : public ARM
DataCycles = NDS::ARM7MemTimings[addr >> 15][0];
}

void DataRead32(u32 addr, u32* val)
void DataRead32(u32 addr, u32* val) override
{
addr &= ~3;

Expand All @@ -393,22 +403,22 @@ class ARMv4 : public ARM
DataCycles = NDS::ARM7MemTimings[addr >> 15][2];
}

void DataRead32S(u32 addr, u32* val)
void DataRead32S(u32 addr, u32* val) override
{
addr &= ~3;

*val = BusRead32(addr);
DataCycles += NDS::ARM7MemTimings[addr >> 15][3];
}

void DataWrite8(u32 addr, u8 val)
void DataWrite8(u32 addr, u8 val) override
{
BusWrite8(addr, val);
DataRegion = addr;
DataCycles = NDS::ARM7MemTimings[addr >> 15][0];
}

void DataWrite16(u32 addr, u16 val)
void DataWrite16(u32 addr, u16 val) override
{
addr &= ~1;

Expand All @@ -417,7 +427,7 @@ class ARMv4 : public ARM
DataCycles = NDS::ARM7MemTimings[addr >> 15][0];
}

void DataWrite32(u32 addr, u32 val)
void DataWrite32(u32 addr, u32 val) override
{
addr &= ~3;

Expand All @@ -426,7 +436,7 @@ class ARMv4 : public ARM
DataCycles = NDS::ARM7MemTimings[addr >> 15][2];
}

void DataWrite32S(u32 addr, u32 val)
void DataWrite32S(u32 addr, u32 val) override
{
addr &= ~3;

Expand All @@ -435,19 +445,19 @@ class ARMv4 : public ARM
}


void AddCycles_C()
void AddCycles_C() override
{
// code only. this code fetch is sequential.
Cycles += NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?1:3];
}

void AddCycles_CI(s32 num)
void AddCycles_CI(s32 num) override
{
// code+internal. results in a nonseq code fetch.
Cycles += NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2] + num;
}

void AddCycles_CDI()
void AddCycles_CDI() override
{
// LDR/LDM cycles.
s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2];
Expand All @@ -474,7 +484,7 @@ class ARMv4 : public ARM
}
}

void AddCycles_CD()
void AddCycles_CD() override
{
// TODO: max gain should be 5c when writing to mainRAM
s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2];
Expand All @@ -498,7 +508,7 @@ class ARMv4 : public ARM
}

#ifdef GDBSTUB_ENABLED
static const Gdb::StubCallbacks GdbStubCallbacks;
int GetCPU() const override { return 7; }
#endif
};

Expand Down
4 changes: 2 additions & 2 deletions src/ARMInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void A_UNK(ARM* cpu)
{
Log(LogLevel::Warn, "undefined ARM%d instruction %08X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-8);
#ifdef GDBSTUB_ENABLED
cpu->gdbstub.Enter(true, Gdb::TgtStatus::FaultInsn, cpu->R[15]-8);
cpu->GdbStub.Enter(true, Gdb::TgtStatus::FaultInsn, cpu->R[15]-8);
#endif
//for (int i = 0; i < 16; i++) printf("R%d: %08X\n", i, cpu->R[i]);
//NDS::Halt();
Expand All @@ -57,7 +57,7 @@ void T_UNK(ARM* cpu)
{
Log(LogLevel::Warn, "undefined THUMB%d instruction %04X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-4);
#ifdef GDBSTUB_ENABLED
cpu->gdbstub.Enter(true, Gdb::TgtStatus::FaultInsn, cpu->R[15]-4);
cpu->GdbStub.Enter(true, Gdb::TgtStatus::FaultInsn, cpu->R[15]-4);
#endif
//NDS::Halt();
u32 oldcpsr = cpu->CPSR;
Expand Down
8 changes: 5 additions & 3 deletions src/debug/GdbArch.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#ifndef GDBARCH_H_
#define GDBARCH_H_

namespace Gdb {
namespace Gdb
{

enum class Register : int {
enum class Register : int
{
r0,
r1,
r2,
Expand Down Expand Up @@ -52,7 +54,7 @@ enum class Register : int {
COUNT
};

#define GDB_ARCH_N_REG ((int)Register::COUNT)
constexpr int GDB_ARCH_N_REG = (int)Register::COUNT;

}

Expand Down
Loading