GDB Stub: More progress

This commit is contained in:
RichardG867
2022-03-16 00:33:01 -03:00
parent 7a3ff82a63
commit f57cbe36b1
18 changed files with 972 additions and 241 deletions

View File

@@ -121,7 +121,7 @@ option(DINPUT "DirectInput"
option(CPPTHREADS "C++11 threads" ON)
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
option(GDBSTUB "Enable GDB stub server for debugging" ON)
option(GDBSTUB "Enable GDB stub server for debugging" OFF)
option(DEV_BRANCH "Development branch" OFF)
if(NOT WIN32)
option(QT "QT GUI" ON)

View File

@@ -1204,6 +1204,9 @@ pc_run(void)
/* Run a block of code. */
startblit();
cpu_exec(cpu_s->rspeed / 100);
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
if (gdbstub_step == GDBSTUB_EXEC)
#endif
mouse_process();
joystick_process();
endblit();

View File

@@ -259,7 +259,7 @@ exec386(int cycs)
timer_process_inline();
#ifdef USE_GDBSTUB
if (gdbstub_singlestep)
if (gdbstub_instruction())
return;
#endif
}

View File

@@ -26,6 +26,7 @@
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/machine.h>
#include <86box/gdbstub.h>
#ifdef USE_DYNAREC
#include "codegen.h"
#ifdef USE_NEW_DYNAREC
@@ -858,6 +859,11 @@ exec386_dynarec(int cycs)
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
timer_process_inline();
}
#ifdef USE_GDBSTUB
if (gdbstub_instruction())
return;
#endif
}
cycles_main -= (cycles_start - cycles);

View File

@@ -19,6 +19,7 @@
#include <86box/mem.h>
#include <86box/nmi.h>
#include <86box/pic.h>
#include <86box/gdbstub.h>
#include "codegen.h"
#define CPU_BLOCK_END() cpu_block_end = 1

View File

@@ -2835,7 +2835,7 @@ execx86(int cycs)
}
#ifdef USE_GDBSTUB
if (gdbstub_singlestep)
if (gdbstub_instruction())
return;
#endif
}

View File

@@ -36,6 +36,7 @@
#include <86box/nmi.h>
#include <86box/pic.h>
#include <86box/pci.h>
#include <86box/gdbstub.h>
#ifdef USE_DYNAREC
# include "codegen.h"
#endif
@@ -1383,6 +1384,7 @@ cpu_set(void)
cpu_exec = exec386;
else
cpu_exec = execx86;
gdbstub_cpu_init();
}

View File

@@ -1,6 +1,10 @@
static int opINT3(uint32_t fetchdat)
{
int cycles_old = cycles; UN_USED(cycles_old);
#ifdef USE_GDBSTUB
if (gdbstub_int3())
return 1;
#endif
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
{
x86gpf(NULL,0);

View File

@@ -239,86 +239,22 @@ static __inline int64_t x87_fround(double b)
return 0LL;
}
#define BIAS80 16383
#define BIAS64 1023
#include "x87_ops_conv.h"
static __inline double x87_ld80()
{
int64_t exp64;
int64_t blah;
int64_t exp64final;
int64_t mant64;
int64_t sign;
struct {
int16_t begin;
union
{
double d;
uint64_t ll;
} eind;
} test;
x87_conv_t test;
test.eind.ll = readmeml(easeg,cpu_state.eaaddr);
test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32;
test.begin = readmemw(easeg,cpu_state.eaaddr+8);
exp64 = (((test.begin&0x7fff) - BIAS80));
blah = ((exp64 >0)?exp64:-exp64)&0x3ff;
exp64final = ((exp64 >0)?blah:-blah) +BIAS64;
mant64 = (test.eind.ll >> 11) & (0xfffffffffffffll);
sign = (test.begin&0x8000)?1:0;
if ((test.begin & 0x7fff) == 0x7fff)
exp64final = 0x7ff;
if ((test.begin & 0x7fff) == 0)
exp64final = 0;
if (test.eind.ll & 0x400)
mant64++;
test.eind.ll = (sign <<63)|(exp64final << 52)| mant64;
return test.eind.d;
return x87_from80(&test);
}
static __inline void x87_st80(double d)
{
int64_t sign80;
int64_t exp80;
int64_t exp80final;
int64_t mant80;
int64_t mant80final;
struct {
int16_t begin;
union
{
double d;
uint64_t ll;
} eind;
} test;
test.eind.d=d;
sign80 = (test.eind.ll&(0x8000000000000000ll))?1:0;
exp80 = test.eind.ll&(0x7ff0000000000000ll);
exp80final = (exp80>>52);
mant80 = test.eind.ll&(0x000fffffffffffffll);
mant80final = (mant80 << 11);
if (exp80final == 0x7ff) /*Infinity / Nan*/
{
exp80final = 0x7fff;
mant80final |= (0x8000000000000000ll);
}
else if (d != 0){ /* Zero is a special case */
/* Elvira wants the 8 and tcalc doesn't */
mant80final |= (0x8000000000000000ll);
/* Ca-cyber doesn't like this when result is zero. */
exp80final += (BIAS80 - BIAS64);
}
test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final;
test.eind.ll = mant80final;
x87_conv_t test;
x87_to80(d, &test);
writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff);
writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32);
writememw(easeg,cpu_state.eaaddr+8,test.begin);

