GDBserver
win32-low.c
Go to the documentation of this file.
1 /* Low level interface to Windows debugging, for gdbserver.
2  Copyright (C) 2006-2015 Free Software Foundation, Inc.
3 
4  Contributed by Leo Zayas. Based on "win32-nat.c" from GDB.
5 
6  This file is part of GDB.
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 
21 #include "server.h"
22 #include "regcache.h"
23 #include "gdb/fileio.h"
24 #include "mem-break.h"
25 #include "win32-low.h"
26 #include "gdbthread.h"
27 #include "dll.h"
28 #include "hostio.h"
29 #include <windows.h>
30 #include <winnt.h>
31 #include <imagehlp.h>
32 #include <tlhelp32.h>
33 #include <psapi.h>
34 #include <process.h>
35 
36 #ifndef USE_WIN32API
37 #include <sys/cygwin.h>
38 #endif
39 
40 #define OUTMSG(X) do { printf X; fflush (stderr); } while (0)
41 
42 #define OUTMSG2(X) \
43  do \
44  { \
45  if (debug_threads) \
46  { \
47  printf X; \
48  fflush (stderr); \
49  } \
50  } while (0)
51 
52 #ifndef _T
53 #define _T(x) TEXT (x)
54 #endif
55 
56 #ifndef COUNTOF
57 #define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
58 #endif
59 
60 #ifdef _WIN32_WCE
61 # define GETPROCADDRESS(DLL, PROC) \
62  ((winapi_ ## PROC) GetProcAddress (DLL, TEXT (#PROC)))
63 #else
64 # define GETPROCADDRESS(DLL, PROC) \
65  ((winapi_ ## PROC) GetProcAddress (DLL, #PROC))
66 #endif
67 
68 int using_threads = 1;
69 
70 /* Globals. */
71 static int attaching = 0;
72 static HANDLE current_process_handle = NULL;
73 static DWORD current_process_id = 0;
74 static DWORD main_thread_id = 0;
75 static enum gdb_signal last_sig = GDB_SIGNAL_0;
76 
77 /* The current debug event from WaitForDebugEvent. */
78 static DEBUG_EVENT current_event;
79 
80 /* A status that hasn't been reported to the core yet, and so
81  win32_wait should return it next, instead of fetching the next
82  debug event off the win32 API. */
83 static struct target_waitstatus cached_status;
84 
85 /* Non zero if an interrupt request is to be satisfied by suspending
86  all threads. */
87 static int soft_interrupt_requested = 0;
88 
89 /* Non zero if the inferior is stopped in a simulated breakpoint done
90  by suspending all the threads. */
91 static int faked_breakpoint = 0;
92 
93 const struct target_desc *win32_tdesc;
94 
95 #define NUM_REGS (the_low_target.num_regs)
96 
97 typedef BOOL (WINAPI *winapi_DebugActiveProcessStop) (DWORD dwProcessId);
98 typedef BOOL (WINAPI *winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
99 typedef BOOL (WINAPI *winapi_DebugBreakProcess) (HANDLE);
100 typedef BOOL (WINAPI *winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
101 
102 static ptid_t win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus,
103  int options);
104 static void win32_resume (struct thread_resume *resume_info, size_t n);
105 #ifndef _WIN32_WCE
106 static void win32_add_all_dlls (void);
107 #endif
108 
109 /* Get the thread ID from the current selected inferior (the current
110  thread). */
111 static ptid_t
113 {
114  return current_ptid;
115 }
116 
117 /* The current debug event from WaitForDebugEvent. */
118 static ptid_t
119 debug_event_ptid (DEBUG_EVENT *event)
120 {
121  return ptid_build (event->dwProcessId, event->dwThreadId, 0);
122 }
123 
124 /* Get the thread context of the thread associated with TH. */
125 
126 static void
128 {
129  memset (&th->context, 0, sizeof (CONTEXT));
130  (*the_low_target.get_thread_context) (th);
131 #ifdef _WIN32_WCE
132  memcpy (&th->base_context, &th->context, sizeof (CONTEXT));
133 #endif
134 }
135 
136 /* Set the thread context of the thread associated with TH. */
137 
138 static void
140 {
141 #ifdef _WIN32_WCE
142  /* Calling SuspendThread on a thread that is running kernel code
143  will report that the suspending was successful, but in fact, that
144  will often not be true. In those cases, the context returned by
145  GetThreadContext will not be correct by the time the thread
146  stops, hence we can't set that context back into the thread when
147  resuming - it will most likelly crash the inferior.
148  Unfortunately, there is no way to know when the thread will
149  really stop. To work around it, we'll only write the context
150  back to the thread when either the user or GDB explicitly change
151  it between stopping and resuming. */
152  if (memcmp (&th->context, &th->base_context, sizeof (CONTEXT)) != 0)
153 #endif
154  SetThreadContext (th->h, &th->context);
155 }
156 
157 /* Set the thread context of the thread associated with TH. */
158 
159 static void
161 {
162  if (the_low_target.prepare_to_resume != NULL)
164 }
165 
166 /* See win32-low.h. */
167 
168 void
170 {
171  if (th->context.ContextFlags == 0)
172  {
173  if (!th->suspended)
174  {
175  if (SuspendThread (th->h) == (DWORD) -1)
176  {
177  DWORD err = GetLastError ();
178  OUTMSG (("warning: SuspendThread failed in thread_rec, "
179  "(error %d): %s\n", (int) err, strwinerror (err)));
180  }
181  else
182  th->suspended = 1;
183  }
184 
186  }
187 }
188 
189 /* Find a thread record given a thread id. If GET_CONTEXT is set then
190  also retrieve the context for this thread. */
191 static win32_thread_info *
192 thread_rec (ptid_t ptid, int get_context)
193 {
194  struct thread_info *thread;
195  win32_thread_info *th;
196 
197  thread = (struct thread_info *) find_inferior_id (&all_threads, ptid);
198  if (thread == NULL)
199  return NULL;
200 
201  th = inferior_target_data (thread);
202  if (get_context)
204  return th;
205 }
206 
207 /* Add a thread to the thread list. */
208 static win32_thread_info *
209 child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb)
210 {
211  win32_thread_info *th;
212  ptid_t ptid = ptid_build (pid, tid, 0);
213 
214  if ((th = thread_rec (ptid, FALSE)))
215  return th;
216 
217  th = xcalloc (1, sizeof (*th));
218  th->tid = tid;
219  th->h = h;
220  th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb;
221 
222  add_thread (ptid, th);
223 
224  if (the_low_target.thread_added != NULL)
225  (*the_low_target.thread_added) (th);
226 
227  return th;
228 }
229 
230 /* Delete a thread from the list of threads. */
231 static void
233 {
234  win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);
235 
236  remove_thread ((struct thread_info *) thread);
237  CloseHandle (th->h);
238  free (th);
239 }
240 
241 /* Delete a thread from the list of threads. */
242 static void
243 child_delete_thread (DWORD pid, DWORD tid)
244 {
245  struct inferior_list_entry *thread;
246  ptid_t ptid;
247 
248  /* If the last thread is exiting, just return. */
250  return;
251 
252  ptid = ptid_build (pid, tid, 0);
253  thread = find_inferior_id (&all_threads, ptid);
254  if (thread == NULL)
255  return;
256 
257  delete_thread_info (thread);
258 }
259 
260 /* These watchpoint related wrapper functions simply pass on the function call
261  if the low target has registered a corresponding function. */
262 
263 static int
265 {
266  return (the_low_target.supports_z_point_type != NULL
268 }
269 
270 static int
272  int size, struct raw_breakpoint *bp)
273 {
274  if (the_low_target.insert_point != NULL)
275  return the_low_target.insert_point (type, addr, size, bp);
276  else
277  /* Unsupported (see target.h). */
278  return 1;
279 }
280 
281 static int
283  int size, struct raw_breakpoint *bp)
284 {
285  if (the_low_target.remove_point != NULL)
286  return the_low_target.remove_point (type, addr, size, bp);
287  else
288  /* Unsupported (see target.h). */
289  return 1;
290 }
291 
292 static int
294 {
297  else
298  return 0;
299 }
300 
301 static CORE_ADDR
303 {
306  else
307  return 0;
308 }
309 
310 
311 /* Transfer memory from/to the debugged process. */
312 static int
313 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
314  int write, struct target_ops *target)
315 {
316  BOOL success;
317  SIZE_T done = 0;
318  DWORD lasterror = 0;
319  uintptr_t addr = (uintptr_t) memaddr;
320 
321  if (write)
322  {
323  success = WriteProcessMemory (current_process_handle, (LPVOID) addr,
324  (LPCVOID) our, len, &done);
325  if (!success)
326  lasterror = GetLastError ();
327  FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
328  }
329  else
330  {
331  success = ReadProcessMemory (current_process_handle, (LPCVOID) addr,
332  (LPVOID) our, len, &done);
333  if (!success)
334  lasterror = GetLastError ();
335  }
336  if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0)
337  return done;
338  else
339  return success ? done : -1;
340 }
341 
342 /* Clear out any old thread list and reinitialize it to a pristine
343  state. */
344 static void
346 {
348 }
349 
350 /* Zero during the child initialization phase, and nonzero otherwise. */
351 
353 
354 static void
355 do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
356 {
357  struct process_info *proc;
358 
359  last_sig = GDB_SIGNAL_0;
360 
361  current_process_handle = proch;
362  current_process_id = pid;
363  main_thread_id = 0;
364 
365  soft_interrupt_requested = 0;
366  faked_breakpoint = 0;
367 
368  memset (&current_event, 0, sizeof (current_event));
369 
370  proc = add_process (pid, attached);
371  proc->tdesc = win32_tdesc;
373  child_initialization_done = 0;
374 
375  if (the_low_target.initial_stuff != NULL)
376  (*the_low_target.initial_stuff) ();
377 
378  cached_status.kind = TARGET_WAITKIND_IGNORE;
379 
380  /* Flush all currently pending debug events (thread and dll list) up
381  to the initial breakpoint. */
382  while (1)
383  {
384  struct target_waitstatus status;
385 
386  win32_wait (minus_one_ptid, &status, 0);
387 
388  /* Note win32_wait doesn't return thread events. */
389  if (status.kind != TARGET_WAITKIND_LOADED)
390  {
391  cached_status = status;
392  break;
393  }
394 
395  {
396  struct thread_resume resume;
397 
398  resume.thread = minus_one_ptid;
399  resume.kind = resume_continue;
400  resume.sig = 0;
401 
402  win32_resume (&resume, 1);
403  }
404  }
405 
406 #ifndef _WIN32_WCE
407  /* Now that the inferior has been started and all DLLs have been mapped,
408  we can iterate over all DLLs and load them in.
409 
410  We avoid doing it any earlier because, on certain versions of Windows,
411  LOAD_DLL_DEBUG_EVENTs are sometimes not complete. In particular,
412  we have seen on Windows 8.1 that the ntdll.dll load event does not
413  include the DLL name, preventing us from creating an associated SO.
414  A possible explanation is that ntdll.dll might be mapped before
415  the SO info gets created by the Windows system -- ntdll.dll is
416  the first DLL to be reported via LOAD_DLL_DEBUG_EVENT and other DLLs
417  do not seem to suffer from that problem.
418 
419  Rather than try to work around this sort of issue, it is much
420  simpler to just ignore DLL load/unload events during the startup
421  phase, and then process them all in one batch now. */
423 #endif
424 
425  child_initialization_done = 1;
426 }
427 
428 /* Resume all artificially suspended threads if we are continuing
429  execution. */
430 static int
431 continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
432 {
433  struct thread_info *thread = (struct thread_info *) this_thread;
434  int thread_id = * (int *) id_ptr;
436 
437  if (thread_id == -1 || thread_id == th->tid)
438  {
440 
441  if (th->suspended)
442  {
443  if (th->context.ContextFlags)
444  {
446  th->context.ContextFlags = 0;
447  }
448 
449  if (ResumeThread (th->h) == (DWORD) -1)
450  {
451  DWORD err = GetLastError ();
452  OUTMSG (("warning: ResumeThread failed in continue_one_thread, "
453  "(error %d): %s\n", (int) err, strwinerror (err)));
454  }
455  th->suspended = 0;
456  }
457  }
458 
459  return 0;
460 }
461 
462 static BOOL
463 child_continue (DWORD continue_status, int thread_id)
464 {
465  /* The inferior will only continue after the ContinueDebugEvent
466  call. */
468  faked_breakpoint = 0;
469 
470  if (!ContinueDebugEvent (current_event.dwProcessId,
471  current_event.dwThreadId,
472  continue_status))
473  return FALSE;
474 
475  return TRUE;
476 }
477 
478 /* Fetch register(s) from the current thread context. */
479 static void
481 {
482  int regno;
484  if (r == -1 || r > NUM_REGS)
486  else
487  for (regno = 0; regno < r; regno++)
488  (*the_low_target.fetch_inferior_register) (regcache, th, regno);
489 }
490 
491 /* Store a new register value into the current thread context. We don't
492  change the program's context until later, when we resume it. */
493 static void
495 {
496  int regno;
498  if (r == -1 || r == 0 || r > NUM_REGS)
500  else
501  for (regno = 0; regno < r; regno++)
502  (*the_low_target.store_inferior_register) (regcache, th, regno);
503 }
504 
505 /* Map the Windows error number in ERROR to a locale-dependent error
506  message string and return a pointer to it. Typically, the values
507  for ERROR come from GetLastError.
508 
509  The string pointed to shall not be modified by the application,
510  but may be overwritten by a subsequent call to strwinerror
511 
512  The strwinerror function does not change the current setting
513  of GetLastError. */
514 
515 char *
517 {
518  static char buf[1024];
519  TCHAR *msgbuf;
520  DWORD lasterr = GetLastError ();
521  DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
522  | FORMAT_MESSAGE_ALLOCATE_BUFFER,
523  NULL,
524  error,
525  0, /* Default language */
526  (LPVOID)&msgbuf,
527  0,
528  NULL);
529  if (chars != 0)
530  {
531  /* If there is an \r\n appended, zap it. */
532  if (chars >= 2
533  && msgbuf[chars - 2] == '\r'
534  && msgbuf[chars - 1] == '\n')
535  {
536  chars -= 2;
537  msgbuf[chars] = 0;
538  }
539 
540  if (chars > ((COUNTOF (buf)) - 1))
541  {
542  chars = COUNTOF (buf) - 1;
543  msgbuf [chars] = 0;
544  }
545 
546 #ifdef UNICODE
547  wcstombs (buf, msgbuf, chars + 1);
548 #else
549  strncpy (buf, msgbuf, chars + 1);
550 #endif
551  LocalFree (msgbuf);
552  }
553  else
554  sprintf (buf, "unknown win32 error (%u)", (unsigned) error);
555 
556  SetLastError (lasterr);
557  return buf;
558 }
559 
560 static BOOL
561 create_process (const char *program, char *args,
562  DWORD flags, PROCESS_INFORMATION *pi)
563 {
564  BOOL ret;
565 
566 #ifdef _WIN32_WCE
567  wchar_t *p, *wprogram, *wargs;
568  size_t argslen;
569 
570  wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t));
571  mbstowcs (wprogram, program, strlen (program) + 1);
572 
573  for (p = wprogram; *p; ++p)
574  if (L'/' == *p)
575  *p = L'\\';
576 
577  argslen = strlen (args);
578  wargs = alloca ((argslen + 1) * sizeof (wchar_t));
579  mbstowcs (wargs, args, argslen + 1);
580 
581  ret = CreateProcessW (wprogram, /* image name */
582  wargs, /* command line */
583  NULL, /* security, not supported */
584  NULL, /* thread, not supported */
585  FALSE, /* inherit handles, not supported */
586  flags, /* start flags */
587  NULL, /* environment, not supported */
588  NULL, /* current directory, not supported */
589  NULL, /* start info, not supported */
590  pi); /* proc info */
591 #else
592  STARTUPINFOA si = { sizeof (STARTUPINFOA) };
593 
594  ret = CreateProcessA (program, /* image name */
595  args, /* command line */
596  NULL, /* security */
597  NULL, /* thread */
598  TRUE, /* inherit handles */
599  flags, /* start flags */
600  NULL, /* environment */
601  NULL, /* current directory */
602  &si, /* start info */
603  pi); /* proc info */
604 #endif
605 
606  return ret;
607 }
608 
609 /* Start a new process.
610  PROGRAM is a path to the program to execute.
611  ARGS is a standard NULL-terminated array of arguments,
612  to be passed to the inferior as ``argv''.
613  Returns the new PID on success, -1 on failure. Registers the new
614  process with the process list. */
615 static int
616 win32_create_inferior (char *program, char **program_args)
617 {
618 #ifndef USE_WIN32API
619  char real_path[PATH_MAX];
620  char *orig_path, *new_path, *path_ptr;
621 #endif
622  BOOL ret;
623  DWORD flags;
624  char *args;
625  int argslen;
626  int argc;
627  PROCESS_INFORMATION pi;
628  DWORD err;
629 
630  /* win32_wait needs to know we're not attaching. */
631  attaching = 0;
632 
633  if (!program)
634  error ("No executable specified, specify executable to debug.\n");
635 
636  flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
637 
638 #ifndef USE_WIN32API
639  orig_path = NULL;
640  path_ptr = getenv ("PATH");
641  if (path_ptr)
642  {
643  int size = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, NULL, 0);
644  orig_path = alloca (strlen (path_ptr) + 1);
645  new_path = alloca (size);
646  strcpy (orig_path, path_ptr);
647  cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, new_path, size);
648  setenv ("PATH", new_path, 1);
649  }
650  cygwin_conv_path (CCP_POSIX_TO_WIN_A, program, real_path, PATH_MAX);
651  program = real_path;
652 #endif
653 
654  argslen = 1;
655  for (argc = 1; program_args[argc]; argc++)
656  argslen += strlen (program_args[argc]) + 1;
657  args = alloca (argslen);
658  args[0] = '\0';
659  for (argc = 1; program_args[argc]; argc++)
660  {
661  /* FIXME: Can we do better about quoting? How does Cygwin
662  handle this? */
663  strcat (args, " ");
664  strcat (args, program_args[argc]);
665  }
666  OUTMSG2 (("Command line is \"%s\"\n", args));
667 
668 #ifdef CREATE_NEW_PROCESS_GROUP
669  flags |= CREATE_NEW_PROCESS_GROUP;
670 #endif
671 
672  ret = create_process (program, args, flags, &pi);
673  err = GetLastError ();
674  if (!ret && err == ERROR_FILE_NOT_FOUND)
675  {
676  char *exename = alloca (strlen (program) + 5);
677  strcat (strcpy (exename, program), ".exe");
678  ret = create_process (exename, args, flags, &pi);
679  err = GetLastError ();
680  }
681 
682 #ifndef USE_WIN32API
683  if (orig_path)
684  setenv ("PATH", orig_path, 1);
685 #endif
686 
687  if (!ret)
688  {
689  error ("Error creating process \"%s%s\", (error %d): %s\n",
690  program, args, (int) err, strwinerror (err));
691  }
692  else
693  {
694  OUTMSG2 (("Process created: %s\n", (char *) args));
695  }
696 
697 #ifndef _WIN32_WCE
698  /* On Windows CE this handle can't be closed. The OS reuses
699  it in the debug events, while the 9x/NT versions of Windows
700  probably use a DuplicateHandle'd one. */
701  CloseHandle (pi.hThread);
702 #endif
703 
704  do_initial_child_stuff (pi.hProcess, pi.dwProcessId, 0);
705 
706  return current_process_id;
707 }
708 
709 /* Attach to a running process.
710  PID is the process ID to attach to, specified by the user
711  or a higher layer. */
712 static int
713 win32_attach (unsigned long pid)
714 {
715  HANDLE h;
716  winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
717  DWORD err;
718 #ifdef _WIN32_WCE
719  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
720 #else
721  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
722 #endif
723  DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
724 
725  h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
726  if (h != NULL)
727  {
728  if (DebugActiveProcess (pid))
729  {
730  if (DebugSetProcessKillOnExit != NULL)
731  DebugSetProcessKillOnExit (FALSE);
732 
733  /* win32_wait needs to know we're attaching. */
734  attaching = 1;
735  do_initial_child_stuff (h, pid, 1);
736  return 0;
737  }
738 
739  CloseHandle (h);
740  }
741 
742  err = GetLastError ();
743  error ("Attach to process failed (error %d): %s\n",
744  (int) err, strwinerror (err));
745 }
746 
747 /* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */
748 static void
749 handle_output_debug_string (struct target_waitstatus *ourstatus)
750 {
751 #define READ_BUFFER_LEN 1024
752  CORE_ADDR addr;
753  char s[READ_BUFFER_LEN + 1] = { 0 };
754  DWORD nbytes = current_event.u.DebugString.nDebugStringLength;
755 
756  if (nbytes == 0)
757  return;
758 
759  if (nbytes > READ_BUFFER_LEN)
760  nbytes = READ_BUFFER_LEN;
761 
762  addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData;
763 
764  if (current_event.u.DebugString.fUnicode)
765  {
766  /* The event tells us how many bytes, not chars, even
767  in Unicode. */
768  WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 };
769  if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0)
770  return;
771  wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR));
772  }
773  else
774  {
775  if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0)
776  return;
777  }
778 
779  if (!startswith (s, "cYg"))
780  {
781  if (!server_waiting)
782  {
783  OUTMSG2(("%s", s));
784  return;
785  }
786 
787  monitor_output (s);
788  }
789 #undef READ_BUFFER_LEN
790 }
791 
792 static void
794 {
795  if (current_process_handle != NULL)
796  CloseHandle (current_process_handle);
797 
799  clear_inferiors ();
800 }
801 
802 /* Kill all inferiors. */
803 static int
804 win32_kill (int pid)
805 {
806  struct process_info *process;
807 
808  if (current_process_handle == NULL)
809  return -1;
810 
811  TerminateProcess (current_process_handle, 0);
812  for (;;)
813  {
814  if (!child_continue (DBG_CONTINUE, -1))
815  break;
816  if (!WaitForDebugEvent (&current_event, INFINITE))
817  break;
818  if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
819  break;
820  else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
821  {
822  struct target_waitstatus our_status = { 0 };
823  handle_output_debug_string (&our_status);
824  }
825  }
826 
828 
829  process = find_process_pid (pid);
830  remove_process (process);
831  return 0;
832 }
833 
834 /* Detach from inferior PID. */
835 static int
836 win32_detach (int pid)
837 {
838  struct process_info *process;
839  winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
840  winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
841 #ifdef _WIN32_WCE
842  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
843 #else
844  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
845 #endif
846  DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
847  DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
848 
849  if (DebugSetProcessKillOnExit == NULL
850  || DebugActiveProcessStop == NULL)
851  return -1;
852 
853  {
854  struct thread_resume resume;
855  resume.thread = minus_one_ptid;
856  resume.kind = resume_continue;
857  resume.sig = 0;
858  win32_resume (&resume, 1);
859  }
860 
861  if (!DebugActiveProcessStop (current_process_id))
862  return -1;
863 
864  DebugSetProcessKillOnExit (FALSE);
865  process = find_process_pid (pid);
866  remove_process (process);
867 
869  return 0;
870 }
871 
872 static void
873 win32_mourn (struct process_info *process)
874 {
875  remove_process (process);
876 }
877 
878 /* Wait for inferiors to end. */
879 static void
880 win32_join (int pid)
881 {
882  HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
883  if (h != NULL)
884  {
885  WaitForSingleObject (h, INFINITE);
886  CloseHandle (h);
887  }
888 }
889 
890 /* Return 1 iff the thread with thread ID TID is alive. */
891 static int
893 {
894  int res;
895 
896  /* Our thread list is reliable; don't bother to poll target
897  threads. */
898  if (find_inferior_id (&all_threads, ptid) != NULL)
899  res = 1;
900  else
901  res = 0;
902  return res;
903 }
904 
905 /* Resume the inferior process. RESUME_INFO describes how we want
906  to resume. */
907 static void
908 win32_resume (struct thread_resume *resume_info, size_t n)
909 {
910  DWORD tid;
911  enum gdb_signal sig;
912  int step;
913  win32_thread_info *th;
914  DWORD continue_status = DBG_CONTINUE;
915  ptid_t ptid;
916 
917  /* This handles the very limited set of resume packets that GDB can
918  currently produce. */
919 
920  if (n == 1 && ptid_equal (resume_info[0].thread, minus_one_ptid))
921  tid = -1;
922  else if (n > 1)
923  tid = -1;
924  else
925  /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
926  the Windows resume code do the right thing for thread switching. */
927  tid = current_event.dwThreadId;
928 
929  if (!ptid_equal (resume_info[0].thread, minus_one_ptid))
930  {
931  sig = resume_info[0].sig;
932  step = resume_info[0].kind == resume_step;
933  }
934  else
935  {
936  sig = 0;
937  step = 0;
938  }
939 
940  if (sig != GDB_SIGNAL_0)
941  {
942  if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
943  {
944  OUTMSG (("Cannot continue with signal %d here.\n", sig));
945  }
946  else if (sig == last_sig)
947  continue_status = DBG_EXCEPTION_NOT_HANDLED;
948  else
949  OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
950  }
951 
952  last_sig = GDB_SIGNAL_0;
953 
954  /* Get context for the currently selected thread. */
955  ptid = debug_event_ptid (&current_event);
956  th = thread_rec (ptid, FALSE);
957  if (th)
958  {
960 
961  if (th->context.ContextFlags)
962  {
963  /* Move register values from the inferior into the thread
964  context structure. */
966 
967  if (step)
968  {
969  if (the_low_target.single_step != NULL)
970  (*the_low_target.single_step) (th);
971  else
972  error ("Single stepping is not supported "
973  "in this configuration.\n");
974  }
975 
977  th->context.ContextFlags = 0;
978  }
979  }
980 
981  /* Allow continuing with the same signal that interrupted us.
982  Otherwise complain. */
983 
984  child_continue (continue_status, tid);
985 }
986 
987 static void
988 win32_add_one_solib (const char *name, CORE_ADDR load_addr)
989 {
990  char buf[MAX_PATH + 1];
991  char buf2[MAX_PATH + 1];
992 
993 #ifdef _WIN32_WCE
994  WIN32_FIND_DATA w32_fd;
995  WCHAR wname[MAX_PATH + 1];
996  mbstowcs (wname, name, MAX_PATH);
997  HANDLE h = FindFirstFile (wname, &w32_fd);
998 #else
999  WIN32_FIND_DATAA w32_fd;
1000  HANDLE h = FindFirstFileA (name, &w32_fd);
1001 #endif
1002 
1003  /* The symbols in a dll are offset by 0x1000, which is the
1004  offset from 0 of the first byte in an image - because
1005  of the file header and the section alignment. */
1006  load_addr += 0x1000;
1007 
1008  if (h == INVALID_HANDLE_VALUE)
1009  strcpy (buf, name);
1010  else
1011  {
1012  FindClose (h);
1013  strcpy (buf, name);
1014 #ifndef _WIN32_WCE
1015  {
1016  char cwd[MAX_PATH + 1];
1017  char *p;
1018  if (GetCurrentDirectoryA (MAX_PATH + 1, cwd))
1019  {
1020  p = strrchr (buf, '\\');
1021  if (p)
1022  p[1] = '\0';
1023  SetCurrentDirectoryA (buf);
1024  GetFullPathNameA (w32_fd.cFileName, MAX_PATH, buf, &p);
1025  SetCurrentDirectoryA (cwd);
1026  }
1027  }
1028 #endif
1029  }
1030 
1031 #ifndef _WIN32_WCE
1032  if (strcasecmp (buf, "ntdll.dll") == 0)
1033  {
1034  GetSystemDirectoryA (buf, sizeof (buf));
1035  strcat (buf, "\\ntdll.dll");
1036  }
1037 #endif
1038 
1039 #ifdef __CYGWIN__
1040  cygwin_conv_path (CCP_WIN_A_TO_POSIX, buf, buf2, sizeof (buf2));
1041 #else
1042  strcpy (buf2, buf);
1043 #endif
1044 
1045  loaded_dll (buf2, load_addr);
1046 }
1047 
1048 static char *
1049 get_image_name (HANDLE h, void *address, int unicode)
1050 {
1051  static char buf[(2 * MAX_PATH) + 1];
1052  DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
1053  char *address_ptr;
1054  int len = 0;
1055  char b[2];
1056  SIZE_T done;
1057 
1058  /* Attempt to read the name of the dll that was detected.
1059  This is documented to work only when actively debugging
1060  a program. It will not work for attached processes. */
1061  if (address == NULL)
1062  return NULL;
1063 
1064 #ifdef _WIN32_WCE
1065  /* Windows CE reports the address of the image name,
1066  instead of an address of a pointer into the image name. */
1067  address_ptr = address;
1068 #else
1069  /* See if we could read the address of a string, and that the
1070  address isn't null. */
1071  if (!ReadProcessMemory (h, address, &address_ptr,
1072  sizeof (address_ptr), &done)
1073  || done != sizeof (address_ptr)
1074  || !address_ptr)
1075  return NULL;
1076 #endif
1077 
1078  /* Find the length of the string */
1079  while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
1080  && (b[0] != 0 || b[size - 1] != 0) && done == size)
1081  continue;
1082 
1083  if (!unicode)
1084  ReadProcessMemory (h, address_ptr, buf, len, &done);
1085  else
1086  {
1087  WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
1088  ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
1089  &done);
1090 
1091  WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
1092  }
1093 
1094  return buf;
1095 }
1096 
1097 typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *,
1098  DWORD, LPDWORD);
1099 typedef BOOL (WINAPI *winapi_GetModuleInformation) (HANDLE, HMODULE,
1100  LPMODULEINFO, DWORD);
1101 typedef DWORD (WINAPI *winapi_GetModuleFileNameExA) (HANDLE, HMODULE,
1102  LPSTR, DWORD);
1103 
1104 static winapi_EnumProcessModules win32_EnumProcessModules;
1105 static winapi_GetModuleInformation win32_GetModuleInformation;
1106 static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA;
1107 
1108 static BOOL
1110 {
1111  static int psapi_loaded = 0;
1112  static HMODULE dll = NULL;
1113 
1114  if (!psapi_loaded)
1115  {
1116  psapi_loaded = 1;
1117  dll = LoadLibrary (TEXT("psapi.dll"));
1118  if (!dll)
1119  return FALSE;
1120  win32_EnumProcessModules =
1121  GETPROCADDRESS (dll, EnumProcessModules);
1122  win32_GetModuleInformation =
1123  GETPROCADDRESS (dll, GetModuleInformation);
1124  win32_GetModuleFileNameExA =
1125  GETPROCADDRESS (dll, GetModuleFileNameExA);
1126  }
1127 
1128  return (win32_EnumProcessModules != NULL
1129  && win32_GetModuleInformation != NULL
1130  && win32_GetModuleFileNameExA != NULL);
1131 }
1132 
1133 #ifndef _WIN32_WCE
1134 
1135 /* Iterate over all DLLs currently mapped by our inferior, and
1136  add them to our list of solibs. */
1137 
1138 static void
1140 {
1141  size_t i;
1142  HMODULE dh_buf[1];
1143  HMODULE *DllHandle = dh_buf;
1144  DWORD cbNeeded;
1145  BOOL ok;
1146 
1147  if (!load_psapi ())
1148  return;
1149 
1150  cbNeeded = 0;
1151  ok = (*win32_EnumProcessModules) (current_process_handle,
1152  DllHandle,
1153  sizeof (HMODULE),
1154  &cbNeeded);
1155 
1156  if (!ok || !cbNeeded)
1157  return;
1158 
1159  DllHandle = (HMODULE *) alloca (cbNeeded);
1160  if (!DllHandle)
1161  return;
1162 
1163  ok = (*win32_EnumProcessModules) (current_process_handle,
1164  DllHandle,
1165  cbNeeded,
1166  &cbNeeded);
1167  if (!ok)
1168  return;
1169 
1170  for (i = 1; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++)
1171  {
1172  MODULEINFO mi;
1173  char dll_name[MAX_PATH];
1174 
1175  if (!(*win32_GetModuleInformation) (current_process_handle,
1176  DllHandle[i],
1177  &mi,
1178  sizeof (mi)))
1179  continue;
1180  if ((*win32_GetModuleFileNameExA) (current_process_handle,
1181  DllHandle[i],
1182  dll_name,
1183  MAX_PATH) == 0)
1184  continue;
1185  win32_add_one_solib (dll_name, (CORE_ADDR) (uintptr_t) mi.lpBaseOfDll);
1186  }
1187 }
1188 #endif
1189 
1190 typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD);
1191 typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32);
1192 typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32);
1193 
1194 /* Handle a DLL load event.
1195 
1196  This function assumes that this event did not occur during inferior
1197  initialization, where their event info may be incomplete (see
1198  do_initial_child_stuff and win32_add_all_dlls for more info on
1199  how we handle DLL loading during that phase). */
1200 
1201 static void
1203 {
1204  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
1205  char *dll_name;
1206 
1207  dll_name = get_image_name (current_process_handle,
1208  event->lpImageName, event->fUnicode);
1209  if (!dll_name)
1210  return;
1211 
1212  win32_add_one_solib (dll_name, (CORE_ADDR) (uintptr_t) event->lpBaseOfDll);
1213 }
1214 
1215 /* Handle a DLL unload event.
1216 
1217  This function assumes that this event did not occur during inferior
1218  initialization, where their event info may be incomplete (see
1219  do_initial_child_stuff and win32_add_one_solib for more info
1220  on how we handle DLL loading during that phase). */
1221 
1222 static void
1224 {
1225  CORE_ADDR load_addr =
1226  (CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll;
1227 
1228  /* The symbols in a dll are offset by 0x1000, which is the
1229  offset from 0 of the first byte in an image - because
1230  of the file header and the section alignment. */
1231  load_addr += 0x1000;
1232  unloaded_dll (NULL, load_addr);
1233 }
1234 
1235 static void
1236 handle_exception (struct target_waitstatus *ourstatus)
1237 {
1238  DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
1239 
1240  ourstatus->kind = TARGET_WAITKIND_STOPPED;
1241 
1242  switch (code)
1243  {
1244  case EXCEPTION_ACCESS_VIOLATION:
1245  OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
1246  ourstatus->value.sig = GDB_SIGNAL_SEGV;
1247  break;
1248  case STATUS_STACK_OVERFLOW:
1249  OUTMSG2 (("STATUS_STACK_OVERFLOW"));
1250  ourstatus->value.sig = GDB_SIGNAL_SEGV;
1251  break;
1252  case STATUS_FLOAT_DENORMAL_OPERAND:
1253  OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
1254  ourstatus->value.sig = GDB_SIGNAL_FPE;
1255  break;
1256  case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1257  OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
1258  ourstatus->value.sig = GDB_SIGNAL_FPE;
1259  break;
1260  case STATUS_FLOAT_INEXACT_RESULT:
1261  OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
1262  ourstatus->value.sig = GDB_SIGNAL_FPE;
1263  break;
1264  case STATUS_FLOAT_INVALID_OPERATION:
1265  OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
1266  ourstatus->value.sig = GDB_SIGNAL_FPE;
1267  break;
1268  case STATUS_FLOAT_OVERFLOW:
1269  OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
1270  ourstatus->value.sig = GDB_SIGNAL_FPE;
1271  break;
1272  case STATUS_FLOAT_STACK_CHECK:
1273  OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
1274  ourstatus->value.sig = GDB_SIGNAL_FPE;
1275  break;
1276  case STATUS_FLOAT_UNDERFLOW:
1277  OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
1278  ourstatus->value.sig = GDB_SIGNAL_FPE;
1279  break;
1280  case STATUS_FLOAT_DIVIDE_BY_ZERO:
1281  OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
1282  ourstatus->value.sig = GDB_SIGNAL_FPE;
1283  break;
1284  case STATUS_INTEGER_DIVIDE_BY_ZERO:
1285  OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
1286  ourstatus->value.sig = GDB_SIGNAL_FPE;
1287  break;
1288  case STATUS_INTEGER_OVERFLOW:
1289  OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
1290  ourstatus->value.sig = GDB_SIGNAL_FPE;
1291  break;
1292  case EXCEPTION_BREAKPOINT:
1293  OUTMSG2 (("EXCEPTION_BREAKPOINT"));
1294  ourstatus->value.sig = GDB_SIGNAL_TRAP;
1295 #ifdef _WIN32_WCE
1296  /* Remove the initial breakpoint. */
1297  check_breakpoints ((CORE_ADDR) (long) current_event
1298  .u.Exception.ExceptionRecord.ExceptionAddress);
1299 #endif
1300  break;
1301  case DBG_CONTROL_C:
1302  OUTMSG2 (("DBG_CONTROL_C"));
1303  ourstatus->value.sig = GDB_SIGNAL_INT;
1304  break;
1305  case DBG_CONTROL_BREAK:
1306  OUTMSG2 (("DBG_CONTROL_BREAK"));
1307  ourstatus->value.sig = GDB_SIGNAL_INT;
1308  break;
1309  case EXCEPTION_SINGLE_STEP:
1310  OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
1311  ourstatus->value.sig = GDB_SIGNAL_TRAP;
1312  break;
1313  case EXCEPTION_ILLEGAL_INSTRUCTION:
1314  OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
1315  ourstatus->value.sig = GDB_SIGNAL_ILL;
1316  break;
1317  case EXCEPTION_PRIV_INSTRUCTION:
1318  OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
1319  ourstatus->value.sig = GDB_SIGNAL_ILL;
1320  break;
1321  case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1322  OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
1323  ourstatus->value.sig = GDB_SIGNAL_ILL;
1324  break;
1325  default:
1326  if (current_event.u.Exception.dwFirstChance)
1327  {
1328  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1329  return;
1330  }
1331  OUTMSG2 (("gdbserver: unknown target exception 0x%08x at 0x%s",
1332  (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
1333  phex_nz ((uintptr_t) current_event.u.Exception.ExceptionRecord.
1334  ExceptionAddress, sizeof (uintptr_t))));
1335  ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
1336  break;
1337  }
1338  OUTMSG2 (("\n"));
1339  last_sig = ourstatus->value.sig;
1340 }
1341 
1342 
1343 static void
1345 {
1346  struct thread_info *thread = (struct thread_info *) entry;
1347  win32_thread_info *th = inferior_target_data (thread);
1348 
1349  if (!th->suspended)
1350  {
1351  if (SuspendThread (th->h) == (DWORD) -1)
1352  {
1353  DWORD err = GetLastError ();
1354  OUTMSG (("warning: SuspendThread failed in suspend_one_thread, "
1355  "(error %d): %s\n", (int) err, strwinerror (err)));
1356  }
1357  else
1358  th->suspended = 1;
1359  }
1360 }
1361 
1362 static void
1364 {
1365  OUTMSG2(("fake_breakpoint_event\n"));
1366 
1367  faked_breakpoint = 1;
1368 
1369  memset (&current_event, 0, sizeof (current_event));
1370  current_event.dwThreadId = main_thread_id;
1371  current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
1372  current_event.u.Exception.ExceptionRecord.ExceptionCode
1373  = EXCEPTION_BREAKPOINT;
1374 
1376 }
1377 
1378 #ifdef _WIN32_WCE
1379 static int
1380 auto_delete_breakpoint (CORE_ADDR stop_pc)
1381 {
1382  return 1;
1383 }
1384 #endif
1385 
1386 /* Get the next event from the child. */
1387 
1388 static int
1389 get_child_debug_event (struct target_waitstatus *ourstatus)
1390 {
1391  ptid_t ptid;
1392 
1393  last_sig = GDB_SIGNAL_0;
1394  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1395 
1396  /* Check if GDB sent us an interrupt request. */
1398 
1399  if (soft_interrupt_requested)
1400  {
1401  soft_interrupt_requested = 0;
1403  goto gotevent;
1404  }
1405 
1406 #ifndef _WIN32_WCE
1407  attaching = 0;
1408 #else
1409  if (attaching)
1410  {
1411  /* WinCE doesn't set an initial breakpoint automatically. To
1412  stop the inferior, we flush all currently pending debug
1413  events -- the thread list and the dll list are always
1414  reported immediatelly without delay, then, we suspend all
1415  threads and pretend we saw a trap at the current PC of the
1416  main thread.
1417 
1418  Contrary to desktop Windows, Windows CE *does* report the dll
1419  names on LOAD_DLL_DEBUG_EVENTs resulting from a
1420  DebugActiveProcess call. This limits the way we can detect
1421  if all the dlls have already been reported. If we get a real
1422  debug event before leaving attaching, the worst that will
1423  happen is the user will see a spurious breakpoint. */
1424 
1425  current_event.dwDebugEventCode = 0;
1426  if (!WaitForDebugEvent (&current_event, 0))
1427  {
1428  OUTMSG2(("no attach events left\n"));
1430  attaching = 0;
1431  }
1432  else
1433  OUTMSG2(("got attach event\n"));
1434  }
1435  else
1436 #endif
1437  {
1438  /* Keep the wait time low enough for confortable remote
1439  interruption, but high enough so gdbserver doesn't become a
1440  bottleneck. */
1441  if (!WaitForDebugEvent (&current_event, 250))
1442  {
1443  DWORD e = GetLastError();
1444 
1445  if (e == ERROR_PIPE_NOT_CONNECTED)
1446  {
1447  /* This will happen if the loader fails to succesfully
1448  load the application, e.g., if the main executable
1449  tries to pull in a non-existing export from a
1450  DLL. */
1451  ourstatus->kind = TARGET_WAITKIND_EXITED;
1452  ourstatus->value.integer = 1;
1453  return 1;
1454  }
1455 
1456  return 0;
1457  }
1458  }
1459 
1460  gotevent:
1461 
1462  switch (current_event.dwDebugEventCode)
1463  {
1464  case CREATE_THREAD_DEBUG_EVENT:
1465  OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
1466  "for pid=%u tid=%x)\n",
1467  (unsigned) current_event.dwProcessId,
1468  (unsigned) current_event.dwThreadId));
1469 
1470  /* Record the existence of this thread. */
1471  child_add_thread (current_event.dwProcessId,
1472  current_event.dwThreadId,
1473  current_event.u.CreateThread.hThread,
1474  current_event.u.CreateThread.lpThreadLocalBase);
1475  break;
1476 
1477  case EXIT_THREAD_DEBUG_EVENT:
1478  OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
1479  "for pid=%u tid=%x\n",
1480  (unsigned) current_event.dwProcessId,
1481  (unsigned) current_event.dwThreadId));
1482  child_delete_thread (current_event.dwProcessId,
1483  current_event.dwThreadId);
1484 
1486  return 1;
1487 
1488  case CREATE_PROCESS_DEBUG_EVENT:
1489  OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
1490  "for pid=%u tid=%x\n",
1491  (unsigned) current_event.dwProcessId,
1492  (unsigned) current_event.dwThreadId));
1493  CloseHandle (current_event.u.CreateProcessInfo.hFile);
1494 
1495  current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1496  main_thread_id = current_event.dwThreadId;
1497 
1498  ourstatus->kind = TARGET_WAITKIND_EXECD;
1499  ourstatus->value.execd_pathname = "Main executable";
1500 
1501  /* Add the main thread. */
1502  child_add_thread (current_event.dwProcessId,
1503  main_thread_id,
1504  current_event.u.CreateProcessInfo.hThread,
1505  current_event.u.CreateProcessInfo.lpThreadLocalBase);
1506 
1507  ourstatus->value.related_pid = debug_event_ptid (&current_event);
1508 #ifdef _WIN32_WCE
1509  if (!attaching)
1510  {
1511  /* Windows CE doesn't set the initial breakpoint
1512  automatically like the desktop versions of Windows do.
1513  We add it explicitly here. It will be removed as soon as
1514  it is hit. */
1515  set_breakpoint_at ((CORE_ADDR) (long) current_event.u
1516  .CreateProcessInfo.lpStartAddress,
1517  auto_delete_breakpoint);
1518  }
1519 #endif
1520  break;
1521 
1522  case EXIT_PROCESS_DEBUG_EVENT:
1523  OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
1524  "for pid=%u tid=%x\n",
1525  (unsigned) current_event.dwProcessId,
1526  (unsigned) current_event.dwThreadId));
1527  ourstatus->kind = TARGET_WAITKIND_EXITED;
1528  ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1529  child_continue (DBG_CONTINUE, -1);
1530  CloseHandle (current_process_handle);
1531  current_process_handle = NULL;
1532  break;
1533 
1534  case LOAD_DLL_DEBUG_EVENT:
1535  OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
1536  "for pid=%u tid=%x\n",
1537  (unsigned) current_event.dwProcessId,
1538  (unsigned) current_event.dwThreadId));
1539  CloseHandle (current_event.u.LoadDll.hFile);
1540  if (! child_initialization_done)
1541  break;
1542  handle_load_dll ();
1543 
1544  ourstatus->kind = TARGET_WAITKIND_LOADED;
1545  ourstatus->value.sig = GDB_SIGNAL_TRAP;
1546  break;
1547 
1548  case UNLOAD_DLL_DEBUG_EVENT:
1549  OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
1550  "for pid=%u tid=%x\n",
1551  (unsigned) current_event.dwProcessId,
1552  (unsigned) current_event.dwThreadId));
1553  if (! child_initialization_done)
1554  break;
1555  handle_unload_dll ();
1556  ourstatus->kind = TARGET_WAITKIND_LOADED;
1557  ourstatus->value.sig = GDB_SIGNAL_TRAP;
1558  break;
1559 
1560  case EXCEPTION_DEBUG_EVENT:
1561  OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
1562  "for pid=%u tid=%x\n",
1563  (unsigned) current_event.dwProcessId,
1564  (unsigned) current_event.dwThreadId));
1565  handle_exception (ourstatus);
1566  break;
1567 
1568  case OUTPUT_DEBUG_STRING_EVENT:
1569  /* A message from the kernel (or Cygwin). */
1570  OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
1571  "for pid=%u tid=%x\n",
1572  (unsigned) current_event.dwProcessId,
1573  (unsigned) current_event.dwThreadId));
1574  handle_output_debug_string (ourstatus);
1575  break;
1576 
1577  default:
1578  OUTMSG2 (("gdbserver: kernel event unknown "
1579  "for pid=%u tid=%x code=%x\n",
1580  (unsigned) current_event.dwProcessId,
1581  (unsigned) current_event.dwThreadId,
1582  (unsigned) current_event.dwDebugEventCode));
1583  break;
1584  }
1585 
1586  ptid = debug_event_ptid (&current_event);
1587  current_thread =
1588  (struct thread_info *) find_inferior_id (&all_threads, ptid);
1589  return 1;
1590 }
1591 
1592 /* Wait for the inferior process to change state.
1593  STATUS will be filled in with a response code to send to GDB.
1594  Returns the signal which caused the process to stop. */
1595 static ptid_t
1596 win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
1597 {
1598  struct regcache *regcache;
1599 
1600  if (cached_status.kind != TARGET_WAITKIND_IGNORE)
1601  {
1602  /* The core always does a wait after creating the inferior, and
1603  do_initial_child_stuff already ran the inferior to the
1604  initial breakpoint (or an exit, if creating the process
1605  fails). Report it now. */
1606  *ourstatus = cached_status;
1607  cached_status.kind = TARGET_WAITKIND_IGNORE;
1608  return debug_event_ptid (&current_event);
1609  }
1610 
1611  while (1)
1612  {
1613  if (!get_child_debug_event (ourstatus))
1614  continue;
1615 
1616  switch (ourstatus->kind)
1617  {
1618  case TARGET_WAITKIND_EXITED:
1619  OUTMSG2 (("Child exited with retcode = %x\n",
1620  ourstatus->value.integer));
1622  return pid_to_ptid (current_event.dwProcessId);
1623  case TARGET_WAITKIND_STOPPED:
1624  case TARGET_WAITKIND_LOADED:
1625  OUTMSG2 (("Child Stopped with signal = %d \n",
1626  ourstatus->value.sig));
1627 
1628  regcache = get_thread_regcache (current_thread, 1);
1629  child_fetch_inferior_registers (regcache, -1);
1630  return debug_event_ptid (&current_event);
1631  default:
1632  OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus->kind));
1633  /* fall-through */
1634  case TARGET_WAITKIND_SPURIOUS:
1635  case TARGET_WAITKIND_EXECD:
1636  /* do nothing, just continue */
1637  child_continue (DBG_CONTINUE, -1);
1638  break;
1639  }
1640  }
1641 }
1642 
1643 /* Fetch registers from the inferior process.
1644  If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
1645 static void
1647 {
1648  child_fetch_inferior_registers (regcache, regno);
1649 }
1650 
1651 /* Store registers to the inferior process.
1652  If REGNO is -1, store all registers; otherwise, store at least REGNO. */
1653 static void
1655 {
1656  child_store_inferior_registers (regcache, regno);
1657 }
1658 
1659 /* Read memory from the inferior process. This should generally be
1660  called through read_inferior_memory, which handles breakpoint shadowing.
1661  Read LEN bytes at MEMADDR into a buffer at MYADDR. */
1662 static int
1663 win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1664 {
1665  return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
1666 }
1667 
1668 /* Write memory to the inferior process. This should generally be
1669  called through write_inferior_memory, which handles breakpoint shadowing.
1670  Write LEN bytes from the buffer at MYADDR to MEMADDR.
1671  Returns 0 on success and errno on failure. */
1672 static int
1673 win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
1674  int len)
1675 {
1676  return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
1677 }
1678 
1679 /* Send an interrupt request to the inferior process. */
1680 static void
1682 {
1683  winapi_DebugBreakProcess DebugBreakProcess;
1684  winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent;
1685 
1686 #ifdef _WIN32_WCE
1687  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
1688 #else
1689  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
1690 #endif
1691 
1692  GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent);
1693 
1694  if (GenerateConsoleCtrlEvent != NULL
1695  && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id))
1696  return;
1697 
1698  /* GenerateConsoleCtrlEvent can fail if process id being debugged is
1699  not a process group id.
1700  Fallback to XP/Vista 'DebugBreakProcess', which generates a
1701  breakpoint exception in the interior process. */
1702 
1703  DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess);
1704 
1705  if (DebugBreakProcess != NULL
1706  && DebugBreakProcess (current_process_handle))
1707  return;
1708 
1709  /* Last resort, suspend all threads manually. */
1710  soft_interrupt_requested = 1;
1711 }
1712 
1713 #ifdef _WIN32_WCE
1714 int
1715 win32_error_to_fileio_error (DWORD err)
1716 {
1717  switch (err)
1718  {
1719  case ERROR_BAD_PATHNAME:
1720  case ERROR_FILE_NOT_FOUND:
1721  case ERROR_INVALID_NAME:
1722  case ERROR_PATH_NOT_FOUND:
1723  return FILEIO_ENOENT;
1724  case ERROR_CRC:
1725  case ERROR_IO_DEVICE:
1726  case ERROR_OPEN_FAILED:
1727  return FILEIO_EIO;
1728  case ERROR_INVALID_HANDLE:
1729  return FILEIO_EBADF;
1730  case ERROR_ACCESS_DENIED:
1731  case ERROR_SHARING_VIOLATION:
1732  return FILEIO_EACCES;
1733  case ERROR_NOACCESS:
1734  return FILEIO_EFAULT;
1735  case ERROR_BUSY:
1736  return FILEIO_EBUSY;
1737  case ERROR_ALREADY_EXISTS:
1738  case ERROR_FILE_EXISTS:
1739  return FILEIO_EEXIST;
1740  case ERROR_BAD_DEVICE:
1741  return FILEIO_ENODEV;
1742  case ERROR_DIRECTORY:
1743  return FILEIO_ENOTDIR;
1744  case ERROR_FILENAME_EXCED_RANGE:
1745  case ERROR_INVALID_DATA:
1746  case ERROR_INVALID_PARAMETER:
1747  case ERROR_NEGATIVE_SEEK:
1748  return FILEIO_EINVAL;
1749  case ERROR_TOO_MANY_OPEN_FILES:
1750  return FILEIO_EMFILE;
1751  case ERROR_HANDLE_DISK_FULL:
1752  case ERROR_DISK_FULL:
1753  return FILEIO_ENOSPC;
1754  case ERROR_WRITE_PROTECT:
1755  return FILEIO_EROFS;
1756  case ERROR_NOT_SUPPORTED:
1757  return FILEIO_ENOSYS;
1758  }
1759 
1760  return FILEIO_EUNKNOWN;
1761 }
1762 
1763 static void
1764 wince_hostio_last_error (char *buf)
1765 {
1766  DWORD winerr = GetLastError ();
1767  int fileio_err = win32_error_to_fileio_error (winerr);
1768  sprintf (buf, "F-1,%x", fileio_err);
1769 }
1770 #endif
1771 
1772 /* Write Windows OS Thread Information Block address. */
1773 
1774 static int
1776 {
1777  win32_thread_info *th;
1778  th = thread_rec (ptid, 0);
1779  if (th == NULL)
1780  return 0;
1781  if (addr != NULL)
1782  *addr = th->thread_local_base;
1783  return 1;
1784 }
1785 
1786 static struct target_ops win32_target_ops = {
1788  win32_attach,
1789  win32_kill,
1790  win32_detach,
1791  win32_mourn,
1792  win32_join,
1794  win32_resume,
1795  win32_wait,
1798  NULL, /* prepare_to_access_memory */
1799  NULL, /* done_accessing_memory */
1802  NULL, /* lookup_symbols */
1804  NULL, /* read_auxv */
1808  NULL, /* stopped_by_sw_breakpoint */
1809  NULL, /* supports_stopped_by_sw_breakpoint */
1810  NULL, /* stopped_by_hw_breakpoint */
1811  NULL, /* supports_stopped_by_hw_breakpoint */
1812  /* Although win32-i386 has hardware single step, still disable this
1813  feature for win32, because it is implemented in linux-low.c instead
1814  of in generic code. */
1815  NULL, /* supports_conditional_breakpoints */
1818  NULL, /* read_offsets */
1819  NULL, /* get_tls_address */
1820  NULL, /* qxfer_spu */
1821 #ifdef _WIN32_WCE
1822  wince_hostio_last_error,
1823 #else
1825 #endif
1826  NULL, /* qxfer_osdata */
1827  NULL, /* qxfer_siginfo */
1828  NULL, /* supports_non_stop */
1829  NULL, /* async */
1830  NULL, /* start_non_stop */
1831  NULL, /* supports_multi_process */
1832  NULL, /* supports_fork_events */
1833  NULL, /* supports_vfork_events */
1834  NULL, /* handle_new_gdb_connection */
1835  NULL, /* handle_monitor_command */
1836  NULL, /* core_of_thread */
1837  NULL, /* read_loadmap */
1838  NULL, /* process_qsupported */
1839  NULL, /* supports_tracepoints */
1840  NULL, /* read_pc */
1841  NULL, /* write_pc */
1842  NULL, /* thread_stopped */
1844 };
1845 
1846 /* Initialize the Win32 backend. */
1847 void
1849 {
1850  set_target_ops (&win32_target_ops);
1851  if (the_low_target.breakpoint != NULL)
1855 }
static winapi_GetModuleInformation win32_GetModuleInformation
Definition: win32-low.c:1105
static int win32_detach(int pid)
Definition: win32-low.c:836
struct thread_info * current_thread
Definition: inferiors.c:28
#define OUTMSG2(X)
Definition: win32-low.c:42
static void suspend_one_thread(struct inferior_list_entry *entry)
Definition: win32-low.c:1344
static DEBUG_EVENT current_event
Definition: win32-low.c:78
void monitor_output(const char *msg)
struct process_info * add_process(int pid, int attached)
Definition: inferiors.c:274
static void win32_add_all_dlls(void)
Definition: win32-low.c:1139
CORE_ADDR thread_local_base
Definition: win32-low.h:38
static ptid_t debug_event_ptid(DEBUG_EVENT *event)
Definition: win32-low.c:119
static int attaching
Definition: win32-low.c:71
int ptid_equal(ptid_t ptid1, ptid_t ptid2)
Definition: ptid.c:76
bfd_vma CORE_ADDR
Definition: common-types.h:41
int(* supports_z_point_type)(char z_type)
Definition: linux-low.h:158
static void child_delete_thread(DWORD pid, DWORD tid)
Definition: win32-low.c:243
static void win32_request_interrupt(void)
Definition: win32-low.c:1681
static int win32_create_inferior(char *program, char **program_args)
Definition: win32-low.c:616
static void win32_store_inferior_registers(struct regcache *regcache, int regno)
Definition: win32-low.c:1654
int server_waiting
Definition: server.c:50
struct process_info * find_process_pid(int pid)
Definition: inferiors.c:302
char * strwinerror(DWORD error)
Definition: win32-low.c:516
static BOOL load_psapi(void)
Definition: win32-low.c:1109
static void handle_exception(struct target_waitstatus *ourstatus)
Definition: win32-low.c:1236
static char * get_image_name(HANDLE h, void *address, int unicode)
Definition: win32-low.c:1049
static DWORD current_process_id
Definition: win32-low.c:73
static int win32_write_inferior_memory(CORE_ADDR memaddr, const unsigned char *myaddr, int len)
Definition: win32-low.c:1673
void for_each_inferior(struct inferior_list *list, void(*action)(struct inferior_list_entry *))
Definition: inferiors.c:47
const char * name
Definition: tracepoint.c:178
static void win32_clear_inferiors(void)
Definition: win32-low.c:793
int(* stopped_by_watchpoint)(void)
Definition: linux-low.h:164
void set_breakpoint_data(const unsigned char *bp_data, int bp_len)
Definition: mem-break.c:1592
struct linux_target_ops the_low_target
typedef BOOL(WINAPI *winapi_DebugActiveProcessStop)(DWORD dwProcessId)
static int soft_interrupt_requested
Definition: win32-low.c:87
static int child_initialization_done
Definition: win32-low.c:352
static void win32_fetch_inferior_registers(struct regcache *regcache, int regno)
Definition: win32-low.c:1646
static void win32_prepare_to_resume(win32_thread_info *th)
Definition: win32-low.c:160
const struct target_desc * tdesc
Definition: inferiors.h:69
const unsigned char * breakpoint
Definition: linux-low.h:149
void win32_require_context(win32_thread_info *th)
Definition: win32-low.c:169
int using_threads
Definition: win32-low.c:68
Definition: ptid.h:35
static void fake_breakpoint_event(void)
Definition: win32-low.c:1363
ptid_t ptid_build(int pid, long lwp, long tid)
Definition: ptid.c:31
void * inferior_target_data(struct thread_info *inferior)
Definition: inferiors.c:222
static void handle_load_dll(void)
Definition: win32-low.c:1202
static void child_fetch_inferior_registers(struct regcache *regcache, int r)
Definition: win32-low.c:480
static int faked_breakpoint
Definition: win32-low.c:91
#define _T(x)
Definition: win32-low.c:53
static int win32_attach(unsigned long pid)
Definition: win32-low.c:713
static void handle_unload_dll(void)
Definition: win32-low.c:1223
typedef LPSTR
Definition: win32-low.c:1101
HMODULE LPDWORD
Definition: win32-low.c:1097
raw_bkpt_type
Definition: mem-break.h:40
void regcache_invalidate(void)
Definition: regcache.c:111
#define NUM_REGS
Definition: win32-low.c:95
void initialize_low(void)
Definition: win32-low.c:1848
enum resume_kind kind
Definition: target.h:45
static winapi_EnumProcessModules win32_EnumProcessModules
Definition: win32-low.c:1104
HMODULE DWORD
Definition: win32-low.c:1097
static void win32_get_thread_context(win32_thread_info *th)
Definition: win32-low.c:127
int read_inferior_memory(CORE_ADDR memaddr, unsigned char *myaddr, int len)
Definition: target.c:43
ptid_t pid_to_ptid(int pid)
Definition: ptid.c:44
typedef LPMODULEENTRY32
Definition: win32-low.c:1191
#define current_ptid
Definition: gdbthread.h:83
static void win32_set_thread_context(win32_thread_info *th)
Definition: win32-low.c:139
static int win32_remove_point(enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp)
Definition: win32-low.c:282
static void delete_thread_info(struct inferior_list_entry *thread)
Definition: win32-low.c:232
void unloaded_dll(const char *name, CORE_ADDR base_addr)
Definition: dll.c:78
static int child_xfer_memory(CORE_ADDR memaddr, char *our, int len, int write, struct target_ops *target)
Definition: win32-low.c:313
static int win32_supports_z_point_type(char z_type)
Definition: win32-low.c:264
static int win32_read_inferior_memory(CORE_ADDR memaddr, unsigned char *myaddr, int len)
Definition: win32-low.c:1663
typedef LPMODULEINFO
Definition: win32-low.c:1099
static int startswith(const char *string, const char *pattern)
Definition: common-utils.h:75
CORE_ADDR(* stopped_data_address)(void)
Definition: linux-low.h:165
static int continue_one_thread(struct inferior_list_entry *this_thread, void *id_ptr)
Definition: win32-low.c:431
void check_breakpoints(CORE_ADDR stop_pc)
Definition: mem-break.c:1553
void remove_process(struct process_info *process)
Definition: inferiors.c:293
void set_target_ops(struct target_ops *target)
Definition: target.c:184
static win32_thread_info * thread_rec(ptid_t ptid, int get_context)
Definition: win32-low.c:192
static ptid_t win32_wait(ptid_t ptid, struct target_waitstatus *ourstatus, int options)
Definition: win32-low.c:1596
struct inferior_list_entry * head
Definition: inferiors.h:26
static void handle_output_debug_string(struct target_waitstatus *ourstatus)
Definition: win32-low.c:749
struct inferior_list all_threads
Definition: inferiors.c:26
typedef HMODULE
Definition: win32-low.c:1099
static ptid_t current_thread_ptid(void)
Definition: win32-low.c:112
static void child_init_thread_list(void)
Definition: win32-low.c:345
static struct target_waitstatus cached_status
Definition: win32-low.c:83
static BOOL create_process(const char *program, char *args, DWORD flags, PROCESS_INFORMATION *pi)
Definition: win32-low.c:561
static int win32_insert_point(enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp)
Definition: win32-low.c:271
int(* insert_point)(enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp)
Definition: linux-low.h:159
static int win32_kill(int pid)
Definition: win32-low.c:804
struct inferior_list_entry * find_inferior_id(struct inferior_list *list, ptid_t id)
Definition: inferiors.c:207
int(* remove_point)(enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp)
Definition: linux-low.h:161
#define GETPROCADDRESS(DLL, PROC)
Definition: win32-low.c:64
static int win32_thread_alive(ptid_t ptid)
Definition: win32-low.c:892
void(* prepare_to_resume)(struct lwp_info *)
Definition: linux-low.h:194
typedef HANDLE(WINAPI *winapi_CreateToolhelp32Snapshot)(DWORD
#define READ_BUFFER_LEN
static enum gdb_signal last_sig
Definition: win32-low.c:75
static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA
Definition: win32-low.c:1106
static int win32_stopped_by_watchpoint(void)
Definition: win32-low.c:293
static void do_initial_child_stuff(HANDLE proch, DWORD pid, int attached)
Definition: win32-low.c:355
static CORE_ADDR win32_stopped_data_address(void)
Definition: win32-low.c:302
ptid_t thread
Definition: target.h:42
static void win32_mourn(struct process_info *process)
Definition: win32-low.c:873
void * alloca(size_t)
static int get_child_debug_event(struct target_waitstatus *ourstatus)
Definition: win32-low.c:1389
static win32_thread_info * child_add_thread(DWORD pid, DWORD tid, HANDLE h, void *tlb)
Definition: win32-low.c:209
static DWORD main_thread_id
Definition: win32-low.c:74
Definition: buffer.h:23
void hostio_last_error_from_errno(char *buf)
Definition: hostio-errno.c:28
int one_inferior_p(struct inferior_list *list)
Definition: inferiors.c:248
const struct target_desc * win32_tdesc
Definition: win32-low.c:93
struct regcache * get_thread_regcache(struct thread_info *thread, int fetch)
Definition: regcache.c:27
#define COUNTOF(STR)
Definition: win32-low.c:57
CONTEXT context
Definition: win32-low.h:49
void remove_thread(struct thread_info *thread)
Definition: inferiors.c:163
static void win32_add_one_solib(const char *name, CORE_ADDR load_addr)
Definition: win32-low.c:988
struct breakpoint * set_breakpoint_at(CORE_ADDR where, int(*handler)(CORE_ADDR))
Definition: mem-break.c:773
Definition: inferiors.h:29
#define OUTMSG(X)
Definition: win32-low.c:40
static void win32_resume(struct thread_resume *resume_info, size_t n)
Definition: win32-low.c:908
void loaded_dll(const char *name, CORE_ADDR base_addr)
Definition: dll.c:61
void(* arch_setup)(void)
Definition: linux-low.h:130
void check_remote_input_interrupt_request(void)
Definition: remote-utils.c:766
struct thread_info * add_thread(ptid_t ptid, void *target_data)
Definition: inferiors.c:106
PTR xcalloc(size_t number, size_t size)
Definition: common-utils.c:71
void clear_inferiors(void)
Definition: inferiors.c:263
static void win32_join(int pid)
Definition: win32-low.c:880
void error(const char *fmt,...)
Definition: errors.c:38
static HANDLE current_process_handle
Definition: win32-low.c:72
ptid_t minus_one_ptid
Definition: ptid.c:26
static void child_store_inferior_registers(struct regcache *regcache, int r)
Definition: win32-low.c:494
struct inferior_list_entry * find_inferior(struct inferior_list *list, int(*func)(struct inferior_list_entry *, void *), void *arg)
Definition: inferiors.c:188
static BOOL child_continue(DWORD continue_status, int thread_id)
Definition: win32-low.c:463
static int win32_get_tib_address(ptid_t ptid, CORE_ADDR *addr)
Definition: win32-low.c:1775