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

@@ -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,8 +2835,8 @@ execx86(int cycs)
}
#ifdef USE_GDBSTUB
if (gdbstub_singlestep)
return;
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,89 +239,25 @@ 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;
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;
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);
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;
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);
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);
}
static __inline void x87_st_fsave(int reg)

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();