68
src/cpu/x87_ops_conv.h Normal file
View File

@@ -0,0 +1,68 @@
#define BIAS80 16383
#define BIAS64 1023
typedef struct {
int16_t begin;
union {
double d;
uint64_t ll;
} eind;
} x87_conv_t;
static __inline double x87_from80(x87_conv_t *test)
{
int64_t exp64;
int64_t blah;
int64_t exp64final;
int64_t mant64;
int64_t sign;
exp64 = (((test->begin&0x7fff) - BIAS80));
blah = ((exp64 >0)?exp64:-exp64)&0x3ff;
exp64final = ((exp64 >0)?blah:-blah) +BIAS64;
mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll);
sign = (test->begin&0x8000)?1:0;
if ((test->begin & 0x7fff) == 0x7fff)
exp64final = 0x7ff;
if ((test->begin & 0x7fff) == 0)
exp64final = 0;
if (test->eind.ll & 0x400)
mant64++;
test->eind.ll = (sign <<63)|(exp64final << 52)| mant64;
return test->eind.d;
}
static __inline void x87_to80(double d, x87_conv_t *test)
{
int64_t sign80;
int64_t exp80;
int64_t exp80final;
int64_t mant80;
int64_t mant80final;
test->eind.d=d;
sign80 = (test->eind.ll&(0x8000000000000000ll))?1:0;
exp80 = test->eind.ll&(0x7ff0000000000000ll);
exp80final = (exp80>>52);
mant80 = test->eind.ll&(0x000fffffffffffffll);
mant80final = (mant80 << 11);
if (exp80final == 0x7ff) /*Infinity / Nan*/
{
exp80final = 0x7fff;
mant80final |= (0x8000000000000000ll);
}
else if (d != 0){ /* Zero is a special case */
/* Elvira wants the 8 and tcalc doesn't */
mant80final |= (0x8000000000000000ll);
/* Ca-cyber doesn't like this when result is zero. */
exp80final += (BIAS80 - BIAS64);
}
test->begin = (((int16_t)sign80)<<15)| (int16_t)exp80final;
test->eind.ll = mant80final;
}

File diff suppressed because it is too large Load Diff

View File

