📄 i386-stub-win32.c
字号:
*ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */
*ptr++ = hexchars[sigval >> 4];
*ptr++ = hexchars[sigval & 0xf];
*ptr++ = hexchars[ESP];
*ptr++ = ':';
ptr = mem2hex((char *)®isters[ESP], ptr, 4, 0); /* SP */
*ptr++ = ';';
*ptr++ = hexchars[EBP];
*ptr++ = ':';
ptr = mem2hex((char *)®isters[EBP], ptr, 4, 0); /* FP */
*ptr++ = ';';
*ptr++ = hexchars[PC];
*ptr++ = ':';
ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); /* PC */
*ptr++ = ';';
*ptr = '\0';
putpacket (remcomOutBuffer);
stepping = 0;
while (1 == 1)
{
remcomOutBuffer[0] = 0;
ptr = getpacket ();
switch (*ptr++)
{
case '?':
remcomOutBuffer[0] = 'S';
remcomOutBuffer[1] = hexchars[sigval >> 4];
remcomOutBuffer[2] = hexchars[sigval % 16];
remcomOutBuffer[3] = 0;
break;
case 'd':
remote_debug = !(remote_debug); /* toggle debug flag */
break;
case 'g': /* return the value of the CPU registers */
mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0);
break;
case 'G': /* set the value of the CPU registers - return OK */
hex2mem (ptr, (char *) registers, NUMREGBYTES, 0);
strcpy_s(remcomOutBuffer, BUFMAX, "OK");
break;
case 'P': /* set the value of a single CPU register - return OK */
{
int regno;
if (hexToInt (&ptr, ®no) && *ptr++ == '=')
if (regno >= 0 && regno < NUMREGS)
{
hex2mem (ptr, (char *) ®isters[regno], 4, 0);
strcpy_s(remcomOutBuffer, BUFMAX, "OK");
break;
}
strcpy_s(remcomOutBuffer, BUFMAX, "E01");
break;
}
/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
case 'm':
/* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
if (hexToInt (&ptr, &addr))
if (*(ptr++) == ',')
if (hexToInt (&ptr, &length))
{
ptr = 0;
mem_err = 0;
mem2hex ((char *) addr, remcomOutBuffer, length, 1);
if (mem_err)
{
strcpy_s(remcomOutBuffer, BUFMAX, "E03");
debug_error ("memory fault");
}
}
if (ptr)
{
strcpy_s(remcomOutBuffer, BUFMAX, "E01");
}
break;
/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
case 'M':
/* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
if (hexToInt (&ptr, &addr))
if (*(ptr++) == ',')
if (hexToInt (&ptr, &length))
if (*(ptr++) == ':')
{
mem_err = 0;
hex2mem (ptr, (char *) addr, length, 1);
if (mem_err)
{
strcpy_s(remcomOutBuffer, BUFMAX, "E03");
debug_error ("memory fault");
}
else
{
strcpy_s(remcomOutBuffer, BUFMAX, "OK");
}
ptr = 0;
}
if (ptr)
{
strcpy_s(remcomOutBuffer, BUFMAX, "E02");
}
break;
/* cAA..AA Continue at address AA..AA(optional) */
/* sAA..AA Step one instruction from AA..AA(optional) */
case 's':
stepping = 1;
case 'c':
/* try to read optional parameter, pc unchanged if no parm */
if (hexToInt (&ptr, &addr))
registers[PC] = addr;
newPC = registers[PC];
/* clear the trace bit */
registers[PS] &= 0xfffffeff;
/* set the trace bit if we're stepping */
if (stepping)
registers[PS] |= 0x100;
#ifdef WIN32 //MF
return;
#else
_returnFromException (); /* this is a jump */
#endif
break;
/* kill the program */
case 'k': /* do nothing */
#if 0
/* Huh? This doesn't look like "nothing".
m68k-stub.c and sparc-stub.c don't have it. */
BREAKPOINT ();
#endif
break;
} /* switch */
/* reply to the request */
putpacket (remcomOutBuffer);
}
}
/* this function is used to set up exception handlers for tracing and
breakpoints */
void
set_debug_traps (void)
{
#ifndef WIN32 //MF
stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
exceptionHandler (0, _catchException0);
exceptionHandler (1, _catchException1);
exceptionHandler (3, _catchException3);
exceptionHandler (4, _catchException4);
exceptionHandler (5, _catchException5);
exceptionHandler (6, _catchException6);
exceptionHandler (7, _catchException7);
exceptionHandler (8, _catchException8);
exceptionHandler (9, _catchException9);
exceptionHandler (10, _catchException10);
exceptionHandler (11, _catchException11);
exceptionHandler (12, _catchException12);
exceptionHandler (13, _catchException13);
exceptionHandler (14, _catchException14);
exceptionHandler (16, _catchException16);
#endif // WIN32
initialized = 1;
}
/* This function will generate a breakpoint exception. It is used at the
beginning of a program to sync up with a debugger and can be used
otherwise as a quick means to stop program execution and "break" into
the debugger. */
void
breakpoint (void)
{
if (initialized)
BREAKPOINT ();
}
//
// debugger stub implementation for WIN32 applications
// M. Fuchs, 29.11.2003
//
#ifdef WIN32
#include <stdlib.h>
#include <errno.h>
#include "utility/utility.h"
int s_initial_breakpoint = 0;
#ifdef DEBUG_SERIAL
FILE* ser_port = NULL;
int init_gdb_connect()
{
//TODO: set up connection using serial communication port
ser_port = fopen("COM1:", "rwb");
return 1;
}
int getDebugChar()
{
return fgetc(ser_port);
}
void putDebugChar(int c)
{
fputc(c, ser_port);
}
#else // DEBUG_SERIAL
static LPTOP_LEVEL_EXCEPTION_FILTER s_prev_exc_handler = 0;
#define I386_EXCEPTION_CNT 17
LONG WINAPI exc_protection_handler(EXCEPTION_POINTERS* exc_info)
{
int exc_nr = exc_info->ExceptionRecord->ExceptionCode & 0xFFFF;
if (exc_nr < I386_EXCEPTION_CNT) {
//LOG(FmtString(TEXT("exc_protection_handler: Exception %x"), exc_nr));
if (exc_nr==11 || exc_nr==13 || exc_nr==14) {
if (mem_fault_routine)
mem_fault_routine();
}
++exc_info->ContextRecord->Eip;
}
return EXCEPTION_CONTINUE_EXECUTION;
}
LONG WINAPI exc_handler(EXCEPTION_POINTERS* exc_info)
{
int exc_nr = exc_info->ExceptionRecord->ExceptionCode & 0xFFFF;
if (exc_nr < I386_EXCEPTION_CNT) {
//LOG(FmtString("Exception %x", exc_nr));
//LOG(FmtString("EIP=%08X EFLAGS=%08X", exc_info->ContextRecord->Eip, exc_info->ContextRecord->EFlags));
// step over initial breakpoint
if (s_initial_breakpoint) {
s_initial_breakpoint = 0;
++exc_info->ContextRecord->Eip;
}
SetUnhandledExceptionFilter(exc_protection_handler);
win32_exception_handler(exc_info);
//LOG(FmtString("EIP=%08X EFLAGS=%08X", exc_info->ContextRecord->Eip, exc_info->ContextRecord->EFlags));
SetUnhandledExceptionFilter(exc_handler);
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
/* not needed because we use win32_exception_handler() instead of catchExceptionX()
void exceptionHandler(int exc_nr, void* exc_addr)
{
if (exc_nr>=0 && exc_nr<I386_EXCEPTION_CNT)
exc_handlers[exc_nr] = exc_addr;
}
*/
void disable_debugging()
{
if (s_prev_exc_handler) {
SetUnhandledExceptionFilter(s_prev_exc_handler);
s_prev_exc_handler = 0;
}
}
#include <winsock.h>
#ifdef _MSC_VER
#pragma comment(lib, "wsock32")
#endif
static int s_rem_fd = -1;
int init_gdb_connect()
{
SOCKADDR_IN srv_addr = {0};
SOCKADDR_IN rem_addr;
WSADATA wsa_data;
int srv_socket, rem_len;
s_prev_exc_handler = SetUnhandledExceptionFilter(exc_handler);
if (WSAStartup(MAKEWORD(2,2), &wsa_data)) {
fprintf(stderr, "WSAStartup() failed");
return 0;
}
srv_addr.sin_family = AF_INET;
srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
srv_addr.sin_port = htons(9999);
srv_socket = socket(PF_INET, SOCK_STREAM, 0);
if (srv_socket == -1) {
perror("socket()");
return 0;
}
if (bind(srv_socket, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) {
perror("bind()");
return 0;
}
if (listen(srv_socket, 4) == -1) {
perror("listen()");
return 0;
}
rem_len = sizeof(rem_addr);
for(;;) {
s_rem_fd = accept(srv_socket, (struct sockaddr*)&rem_addr, &rem_len);
if (s_rem_fd < 0) {
if (errno == EINTR)
continue;
perror("accept()");
return 0;
}
break;
}
return 1;
}
#endif // DEBUG_SERIAL
int getDebugChar()
{
char buffer[1024];
int r;
if (s_rem_fd == -1)
return EOF;
r = recv(s_rem_fd, buffer, 1, 0);
if (r == -1) {
perror("recv()");
LOG(TEXT("debugger connection broken"));
s_rem_fd = -1;
return EOF;
}
if (!r)
return EOF;
return buffer[0];
}
void putDebugChar(int c)
{
if (s_rem_fd != -1) {
const char buffer[] = {c};
if (!send(s_rem_fd, buffer, 1, 0)) {
perror("send()");
LOG(TEXT("debugger connection broken"));
exit(-1);
}
}
}
// start up GDB stub interface
int initialize_gdb_stub()
{
if (!init_gdb_connect())
return 0;
set_debug_traps();
s_initial_breakpoint = 1;
breakpoint();
return 1;
}
#endif // WIN32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -