From 61c37cee5da9d08b107ec331b1080f1982f5afa1 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 21 Apr 2000 03:04:35 +0000 Subject: * wince-stub.c (FREE): New macro. (mempool): Just free any buffer prior to reuse. Don't bother with realloc. (flag_single_step): New function. (skip_message): Detect "helpful" Windows CE messages and skip sending them to the host. (wait_for_debug_event): Use skip_message to avoid sending debug messages to the host. (dispatch): Prelimary implementation of single step detection. * wince.c: Rework SH single stepping code to be more consistent with other wince targets. (handle_output_debug_string): Allow first chance exceptions to come through since they seem to be all that we get on some versions of Windows CE. (check_for_step): New function, conditionally compiled based on target. (regptr): Delete obsolete function. (handle_exception): Detect illegal instructions. (get_child_debug_event): Return success only if event code matches target. (child_create_inferior): Reflect change to get_child_debug_event arguments. --- gdb/wince-stub.c | 137 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 40 deletions(-) (limited to 'gdb/wince-stub.c') diff --git a/gdb/wince-stub.c b/gdb/wince-stub.c index d20223c..ce872d8 100644 --- a/gdb/wince-stub.c +++ b/gdb/wince-stub.c @@ -28,12 +28,13 @@ #include #include "wince-stub.h" -#define MALLOC(n) (void *) LocalAlloc (LMEM_MOVEABLE, (UINT)(n)) +#define MALLOC(n) (void *) LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, (UINT)(n)) #define REALLOC(s, n) (void *) LocalReAlloc ((HLOCAL)(s), (UINT)(n), LMEM_MOVEABLE) +#define FREE(s) LocalFree ((HLOCAL)(s)) static int skip_next_id = 0; /* Don't read next API code from socket */ -/* v-style interface for handling varying argyment list error messages. +/* v-style interface for handling varying argument list error messages. Displays the error message in a dialog box and exits when user clicks on OK. */ static void @@ -56,6 +57,27 @@ stub_error (LPCWSTR fmt, ...) vstub_error (fmt, args); } +/* Allocate a limited pool of memory, reallocating over unused + buffers. This assumes that there will never be more than four + "buffers" required which, so far, is a safe assumption. */ +static LPVOID +mempool (unsigned int len) +{ + static int outn = -1; + static LPWSTR outs[4] = {NULL, NULL, NULL, NULL}; + + if (++outn >= (sizeof (outs) / sizeof (outs[0]))) + outn = 0; + + /* Allocate space for the converted string, reusing any previously allocated + space, if applicable. */ + if (outs[outn]) + FREE (outs[outn]); + outs[outn] = (LPWSTR) MALLOC (len); + + return outs[outn]; +} + /* Standard "oh well" can't communicate error. Someday this might attempt synchronization. */ static void @@ -88,28 +110,6 @@ sockwrite (LPCWSTR huh, int s, const void *str, size_t n) } } -/* Allocate a limited pool of memory, reallocating over unused - buffers. This assumes that there will never be more than four - "buffers" required which, so far, is a safe assumption. */ -static LPVOID -mempool (gdb_wince_len len) -{ - static int n = -1; - static LPWSTR outs[4] = {NULL /*, NULL, etc. */}; - - if (++n >= (sizeof (outs) / sizeof (outs[0]))) - n = 0; - - /* Allocate space for the converted string, reusing any previously allocated - space, if applicable. */ - if (outs[n]) - outs[n] = (LPWSTR) REALLOC (outs[n], len); - else - outs[n] = (LPWSTR) MALLOC (len); - - return outs[n]; -} - /* Get a an ID (possibly) and a DWORD from the host gdb. Don't bother with the id if the main loop has already read it. */ @@ -175,7 +175,7 @@ getmemory (LPCWSTR huh, int s, gdb_wince_id what, gdb_wince_len *inlen) *inlen = getlen (huh, s, what); - p = mempool (*inlen); /* FIXME: check for error */ + p = mempool ((unsigned int) *inlen); /* FIXME: check for error */ if ((gdb_wince_len) sockread (huh, s, p, *inlen) != *inlen) stub_error (L"error getting string from host."); @@ -269,6 +269,49 @@ terminate_process (int s) &res, sizeof (res)); } +static int stepped = 0; +/* Handle single step instruction. FIXME: unneded? */ +static void +flag_single_step (int s) +{ + stepped = 1; + skip_next_id = 0; +} + +struct skipper +{ + wchar_t *s; + int nskip; +} skippy[] = +{ + {L"Undefined Instruction:", 1}, + {L"Data Abort:", 2}, + {NULL, 0} +}; + +static int +skip_message (DEBUG_EVENT *ev) +{ + char s[80]; + DWORD nread; + struct skipper *skp; + int nbytes = ev->u.DebugString.nDebugStringLength; + + if (nbytes > sizeof(s)) + nbytes = sizeof(s); + + memset (s, 0, sizeof (s)); + if (!ReadProcessMemory (curproc, ev->u.DebugString.lpDebugStringData, + s, nbytes, &nread)) + return 0; + + for (skp = skippy; skp->s != NULL; skp++) + if (wcsncmp ((wchar_t *) s, skp->s, wcslen (skp->s)) == 0) + return skp->nskip; + + return 0; +} + /* Emulate WaitForDebugEvent. Returns the debug event on success. */ static void wait_for_debug_event (int s) @@ -276,10 +319,32 @@ wait_for_debug_event (int s) DWORD ms = getdword (L"WaitForDebugEvent ms", s, GDB_WAITFORDEBUGEVENT); gdb_wince_result res; DEBUG_EVENT ev; + static int skip_next = 0; + + for (;;) + { + res = WaitForDebugEvent (&ev, ms); + + if (ev.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) + { + if (skip_next) + { + skip_next--; + goto ignore; + } + if (skip_next = skip_message (&ev)) + goto ignore; + } + + putresult (L"WaitForDebugEvent event", res, s, GDB_WAITFORDEBUGEVENT, + &ev, sizeof (ev)); + break; + + ignore: + ContinueDebugEvent (ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE); + } - res = WaitForDebugEvent (&ev, ms); - putresult (L"WaitForDebugEvent event", res, s, GDB_WAITFORDEBUGEVENT, - &ev, sizeof (ev)); + return; } /* Emulate GetThreadContext. Returns CONTEXT structure on success. */ @@ -291,7 +356,7 @@ get_thread_context (int s) gdb_wince_result res; memset (&c, 0, sizeof (c)); - c.ContextFlags = getdword (L"GetThreadContext handle", s, GDB_GETTHREADCONTEXT); + c.ContextFlags = getdword (L"GetThreadContext flags", s, GDB_GETTHREADCONTEXT); res = (gdb_wince_result) GetThreadContext (h, &c); putresult (L"GetThreadContext data", res, s, GDB_GETTHREADCONTEXT, @@ -319,7 +384,7 @@ read_process_memory (int s) HANDLE h = gethandle (L"ReadProcessMemory handle", s, GDB_READPROCESSMEMORY); LPVOID p = getpvoid (L"ReadProcessMemory base", s, GDB_READPROCESSMEMORY); gdb_wince_len len = getlen (L"ReadProcessMemory size", s, GDB_READPROCESSMEMORY); - LPVOID buf = mempool ((gdb_wince_len) len); + LPVOID buf = mempool ((unsigned int) len); DWORD outlen; gdb_wince_result res; @@ -400,12 +465,6 @@ close_handle (int s) putresult (L"CloseHandle result", res, s, GDB_CLOSEHANDLE, &res, sizeof (res)); } -/* Handle single step instruction */ -static void -single_step (int s) -{ -} - /* Main loop for reading requests from gdb host on the socket. */ static void dispatch (int s) @@ -458,8 +517,8 @@ dispatch (int s) terminate_process (s); return; case GDB_SINGLESTEP: - single_step (s); - return; + flag_single_step (s); + break; default: { WCHAR buf[80]; @@ -495,8 +554,6 @@ WinMain (HINSTANCE hi, HINSTANCE hp, LPWSTR cmd, int show) wcstombs (host, whost, 80); /* Convert from UNICODE to ascii */ } - MessageBoxW (NULL, whost, L"GDB", MB_ICONERROR); - /* Winsock initialization. */ if (WSAStartup (MAKEWORD (1, 1), &wd)) stub_error (L"Couldn't initialize WINSOCK."); -- cgit v1.1