@@ -16,20 +16,60 @@
*/
#ifndef EMU_GDBSTUB_H
# define EMU_GDBSTUB_H
#include <86box/mem.h>
#define GDBSTUB_MEM_READ 0
#define GDBSTUB_MEM_WRITE 16
#define GDBSTUB_MEM_AWATCH 32
enum {
GDBSTUB_EXEC = 0,
GDBSTUB_SSTEP,
GDBSTUB_BREAK,
GDBSTUB_BREAK_SW,
GDBSTUB_BREAK_HW,
GDBSTUB_BREAK_RWATCH,
GDBSTUB_BREAK_WWATCH,
GDBSTUB_BREAK_AWATCH
};
#ifdef USE_GDBSTUB
extern int gdbstub_singlestep;
#define GDBSTUB_MEM_ACCESS(addr, access, width) \
uint32_t gdbstub_page = addr >> MEM_GRANULARITY_BITS; \
if (gdbstub_watch_pages[gdbstub_page >> 6] & (1 << (gdbstub_page & 63)) || (addr == 0xb8dd4)) { \
uint32_t gdbstub_addrs[width]; \
for (int gdbstub_i = 0; gdbstub_i < width; gdbstub_i++) \
gdbstub_addrs[gdbstub_i] = addr + gdbstub_i; \
gdbstub_mem_access(gdbstub_addrs, access | width); \
}
extern void gdbstub_pause(int *p);
#define GDBSTUB_MEM_ACCESS_FAST(addrs, access, width) \
uint32_t gdbstub_page = addr >> MEM_GRANULARITY_BITS; \
if (gdbstub_watch_pages[gdbstub_page >> 6] & (1 << (gdbstub_page & 63)) || (addr == 0xb8dd4)) \
gdbstub_mem_access(addrs, access | width);
extern int gdbstub_step, gdbstub_next_asap;
extern uint64_t gdbstub_watch_pages[(((uint32_t) -1) >> (MEM_GRANULARITY_BITS + 6)) + 1];
extern void gdbstub_cpu_init();
extern int gdbstub_instruction();
extern int gdbstub_int3();
extern void gdbstub_mem_access(uint32_t *addrs, int access);
extern void gdbstub_init();
extern void gdbstub_close();
#else
#define gdbstub_singlestep 0
#define GDBSTUB_MEM_ACCESS(addr, access, width)
#define GDBSTUB_MEM_ACCESS_FAST(addrs, access, width)
#define gdbstub_pause(p)
#define gdbstub_step 0
#define gdbstub_next_asap 0
#define gdbstub_cpu_init()
#define gdbstub_instruction() 0
#define gdbstub_int3() 0
#define gdbstub_init()
#define gdbstub_close()

View File

@@ -36,6 +36,7 @@
#include <86box/mem.h>
#include <86box/plat.h>
#include <86box/rom.h>
#include <86box/gdbstub.h>
#ifdef USE_DYNAREC
# include "codegen_public.h"
#else
@@ -783,6 +784,8 @@ readmembl(uint32_t addr)
mem_mapping_t *map;
uint64_t a;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
addr64 = (uint64_t) addr;
mem_logical_addr = addr;
@@ -811,6 +814,8 @@ writemembl(uint32_t addr, uint8_t val)
mem_mapping_t *map;
uint64_t a;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
addr64 = (uint64_t) addr;
mem_logical_addr = addr;
@@ -842,6 +847,8 @@ readmembl_no_mmut(uint32_t addr, uint32_t a64)
{
mem_mapping_t *map;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
mem_logical_addr = addr;
if (cr0 >> 31) {
@@ -866,6 +873,8 @@ writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val)
{
mem_mapping_t *map;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
mem_logical_addr = addr;
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_b) {
@@ -896,6 +905,7 @@ readmemwl(uint32_t addr)
addr64a[0] = addr;
addr64a[1] = addr + 1;
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2);
mem_logical_addr = addr;
@@ -957,6 +967,7 @@ writememwl(uint32_t addr, uint16_t val)
addr64a[0] = addr;
addr64a[1] = addr + 1;
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2);
mem_logical_addr = addr;
@@ -1029,6 +1040,8 @@ readmemwl_no_mmut(uint32_t addr, uint32_t *a64)
{
mem_mapping_t *map;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2);
mem_logical_addr = addr;
if (addr & 1) {
@@ -1076,6 +1089,8 @@ writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val)
{
mem_mapping_t *map;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2);
mem_logical_addr = addr;
if (addr & 1) {
@@ -1135,6 +1150,7 @@ readmemll(uint32_t addr)
for (i = 0; i < 4; i++)
addr64a[i] = (uint64_t) (addr + i);
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4);
mem_logical_addr = addr;
@@ -1214,6 +1230,7 @@ writememll(uint32_t addr, uint32_t val)
for (i = 0; i < 4; i++)
addr64a[i] = (uint64_t) (addr + i);
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4);
mem_logical_addr = addr;
@@ -1305,6 +1322,8 @@ readmemll_no_mmut(uint32_t addr, uint32_t *a64)
#ifndef NO_MMUT
mem_mapping_t *map;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4);
mem_logical_addr = addr;
if (addr & 3) {
@@ -1361,6 +1380,8 @@ writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val)
#ifndef NO_MMUT
mem_mapping_t *map;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4);
mem_logical_addr = addr;
if (addr & 3) {
@@ -1429,6 +1450,7 @@ readmemql(uint32_t addr)
for (i = 0; i < 8; i++)
addr64a[i] = (uint64_t) (addr + i);
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8);
mem_logical_addr = addr;
@@ -1496,6 +1518,7 @@ writememql(uint32_t addr, uint64_t val)
for (i = 0; i < 8; i++)
addr64a[i] = (uint64_t) (addr + i);
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8);
mem_logical_addr = addr;

