/* Low level interface to Windows debugging, for gdbserver.
- Copyright (C) 2006-2012 Free Software Foundation, Inc.
+ Copyright (C) 2006-2013 Free Software Foundation, Inc.
Contributed by Leo Zayas. Based on "win32-nat.c" from GDB.
#include <imagehlp.h>
#include <tlhelp32.h>
#include <psapi.h>
-#include <sys/param.h>
#include <process.h>
#ifndef USE_WIN32API
static HANDLE current_process_handle = NULL;
static DWORD current_process_id = 0;
static DWORD main_thread_id = 0;
-static enum gdb_signal last_sig = TARGET_SIGNAL_0;
+static enum gdb_signal last_sig = GDB_SIGNAL_0;
/* The current debug event from WaitForDebugEvent. */
static DEBUG_EVENT current_event;
by suspending all the threads. */
static int faked_breakpoint = 0;
+const struct target_desc *win32_tdesc;
+
#define NUM_REGS (the_low_target.num_regs)
-typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId);
-typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
-typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE);
-typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
+typedef BOOL (WINAPI *winapi_DebugActiveProcessStop) (DWORD dwProcessId);
+typedef BOOL (WINAPI *winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
+typedef BOOL (WINAPI *winapi_DebugBreakProcess) (HANDLE);
+typedef BOOL (WINAPI *winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
static void win32_resume (struct thread_resume *resume_info, size_t n);
th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb;
add_thread (ptid, th);
- set_inferior_regcache_data ((struct thread_info *)
- find_inferior_id (&all_threads, ptid),
- new_register_cache ());
if (the_low_target.thread_added != NULL)
(*the_low_target.thread_added) (th);
child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
int write, struct target_ops *target)
{
- SIZE_T done;
+ BOOL success;
+ SIZE_T done = 0;
+ DWORD lasterror = 0;
uintptr_t addr = (uintptr_t) memaddr;
if (write)
{
- WriteProcessMemory (current_process_handle, (LPVOID) addr,
- (LPCVOID) our, len, &done);
+ success = WriteProcessMemory (current_process_handle, (LPVOID) addr,
+ (LPCVOID) our, len, &done);
+ if (!success)
+ lasterror = GetLastError ();
FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
}
else
{
- ReadProcessMemory (current_process_handle, (LPCVOID) addr, (LPVOID) our,
- len, &done);
+ success = ReadProcessMemory (current_process_handle, (LPCVOID) addr,
+ (LPVOID) our, len, &done);
+ if (!success)
+ lasterror = GetLastError ();
}
- return done;
+ if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0)
+ return done;
+ else
+ return success ? done : -1;
}
/* Clear out any old thread list and reinitialize it to a pristine
static void
do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
{
- last_sig = TARGET_SIGNAL_0;
+ struct process_info *proc;
+
+ last_sig = GDB_SIGNAL_0;
current_process_handle = proch;
current_process_id = pid;
memset (¤t_event, 0, sizeof (current_event));
- add_process (pid, attached);
+ proc = add_process (pid, attached);
+ proc->tdesc = win32_tdesc;
child_init_thread_list ();
if (the_low_target.initial_stuff != NULL)
LocalFree (msgbuf);
}
else
- sprintf (buf, "unknown win32 error (%ld)", error);
+ sprintf (buf, "unknown win32 error (%u)", (unsigned) error);
SetLastError (lasterr);
return buf;
win32_create_inferior (char *program, char **program_args)
{
#ifndef USE_WIN32API
- char real_path[MAXPATHLEN];
+ char real_path[PATH_MAX];
char *orig_path, *new_path, *path_ptr;
#endif
BOOL ret;
cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, new_path, size);
setenv ("PATH", new_path, 1);
}
- cygwin_conv_path (CCP_POSIX_TO_WIN_A, program, real_path,
- MAXPATHLEN);
+ cygwin_conv_path (CCP_POSIX_TO_WIN_A, program, real_path, PATH_MAX);
program = real_path;
#endif
step = 0;
}
- if (sig != TARGET_SIGNAL_0)
+ if (sig != GDB_SIGNAL_0)
{
if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
{
OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
}
- last_sig = TARGET_SIGNAL_0;
+ last_sig = GDB_SIGNAL_0;
/* Get context for the currently selected thread. */
ptid = debug_event_ptid (¤t_event);
{
case EXCEPTION_ACCESS_VIOLATION:
OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
- ourstatus->value.sig = TARGET_SIGNAL_SEGV;
+ ourstatus->value.sig = GDB_SIGNAL_SEGV;
break;
case STATUS_STACK_OVERFLOW:
OUTMSG2 (("STATUS_STACK_OVERFLOW"));
- ourstatus->value.sig = TARGET_SIGNAL_SEGV;
+ ourstatus->value.sig = GDB_SIGNAL_SEGV;
break;
case STATUS_FLOAT_DENORMAL_OPERAND:
OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case STATUS_FLOAT_INEXACT_RESULT:
OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case STATUS_FLOAT_INVALID_OPERATION:
OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case STATUS_FLOAT_OVERFLOW:
OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case STATUS_FLOAT_STACK_CHECK:
OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case STATUS_FLOAT_UNDERFLOW:
OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case STATUS_FLOAT_DIVIDE_BY_ZERO:
OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case STATUS_INTEGER_DIVIDE_BY_ZERO:
OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case STATUS_INTEGER_OVERFLOW:
OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
break;
case EXCEPTION_BREAKPOINT:
OUTMSG2 (("EXCEPTION_BREAKPOINT"));
- ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ ourstatus->value.sig = GDB_SIGNAL_TRAP;
#ifdef _WIN32_WCE
/* Remove the initial breakpoint. */
check_breakpoints ((CORE_ADDR) (long) current_event
break;
case DBG_CONTROL_C:
OUTMSG2 (("DBG_CONTROL_C"));
- ourstatus->value.sig = TARGET_SIGNAL_INT;
+ ourstatus->value.sig = GDB_SIGNAL_INT;
break;
case DBG_CONTROL_BREAK:
OUTMSG2 (("DBG_CONTROL_BREAK"));
- ourstatus->value.sig = TARGET_SIGNAL_INT;
+ ourstatus->value.sig = GDB_SIGNAL_INT;
break;
case EXCEPTION_SINGLE_STEP:
OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
- ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ ourstatus->value.sig = GDB_SIGNAL_TRAP;
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
- ourstatus->value.sig = TARGET_SIGNAL_ILL;
+ ourstatus->value.sig = GDB_SIGNAL_ILL;
break;
case EXCEPTION_PRIV_INSTRUCTION:
OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
- ourstatus->value.sig = TARGET_SIGNAL_ILL;
+ ourstatus->value.sig = GDB_SIGNAL_ILL;
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
- ourstatus->value.sig = TARGET_SIGNAL_ILL;
+ ourstatus->value.sig = GDB_SIGNAL_ILL;
break;
default:
if (current_event.u.Exception.dwFirstChance)
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
return;
}
- OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%s",
- current_event.u.Exception.ExceptionRecord.ExceptionCode,
- phex_nz ((uintptr_t) current_event.u.Exception.ExceptionRecord.
- ExceptionAddress, sizeof (uintptr_t))));
- ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ OUTMSG2 (("gdbserver: unknown target exception 0x%08x at 0x%s",
+ (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
+ phex_nz ((uintptr_t) current_event.u.Exception.ExceptionRecord.
+ ExceptionAddress, sizeof (uintptr_t))));
+ ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
break;
}
OUTMSG2 (("\n"));
{
ptid_t ptid;
- last_sig = TARGET_SIGNAL_0;
+ last_sig = GDB_SIGNAL_0;
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
/* Check if GDB sent us an interrupt request. */
{
case CREATE_THREAD_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
- "for pid=%d tid=%x)\n",
+ "for pid=%u tid=%x)\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
case EXIT_THREAD_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
+ "for pid=%u tid=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
child_delete_thread (current_event.dwProcessId,
case CREATE_PROCESS_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
+ "for pid=%u tid=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
CloseHandle (current_event.u.CreateProcessInfo.hFile);
case EXIT_PROCESS_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
+ "for pid=%u tid=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
ourstatus->kind = TARGET_WAITKIND_EXITED;
case LOAD_DLL_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
+ "for pid=%u tid=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
CloseHandle (current_event.u.LoadDll.hFile);
handle_load_dll ();
ourstatus->kind = TARGET_WAITKIND_LOADED;
- ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ ourstatus->value.sig = GDB_SIGNAL_TRAP;
break;
case UNLOAD_DLL_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
+ "for pid=%u tid=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
handle_unload_dll ();
ourstatus->kind = TARGET_WAITKIND_LOADED;
- ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ ourstatus->value.sig = GDB_SIGNAL_TRAP;
break;
case EXCEPTION_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
+ "for pid=%u tid=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
handle_exception (ourstatus);
case OUTPUT_DEBUG_STRING_EVENT:
/* A message from the kernel (or Cygwin). */
OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
- "for pid=%d tid=%x\n",
+ "for pid=%u tid=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
handle_output_debug_string (ourstatus);
default:
OUTMSG2 (("gdbserver: kernel event unknown "
- "for pid=%d tid=%x code=%ld\n",
+ "for pid=%u tid=%x code=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
- current_event.dwDebugEventCode));
+ (unsigned) current_event.dwDebugEventCode));
break;
}