* win32-low.c (child_xfer_memory): Check if ReadProcessMemory
[deliverable/binutils-gdb.git] / gdb / gdbserver / win32-low.c
index 86e7e3572468c675210897980a0a183846c7a0fc..549c29f082558ae6ede647efce3c9e36cdcde380 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
 
@@ -32,7 +32,6 @@
 #include <imagehlp.h>
 #include <tlhelp32.h>
 #include <psapi.h>
-#include <sys/param.h>
 #include <process.h>
 
 #ifndef USE_WIN32API
@@ -74,7 +73,7 @@ static int attaching = 0;
 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;
@@ -87,12 +86,14 @@ static int soft_interrupt_requested = 0;
    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);
 
@@ -193,9 +194,6 @@ child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb)
   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);
@@ -280,21 +278,30 @@ static int
 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
@@ -308,7 +315,9 @@ child_init_thread_list (void)
 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;
@@ -319,7 +328,8 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
 
   memset (&current_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)
@@ -448,7 +458,7 @@ strwinerror (DWORD error)
       LocalFree (msgbuf);
     }
   else
-    sprintf (buf, "unknown win32 error (%ld)", error);
+    sprintf (buf, "unknown win32 error (%u)", (unsigned) error);
 
   SetLastError (lasterr);
   return buf;
@@ -513,7 +523,7 @@ static int
 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;
@@ -544,8 +554,7 @@ win32_create_inferior (char *program, char **program_args)
       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
 
@@ -835,7 +844,7 @@ win32_resume (struct thread_resume *resume_info, size_t n)
       step = 0;
     }
 
-  if (sig != TARGET_SIGNAL_0)
+  if (sig != GDB_SIGNAL_0)
     {
       if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
        {
@@ -847,7 +856,7 @@ win32_resume (struct thread_resume *resume_info, size_t n)
        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 (&current_event);
@@ -1232,55 +1241,55 @@ handle_exception (struct target_waitstatus *ourstatus)
     {
     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
@@ -1289,27 +1298,27 @@ handle_exception (struct target_waitstatus *ourstatus)
       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)
@@ -1317,11 +1326,11 @@ handle_exception (struct target_waitstatus *ourstatus)
          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"));
@@ -1379,7 +1388,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
 {
   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.  */
@@ -1452,7 +1461,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
     {
     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));
 
@@ -1465,7 +1474,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
 
     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,
@@ -1476,7 +1485,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
 
     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);
@@ -1510,7 +1519,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
 
     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;
@@ -1522,29 +1531,29 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
 
     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);
@@ -1553,7 +1562,7 @@ get_child_debug_event (struct target_waitstatus *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);
@@ -1561,10 +1570,10 @@ get_child_debug_event (struct target_waitstatus *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;
     }
 
This page took 0.029199 seconds and 4 git commands to generate.