View File

@@ -54,6 +54,7 @@ extern "C"
#include <86box/ui.h>
#include <86box/video.h>
#include <86box/discord.h>
#include <86box/gdbstub.h>
}
#include <thread>
@@ -95,6 +96,11 @@ main_thread_fn()
while (!is_quit && cpu_thread_run) {
/* See if it is time to run a frame of code. */
new_time = elapsed_timer.elapsed();
#ifdef USE_GDBSTUB
if (gdbstub_next_asap && (drawits <= 0))
drawits = 10;
else
#endif
drawits += (new_time - old_time);
old_time = new_time;
if (drawits > 0 && !dopause) {

View File

@@ -92,7 +92,6 @@ extern "C" {
#include "../cpu/cpu.h"
#include <86box/plat.h>
#include <86box/gdbstub.h>
volatile int cpu_thread_run = 1;
int mouse_capture = 0;
@@ -315,8 +314,6 @@ plat_pause(int p)
static wchar_t oldtitle[512];
wchar_t title[512], paused_msg[64];
gdbstub_pause(&p);
if (p == dopause) {
#ifdef Q_OS_WINDOWS
if (source_hwnd)

View File

@@ -523,6 +523,11 @@ main_thread(void *param)
while (!is_quit && cpu_thread_run) {
/* See if it is time to run a frame of code. */
new_time = SDL_GetTicks();
#ifdef USE_GDBSTUB
if (gdbstub_next_asap && (drawits <= 0))
drawits = 10;
else
#endif
drawits += (new_time - old_time);
old_time = new_time;
if (drawits > 0 && !dopause) {
@@ -720,8 +725,6 @@ plat_pause(int p)
static wchar_t oldtitle[512];
wchar_t title[512];
gdbstub_pause(&p);
if ((p == 0) && (time_sync & TIME_SYNC_ENABLED))
nvr_time_sync();

View File

@@ -55,6 +55,7 @@
#include <86box/win_opengl.h>
#include <86box/win.h>
#include <86box/version.h>
#include <86box/gdbstub.h>
#ifdef MTR_ENABLED
#include <minitrace/minitrace.h>
#endif
@@ -525,6 +526,11 @@ main_thread(void *param)
while (!is_quit && cpu_thread_run) {
/* See if it is time to run a frame of code. */
new_time = GetTickCount();
#ifdef USE_GDBSTUB
if (gdbstub_next_asap && (drawits <= 0))
drawits = 10;
else
#endif
drawits += (new_time - old_time);
old_time = new_time;
if (drawits > 0 && !dopause) {

View File

@@ -44,7 +44,6 @@
#include <86box/win.h>
#include <86box/version.h>
#include <86box/discord.h>
#include <86box/gdbstub.h>
#ifdef MTR_ENABLED
#include <minitrace/minitrace.h>
@@ -1497,8 +1496,6 @@ plat_pause(int p)
static wchar_t oldtitle[512];
wchar_t title[512];
gdbstub_pause(&p);
/* If un-pausing, as the renderer if that's OK. */
if (p == 0)
p = get_vidpause();