OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [windows-nat.c] - Blame information for rev 859

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Target-vector operations for controlling windows child processes, for GDB.
2
 
3
   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4
   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
5
 
6
   Contributed by Cygnus Solutions, A Red Hat Company.
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
/* Originally by Steve Chamberlain, sac@cygnus.com */
24
 
25
#include "defs.h"
26
#include "frame.h"              /* required by inferior.h */
27
#include "inferior.h"
28
#include "target.h"
29
#include "exceptions.h"
30
#include "gdbcore.h"
31
#include "command.h"
32
#include "completer.h"
33
#include "regcache.h"
34
#include "top.h"
35
#include <signal.h>
36
#include <sys/types.h>
37
#include <fcntl.h>
38
#include <stdlib.h>
39
#include <windows.h>
40
#include <imagehlp.h>
41
#include <psapi.h>
42
#ifdef __CYGWIN__
43
#include <sys/cygwin.h>
44
#include <cygwin/version.h>
45
#endif
46
#include <signal.h>
47
 
48
#include "buildsym.h"
49
#include "symfile.h"
50
#include "objfiles.h"
51
#include "gdb_obstack.h"
52
#include "gdb_string.h"
53
#include "gdbthread.h"
54
#include "gdbcmd.h"
55
#include <sys/param.h>
56
#include <unistd.h>
57
#include "exec.h"
58
#include "solist.h"
59
#include "solib.h"
60
#include "xml-support.h"
61
 
62
#include "i386-tdep.h"
63
#include "i387-tdep.h"
64
 
65
#include "windows-tdep.h"
66
#include "windows-nat.h"
67
#include "i386-nat.h"
68
#include "complaints.h"
69
 
70
#define AdjustTokenPrivileges           dyn_AdjustTokenPrivileges
71
#define DebugActiveProcessStop          dyn_DebugActiveProcessStop
72
#define DebugBreakProcess               dyn_DebugBreakProcess
73
#define DebugSetProcessKillOnExit       dyn_DebugSetProcessKillOnExit
74
#define EnumProcessModules              dyn_EnumProcessModules
75
#define GetModuleInformation            dyn_GetModuleInformation
76
#define LookupPrivilegeValueA           dyn_LookupPrivilegeValueA
77
#define OpenProcessToken                dyn_OpenProcessToken
78
#define GetConsoleFontSize              dyn_GetConsoleFontSize
79
#define GetCurrentConsoleFont           dyn_GetCurrentConsoleFont
80
 
81
static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
82
                                            DWORD, PTOKEN_PRIVILEGES, PDWORD);
83
static BOOL WINAPI (*DebugActiveProcessStop) (DWORD);
84
static BOOL WINAPI (*DebugBreakProcess) (HANDLE);
85
static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
86
static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
87
                                          LPDWORD);
88
static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
89
                                            DWORD);
90
static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
91
static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
92
static BOOL WINAPI (*GetCurrentConsoleFont) (HANDLE, BOOL, CONSOLE_FONT_INFO *);
93
static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD);
94
 
95
static struct target_ops windows_ops;
96
 
97
#undef STARTUPINFO
98
#undef CreateProcess
99
#undef GetModuleFileNameEx
100
 
101
#ifndef __CYGWIN__
102
# define __PMAX (MAX_PATH + 1)
103
  static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD);
104
# define STARTUPINFO STARTUPINFOA
105
# define CreateProcess CreateProcessA
106
# define GetModuleFileNameEx_name "GetModuleFileNameExA"
107
# define bad_GetModuleFileNameEx bad_GetModuleFileNameExA
108
#else
109
# define __PMAX PATH_MAX
110
/* The starting and ending address of the cygwin1.dll text segment. */
111
  static CORE_ADDR cygwin_load_start;
112
  static CORE_ADDR cygwin_load_end;
113
# if CYGWIN_VERSION_DLL_MAKE_COMBINED(CYGWIN_VERSION_API_MAJOR,CYGWIN_VERSION_API_MINOR) >= 181
114
#   define __USEWIDE
115
    typedef wchar_t cygwin_buf_t;
116
    static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPWSTR, DWORD);
117
#   define STARTUPINFO STARTUPINFOW
118
#   define CreateProcess CreateProcessW
119
#   define GetModuleFileNameEx_name "GetModuleFileNameExW"
120
#   define bad_GetModuleFileNameEx bad_GetModuleFileNameExW
121
# else
122
#   define CCP_POSIX_TO_WIN_W 1
123
#   define CCP_WIN_W_TO_POSIX 3
124
#   define cygwin_conv_path(op, from, to, size)  \
125
         (op == CCP_WIN_W_TO_POSIX) ? \
126
         cygwin_conv_to_full_posix_path (from, to) : \
127
         cygwin_conv_to_win32_path (from, to)
128
    typedef char cygwin_buf_t;
129
    static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD);
130
#   define STARTUPINFO STARTUPINFOA
131
#   define CreateProcess CreateProcessA
132
#   define GetModuleFileNameEx_name "GetModuleFileNameExA"
133
#   define bad_GetModuleFileNameEx bad_GetModuleFileNameExA
134
#   define CW_SET_DOS_FILE_WARNING -1   /* no-op this for older Cygwin */
135
# endif
136
#endif
137
 
138
static int have_saved_context;  /* True if we've saved context from a cygwin signal. */
139
static CONTEXT saved_context;   /* Containes the saved context from a cygwin signal. */
140
 
141
/* If we're not using the old Cygwin header file set, define the
142
   following which never should have been in the generic Win32 API
143
   headers in the first place since they were our own invention... */
144
#ifndef _GNU_H_WINDOWS_H
145
enum
146
  {
147
    FLAG_TRACE_BIT = 0x100,
148
    CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
149
  };
150
#endif
151
 
152
#ifndef CONTEXT_EXTENDED_REGISTERS
153
/* This macro is only defined on ia32.  It only makes sense on this target,
154
   so define it as zero if not already defined.  */
155
#define CONTEXT_EXTENDED_REGISTERS 0
156
#endif
157
 
158
#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
159
        | CONTEXT_EXTENDED_REGISTERS
160
 
161
static uintptr_t dr[8];
162
static int debug_registers_changed;
163
static int debug_registers_used;
164
 
165
static int windows_initialization_done;
166
#define DR6_CLEAR_VALUE 0xffff0ff0
167
 
168
/* The string sent by cygwin when it processes a signal.
169
   FIXME: This should be in a cygwin include file. */
170
#ifndef _CYGWIN_SIGNAL_STRING
171
#define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
172
#endif
173
 
174
#define CHECK(x)        check (x, __FILE__,__LINE__)
175
#define DEBUG_EXEC(x)   if (debug_exec)         printf_unfiltered x
176
#define DEBUG_EVENTS(x) if (debug_events)       printf_unfiltered x
177
#define DEBUG_MEM(x)    if (debug_memory)       printf_unfiltered x
178
#define DEBUG_EXCEPT(x) if (debug_exceptions)   printf_unfiltered x
179
 
180
static void windows_stop (ptid_t);
181
static int windows_thread_alive (struct target_ops *, ptid_t);
182
static void windows_kill_inferior (struct target_ops *);
183
 
184
static void cygwin_set_dr (int i, CORE_ADDR addr);
185
static void cygwin_set_dr7 (unsigned long val);
186
static unsigned long cygwin_get_dr6 (void);
187
 
188
static enum target_signal last_sig = TARGET_SIGNAL_0;
189
/* Set if a signal was received from the debugged process */
190
 
191
/* Thread information structure used to track information that is
192
   not available in gdb's thread structure.  */
193
typedef struct thread_info_struct
194
  {
195
    struct thread_info_struct *next;
196
    DWORD id;
197
    HANDLE h;
198
    CORE_ADDR thread_local_base;
199
    char *name;
200
    int suspended;
201
    int reload_context;
202
    CONTEXT context;
203
    STACKFRAME sf;
204
  }
205
thread_info;
206
 
207
static thread_info thread_head;
208
 
209
/* The process and thread handles for the above context. */
210
 
211
static DEBUG_EVENT current_event;       /* The current debug event from
212
                                           WaitForDebugEvent */
213
static HANDLE current_process_handle;   /* Currently executing process */
214
static thread_info *current_thread;     /* Info on currently selected thread */
215
static DWORD main_thread_id;            /* Thread ID of the main thread */
216
 
217
/* Counts of things. */
218
static int exception_count = 0;
219
static int event_count = 0;
220
static int saw_create;
221
static int open_process_used = 0;
222
 
223
/* User options. */
224
static int new_console = 0;
225
#ifdef __CYGWIN__
226
static int cygwin_exceptions = 0;
227
#endif
228
static int new_group = 1;
229
static int debug_exec = 0;               /* show execution */
230
static int debug_events = 0;             /* show events from kernel */
231
static int debug_memory = 0;             /* show target memory accesses */
232
static int debug_exceptions = 0; /* show target exceptions */
233
static int useshell = 0;         /* use shell for subprocesses */
234
 
235
/* This vector maps GDB's idea of a register's number into an offset
236
   in the windows exception context vector.
237
 
238
   It also contains the bit mask needed to load the register in question.
239
 
240
   The contents of this table can only be computed by the units
241
   that provide CPU-specific support for Windows native debugging.
242
   These units should set the table by calling
243
   windows_set_context_register_offsets.
244
 
245
   One day we could read a reg, we could inspect the context we
246
   already have loaded, if it doesn't have the bit set that we need,
247
   we read that set of registers in using GetThreadContext.  If the
248
   context already contains what we need, we just unpack it. Then to
249
   write a register, first we have to ensure that the context contains
250
   the other regs of the group, and then we copy the info in and set
251
   out bit. */
252
 
253
static const int *mappings;
254
 
255
/* This vector maps the target's idea of an exception (extracted
256
   from the DEBUG_EVENT structure) to GDB's idea. */
257
 
258
struct xlate_exception
259
  {
260
    int them;
261
    enum target_signal us;
262
  };
263
 
264
static const struct xlate_exception
265
  xlate[] =
266
{
267
  {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
268
  {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
269
  {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
270
  {DBG_CONTROL_C, TARGET_SIGNAL_INT},
271
  {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
272
  {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
273
  {-1, -1}};
274
 
275
/* Set the MAPPINGS static global to OFFSETS.
276
   See the description of MAPPINGS for more details.  */
277
 
278
void
279
windows_set_context_register_offsets (const int *offsets)
280
{
281
  mappings = offsets;
282
}
283
 
284
static void
285
check (BOOL ok, const char *file, int line)
286
{
287
  if (!ok)
288
    printf_filtered ("error return %s:%d was %lu\n", file, line,
289
                     GetLastError ());
290
}
291
 
292
/* Find a thread record given a thread id.  If GET_CONTEXT is not 0,
293
   then also retrieve the context for this thread.  If GET_CONTEXT is
294
   negative, then don't suspend the thread.  */
295
static thread_info *
296
thread_rec (DWORD id, int get_context)
297
{
298
  thread_info *th;
299
 
300
  for (th = &thread_head; (th = th->next) != NULL;)
301
    if (th->id == id)
302
      {
303
        if (!th->suspended && get_context)
304
          {
305
            if (get_context > 0 && id != current_event.dwThreadId)
306
              {
307
                if (SuspendThread (th->h) == (DWORD) -1)
308
                  {
309
                    DWORD err = GetLastError ();
310
                    warning (_("SuspendThread failed. (winerr %d)"),
311
                             (int) err);
312
                    return NULL;
313
                  }
314
                th->suspended = 1;
315
              }
316
            else if (get_context < 0)
317
              th->suspended = -1;
318
            th->reload_context = 1;
319
          }
320
        return th;
321
      }
322
 
323
  return NULL;
324
}
325
 
326
/* Add a thread to the thread list.  */
327
static thread_info *
328
windows_add_thread (ptid_t ptid, HANDLE h, void *tlb)
329
{
330
  thread_info *th;
331
  DWORD id;
332
 
333
  gdb_assert (ptid_get_tid (ptid) != 0);
334
 
335
  id = ptid_get_tid (ptid);
336
 
337
  if ((th = thread_rec (id, FALSE)))
338
    return th;
339
 
340
  th = XZALLOC (thread_info);
341
  th->id = id;
342
  th->h = h;
343
  th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb;
344
  th->next = thread_head.next;
345
  thread_head.next = th;
346
  add_thread (ptid);
347
  /* Set the debug registers for the new thread if they are used.  */
348
  if (debug_registers_used)
349
    {
350
      /* Only change the value of the debug registers.  */
351
      th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
352
      CHECK (GetThreadContext (th->h, &th->context));
353
      th->context.Dr0 = dr[0];
354
      th->context.Dr1 = dr[1];
355
      th->context.Dr2 = dr[2];
356
      th->context.Dr3 = dr[3];
357
      th->context.Dr6 = DR6_CLEAR_VALUE;
358
      th->context.Dr7 = dr[7];
359
      CHECK (SetThreadContext (th->h, &th->context));
360
      th->context.ContextFlags = 0;
361
    }
362
  return th;
363
}
364
 
365
/* Clear out any old thread list and reintialize it to a
366
   pristine state. */
367
static void
368
windows_init_thread_list (void)
369
{
370
  thread_info *th = &thread_head;
371
 
372
  DEBUG_EVENTS (("gdb: windows_init_thread_list\n"));
373
  init_thread_list ();
374
  while (th->next != NULL)
375
    {
376
      thread_info *here = th->next;
377
      th->next = here->next;
378
      xfree (here);
379
    }
380
  thread_head.next = NULL;
381
}
382
 
383
/* Delete a thread from the list of threads */
384
static void
385
windows_delete_thread (ptid_t ptid)
386
{
387
  thread_info *th;
388
  DWORD id;
389
 
390
  gdb_assert (ptid_get_tid (ptid) != 0);
391
 
392
  id = ptid_get_tid (ptid);
393
 
394
  if (info_verbose)
395
    printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid));
396
  delete_thread (ptid);
397
 
398
  for (th = &thread_head;
399
       th->next != NULL && th->next->id != id;
400
       th = th->next)
401
    continue;
402
 
403
  if (th->next != NULL)
404
    {
405
      thread_info *here = th->next;
406
      th->next = here->next;
407
      xfree (here);
408
    }
409
}
410
 
411
static void
412
do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
413
{
414
  char *context_offset = ((char *) &current_thread->context) + mappings[r];
415
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
416
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
417
  long l;
418
 
419
  if (!current_thread)
420
    return;     /* Windows sometimes uses a non-existent thread id in its
421
                   events */
422
 
423
  if (current_thread->reload_context)
424
    {
425
#ifdef __COPY_CONTEXT_SIZE
426
      if (have_saved_context)
427
        {
428
          /* Lie about where the program actually is stopped since cygwin has informed us that
429
             we should consider the signal to have occurred at another location which is stored
430
             in "saved_context. */
431
          memcpy (&current_thread->context, &saved_context, __COPY_CONTEXT_SIZE);
432
          have_saved_context = 0;
433
        }
434
      else
435
#endif
436
        {
437
          thread_info *th = current_thread;
438
          th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
439
          GetThreadContext (th->h, &th->context);
440
          /* Copy dr values from that thread.
441
             But only if there were not modified since last stop. PR gdb/2388 */
442
          if (!debug_registers_changed)
443
            {
444
              dr[0] = th->context.Dr0;
445
              dr[1] = th->context.Dr1;
446
              dr[2] = th->context.Dr2;
447
              dr[3] = th->context.Dr3;
448
              dr[6] = th->context.Dr6;
449
              dr[7] = th->context.Dr7;
450
            }
451
        }
452
      current_thread->reload_context = 0;
453
    }
454
 
455
  if (r == I387_FISEG_REGNUM (tdep))
456
    {
457
      l = *((long *) context_offset) & 0xffff;
458
      regcache_raw_supply (regcache, r, (char *) &l);
459
    }
460
  else if (r == I387_FOP_REGNUM (tdep))
461
    {
462
      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
463
      regcache_raw_supply (regcache, r, (char *) &l);
464
    }
465
  else if (r >= 0)
466
    regcache_raw_supply (regcache, r, context_offset);
467
  else
468
    {
469
      for (r = 0; r < gdbarch_num_regs (gdbarch); r++)
470
        do_windows_fetch_inferior_registers (regcache, r);
471
    }
472
}
473
 
474
static void
475
windows_fetch_inferior_registers (struct target_ops *ops,
476
                                  struct regcache *regcache, int r)
477
{
478
  current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
479
  /* Check if current_thread exists.  Windows sometimes uses a non-existent
480
     thread id in its events */
481
  if (current_thread)
482
    do_windows_fetch_inferior_registers (regcache, r);
483
}
484
 
485
static void
486
do_windows_store_inferior_registers (const struct regcache *regcache, int r)
487
{
488
  if (!current_thread)
489
    /* Windows sometimes uses a non-existent thread id in its events */;
490
  else if (r >= 0)
491
    regcache_raw_collect (regcache, r,
492
                          ((char *) &current_thread->context) + mappings[r]);
493
  else
494
    {
495
      for (r = 0; r < gdbarch_num_regs (get_regcache_arch (regcache)); r++)
496
        do_windows_store_inferior_registers (regcache, r);
497
    }
498
}
499
 
500
/* Store a new register value into the current thread context */
501
static void
502
windows_store_inferior_registers (struct target_ops *ops,
503
                                  struct regcache *regcache, int r)
504
{
505
  current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
506
  /* Check if current_thread exists.  Windows sometimes uses a non-existent
507
     thread id in its events */
508
  if (current_thread)
509
    do_windows_store_inferior_registers (regcache, r);
510
}
511
 
512
/* Get the name of a given module at at given base address.  If base_address
513
   is zero return the first loaded module (which is always the name of the
514
   executable).  */
515
static int
516
get_module_name (LPVOID base_address, char *dll_name_ret)
517
{
518
  DWORD len;
519
  MODULEINFO mi;
520
  int i;
521
  HMODULE dh_buf[1];
522
  HMODULE *DllHandle = dh_buf;  /* Set to temporary storage for initial query */
523
  DWORD cbNeeded;
524
#ifdef __CYGWIN__
525
  cygwin_buf_t pathbuf[__PMAX]; /* Temporary storage prior to converting to
526
                                   posix form.  __PMAX is always enough
527
                                   as long as SO_NAME_MAX_PATH_SIZE is defined
528
                                   as 512. */
529
#endif
530
 
531
  cbNeeded = 0;
532
  /* Find size of buffer needed to handle list of modules loaded in inferior */
533
  if (!EnumProcessModules (current_process_handle, DllHandle,
534
                           sizeof (HMODULE), &cbNeeded) || !cbNeeded)
535
    goto failed;
536
 
537
  /* Allocate correct amount of space for module list */
538
  DllHandle = (HMODULE *) alloca (cbNeeded);
539
  if (!DllHandle)
540
    goto failed;
541
 
542
  /* Get the list of modules */
543
  if (!EnumProcessModules (current_process_handle, DllHandle, cbNeeded,
544
                                 &cbNeeded))
545
    goto failed;
546
 
547
  for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
548
    {
549
      /* Get information on this module */
550
      if (!GetModuleInformation (current_process_handle, DllHandle[i],
551
                                 &mi, sizeof (mi)))
552
        error (_("Can't get module info"));
553
 
554
      if (!base_address || mi.lpBaseOfDll == base_address)
555
        {
556
          /* Try to find the name of the given module */
557
#ifdef __CYGWIN__
558
          /* Cygwin prefers that the path be in /x/y/z format */
559
          len = GetModuleFileNameEx (current_process_handle,
560
                                      DllHandle[i], pathbuf, __PMAX);
561
          if (len == 0)
562
            error (_("Error getting dll name: %lu."), GetLastError ());
563
          if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, dll_name_ret,
564
                                __PMAX) < 0)
565
            error (_("Error converting dll name to POSIX: %d."), errno);
566
#else
567
          len = GetModuleFileNameEx (current_process_handle,
568
                                      DllHandle[i], dll_name_ret, __PMAX);
569
          if (len == 0)
570
            error (_("Error getting dll name: %u."), (unsigned) GetLastError ());
571
#endif
572
          return 1;     /* success */
573
        }
574
    }
575
 
576
failed:
577
  dll_name_ret[0] = '\0';
578
  return 0;              /* failure */
579
}
580
 
581
/* Encapsulate the information required in a call to
582
   symbol_file_add_args */
583
struct safe_symbol_file_add_args
584
{
585
  char *name;
586
  int from_tty;
587
  struct section_addr_info *addrs;
588
  int mainline;
589
  int flags;
590
  struct ui_file *err, *out;
591
  struct objfile *ret;
592
};
593
 
594
/* Maintain a linked list of "so" information. */
595
struct lm_info
596
{
597
  LPVOID load_addr;
598
};
599
 
600
static struct so_list solib_start, *solib_end;
601
 
602
/* Call symbol_file_add with stderr redirected.  We don't care if there
603
   are errors. */
604
static int
605
safe_symbol_file_add_stub (void *argv)
606
{
607
#define p ((struct safe_symbol_file_add_args *) argv)
608
  const int add_flags = ((p->from_tty ? SYMFILE_VERBOSE : 0)
609
                         | (p->mainline ? SYMFILE_MAINLINE : 0));
610
  p->ret = symbol_file_add (p->name, add_flags, p->addrs, p->flags);
611
  return !!p->ret;
612
#undef p
613
}
614
 
615
/* Restore gdb's stderr after calling symbol_file_add */
616
static void
617
safe_symbol_file_add_cleanup (void *p)
618
{
619
#define sp ((struct safe_symbol_file_add_args *)p)
620
  gdb_flush (gdb_stderr);
621
  gdb_flush (gdb_stdout);
622
  ui_file_delete (gdb_stderr);
623
  ui_file_delete (gdb_stdout);
624
  gdb_stderr = sp->err;
625
  gdb_stdout = sp->out;
626
#undef sp
627
}
628
 
629
/* symbol_file_add wrapper that prevents errors from being displayed. */
630
static struct objfile *
631
safe_symbol_file_add (char *name, int from_tty,
632
                      struct section_addr_info *addrs,
633
                      int mainline, int flags)
634
{
635
  struct safe_symbol_file_add_args p;
636
  struct cleanup *cleanup;
637
 
638
  cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
639
 
640
  p.err = gdb_stderr;
641
  p.out = gdb_stdout;
642
  gdb_flush (gdb_stderr);
643
  gdb_flush (gdb_stdout);
644
  gdb_stderr = ui_file_new ();
645
  gdb_stdout = ui_file_new ();
646
  p.name = name;
647
  p.from_tty = from_tty;
648
  p.addrs = addrs;
649
  p.mainline = mainline;
650
  p.flags = flags;
651
  catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
652
 
653
  do_cleanups (cleanup);
654
  return p.ret;
655
}
656
 
657
static struct so_list *
658
windows_make_so (const char *name, LPVOID load_addr)
659
{
660
  struct so_list *so;
661
  char *p;
662
#ifndef __CYGWIN__
663
  char buf[__PMAX];
664
  char cwd[__PMAX];
665
  WIN32_FIND_DATA w32_fd;
666
  HANDLE h = FindFirstFile(name, &w32_fd);
667
 
668
  if (h == INVALID_HANDLE_VALUE)
669
    strcpy (buf, name);
670
  else
671
    {
672
      FindClose (h);
673
      strcpy (buf, name);
674
      if (GetCurrentDirectory (MAX_PATH + 1, cwd))
675
        {
676
          p = strrchr (buf, '\\');
677
          if (p)
678
            p[1] = '\0';
679
          SetCurrentDirectory (buf);
680
          GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
681
          SetCurrentDirectory (cwd);
682
        }
683
    }
684
  if (strcasecmp (buf, "ntdll.dll") == 0)
685
    {
686
      GetSystemDirectory (buf, sizeof (buf));
687
      strcat (buf, "\\ntdll.dll");
688
    }
689
#else
690
  cygwin_buf_t buf[__PMAX];
691
 
692
  buf[0] = 0;
693
  if (access (name, F_OK) != 0)
694
    {
695
      if (strcasecmp (name, "ntdll.dll") == 0)
696
#ifdef __USEWIDE
697
        {
698
          GetSystemDirectoryW (buf, sizeof (buf) / sizeof (wchar_t));
699
          wcscat (buf, L"\\ntdll.dll");
700
        }
701
#else
702
        {
703
          GetSystemDirectoryA (buf, sizeof (buf) / sizeof (wchar_t));
704
          strcat (buf, "\\ntdll.dll");
705
        }
706
#endif
707
    }
708
#endif
709
  so = XZALLOC (struct so_list);
710
  so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
711
  so->lm_info->load_addr = load_addr;
712
  strcpy (so->so_original_name, name);
713
#ifndef __CYGWIN__
714
  strcpy (so->so_name, buf);
715
#else
716
  if (buf[0])
717
    cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
718
                      SO_NAME_MAX_PATH_SIZE);
719
  else
720
    {
721
      char *rname = realpath (name, NULL);
722
      if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE)
723
        {
724
          strcpy (so->so_name, rname);
725
          free (rname);
726
        }
727
      else
728
        error (_("dll path too long"));
729
    }
730
  /* Record cygwin1.dll .text start/end.  */
731
  p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
732
  if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
733
    {
734
      bfd *abfd;
735
      asection *text = NULL;
736
      CORE_ADDR text_vma;
737
 
738
      abfd = bfd_openr (so->so_name, "pei-i386");
739
 
740
      if (!abfd)
741
        return so;
742
 
743
      if (bfd_check_format (abfd, bfd_object))
744
        text = bfd_get_section_by_name (abfd, ".text");
745
 
746
      if (!text)
747
        {
748
          bfd_close (abfd);
749
          return so;
750
        }
751
 
752
      /* The symbols in a dll are offset by 0x1000, which is the the
753
         offset from 0 of the first byte in an image - because of the
754
         file header and the section alignment. */
755
      cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *) load_addr + 0x1000);
756
      cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text);
757
 
758
      bfd_close (abfd);
759
    }
760
#endif
761
 
762
  return so;
763
}
764
 
765
static char *
766
get_image_name (HANDLE h, void *address, int unicode)
767
{
768
#ifdef __CYGWIN__
769
  static char buf[__PMAX];
770
#else
771
  static char buf[(2 * __PMAX) + 1];
772
#endif
773
  DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
774
  char *address_ptr;
775
  int len = 0;
776
  char b[2];
777
  SIZE_T done;
778
 
779
  /* Attempt to read the name of the dll that was detected.
780
     This is documented to work only when actively debugging
781
     a program.  It will not work for attached processes. */
782
  if (address == NULL)
783
    return NULL;
784
 
785
  /* See if we could read the address of a string, and that the
786
     address isn't null. */
787
  if (!ReadProcessMemory (h, address,  &address_ptr, sizeof (address_ptr), &done)
788
      || done != sizeof (address_ptr) || !address_ptr)
789
    return NULL;
790
 
791
  /* Find the length of the string */
792
  while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
793
         && (b[0] != 0 || b[size - 1] != 0) && done == size)
794
    continue;
795
 
796
  if (!unicode)
797
    ReadProcessMemory (h, address_ptr, buf, len, &done);
798
  else
799
    {
800
      WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
801
      ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
802
                         &done);
803
#ifdef __CYGWIN__
804
      wcstombs (buf, unicode_address, __PMAX);
805
#else
806
      WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
807
                           0, 0);
808
#endif
809
    }
810
 
811
  return buf;
812
}
813
 
814
/* Wait for child to do something.  Return pid of child, or -1 in case
815
   of error; store status through argument pointer OURSTATUS.  */
816
static int
817
handle_load_dll (void *dummy)
818
{
819
  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
820
  char dll_buf[__PMAX];
821
  char *dll_name = NULL;
822
 
823
  dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
824
 
825
  if (!get_module_name (event->lpBaseOfDll, dll_buf))
826
    dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
827
 
828
  dll_name = dll_buf;
829
 
830
  if (*dll_name == '\0')
831
    dll_name = get_image_name (current_process_handle,
832
                               event->lpImageName, event->fUnicode);
833
  if (!dll_name)
834
    return 1;
835
 
836
  solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
837
  solib_end = solib_end->next;
838
 
839
  DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name,
840
                 host_address_to_string (solib_end->lm_info->load_addr)));
841
 
842
  return 1;
843
}
844
 
845
static void
846
windows_free_so (struct so_list *so)
847
{
848
  if (so->lm_info)
849
    xfree (so->lm_info);
850
  xfree (so);
851
}
852
 
853
static int
854
handle_unload_dll (void *dummy)
855
{
856
  LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
857
  struct so_list *so;
858
 
859
  for (so = &solib_start; so->next != NULL; so = so->next)
860
    if (so->next->lm_info->load_addr == lpBaseOfDll)
861
      {
862
        struct so_list *sodel = so->next;
863
        so->next = sodel->next;
864
        if (!so->next)
865
          solib_end = so;
866
        DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
867
 
868
        windows_free_so (sodel);
869
        solib_add (NULL, 0, NULL, auto_solib_add);
870
        return 1;
871
      }
872
 
873
  /* We did not find any DLL that was previously loaded at this address,
874
     so register a complaint.  We do not report an error, because we have
875
     observed that this may be happening under some circumstances.  For
876
     instance, running 32bit applications on x64 Windows causes us to receive
877
     4 mysterious UNLOAD_DLL_DEBUG_EVENTs during the startup phase (these
878
     events are apparently caused by the WOW layer, the interface between
879
     32bit and 64bit worlds).  */
880
  complaint (&symfile_complaints, _("dll starting at %s not found."),
881
             host_address_to_string (lpBaseOfDll));
882
 
883
  return 0;
884
}
885
 
886
/* Clear list of loaded DLLs. */
887
static void
888
windows_clear_solib (void)
889
{
890
  solib_start.next = NULL;
891
  solib_end = &solib_start;
892
}
893
 
894
/* Load DLL symbol info. */
895
void
896
dll_symbol_command (char *args, int from_tty)
897
{
898
  int n;
899
  dont_repeat ();
900
 
901
  if (args == NULL)
902
    error (_("dll-symbols requires a file name"));
903
 
904
  n = strlen (args);
905
  if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
906
    {
907
      char *newargs = (char *) alloca (n + 4 + 1);
908
      strcpy (newargs, args);
909
      strcat (newargs, ".dll");
910
      args = newargs;
911
    }
912
 
913
  safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
914
}
915
 
916
/* Handle DEBUG_STRING output from child process.
917
   Cygwin prepends its messages with a "cygwin:".  Interpret this as
918
   a Cygwin signal.  Otherwise just print the string as a warning. */
919
static int
920
handle_output_debug_string (struct target_waitstatus *ourstatus)
921
{
922
  char *s = NULL;
923
  int retval = 0;
924
 
925
  if (!target_read_string
926
        ((CORE_ADDR) (uintptr_t) current_event.u.DebugString.lpDebugStringData,
927
        &s, 1024, 0)
928
      || !s || !*s)
929
    /* nothing to do */;
930
  else if (strncmp (s, _CYGWIN_SIGNAL_STRING, sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0)
931
    {
932
#ifdef __CYGWIN__
933
      if (strncmp (s, "cYg", 3) != 0)
934
#endif
935
        warning (("%s"), s);
936
    }
937
#ifdef __COPY_CONTEXT_SIZE
938
  else
939
    {
940
      /* Got a cygwin signal marker.  A cygwin signal is followed by the signal number
941
         itself and then optionally followed by the thread id and address to saved context
942
         within the DLL.  If these are supplied, then the given thread is assumed to have
943
         issued the signal and the context from the thread is assumed to be stored at the
944
         given address in the inferior.  Tell gdb to treat this like a real signal.  */
945
      char *p;
946
      int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
947
      int gotasig = target_signal_from_host (sig);
948
      ourstatus->value.sig = gotasig;
949
      if (gotasig)
950
        {
951
          LPCVOID x;
952
          DWORD n;
953
          ourstatus->kind = TARGET_WAITKIND_STOPPED;
954
          retval = strtoul (p, &p, 0);
955
          if (!retval)
956
            retval = main_thread_id;
957
          else if ((x = (LPCVOID) strtoul (p, &p, 0))
958
                   && ReadProcessMemory (current_process_handle, x,
959
                                         &saved_context, __COPY_CONTEXT_SIZE, &n)
960
                   && n == __COPY_CONTEXT_SIZE)
961
            have_saved_context = 1;
962
          current_event.dwThreadId = retval;
963
        }
964
    }
965
#endif
966
 
967
  if (s)
968
    xfree (s);
969
  return retval;
970
}
971
 
972
static int
973
display_selector (HANDLE thread, DWORD sel)
974
{
975
  LDT_ENTRY info;
976
  if (GetThreadSelectorEntry (thread, sel, &info))
977
    {
978
      int base, limit;
979
      printf_filtered ("0x%03lx: ", sel);
980
      if (!info.HighWord.Bits.Pres)
981
        {
982
          puts_filtered ("Segment not present\n");
983
          return 0;
984
        }
985
      base = (info.HighWord.Bits.BaseHi << 24) +
986
             (info.HighWord.Bits.BaseMid << 16)
987
             + info.BaseLow;
988
      limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
989
      if (info.HighWord.Bits.Granularity)
990
        limit = (limit << 12) | 0xfff;
991
      printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
992
      if (info.HighWord.Bits.Default_Big)
993
        puts_filtered(" 32-bit ");
994
      else
995
        puts_filtered(" 16-bit ");
996
      switch ((info.HighWord.Bits.Type & 0xf) >> 1)
997
        {
998
        case 0:
999
          puts_filtered ("Data (Read-Only, Exp-up");
1000
          break;
1001
        case 1:
1002
          puts_filtered ("Data (Read/Write, Exp-up");
1003
          break;
1004
        case 2:
1005
          puts_filtered ("Unused segment (");
1006
          break;
1007
        case 3:
1008
          puts_filtered ("Data (Read/Write, Exp-down");
1009
          break;
1010
        case 4:
1011
          puts_filtered ("Code (Exec-Only, N.Conf");
1012
          break;
1013
        case 5:
1014
          puts_filtered ("Code (Exec/Read, N.Conf");
1015
          break;
1016
        case 6:
1017
          puts_filtered ("Code (Exec-Only, Conf");
1018
          break;
1019
        case 7:
1020
          puts_filtered ("Code (Exec/Read, Conf");
1021
          break;
1022
        default:
1023
          printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
1024
        }
1025
      if ((info.HighWord.Bits.Type & 0x1) == 0)
1026
        puts_filtered(", N.Acc");
1027
      puts_filtered (")\n");
1028
      if ((info.HighWord.Bits.Type & 0x10) == 0)
1029
        puts_filtered("System selector ");
1030
      printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
1031
      if (info.HighWord.Bits.Granularity)
1032
        puts_filtered ("Page granular.\n");
1033
      else
1034
        puts_filtered ("Byte granular.\n");
1035
      return 1;
1036
    }
1037
  else
1038
    {
1039
      DWORD err = GetLastError ();
1040
      if (err == ERROR_NOT_SUPPORTED)
1041
        printf_filtered ("Function not supported\n");
1042
      else
1043
        printf_filtered ("Invalid selector 0x%lx.\n",sel);
1044
      return 0;
1045
    }
1046
}
1047
 
1048
static void
1049
display_selectors (char * args, int from_tty)
1050
{
1051
  if (!current_thread)
1052
    {
1053
      puts_filtered ("Impossible to display selectors now.\n");
1054
      return;
1055
    }
1056
  if (!args)
1057
    {
1058
 
1059
      puts_filtered ("Selector $cs\n");
1060
      display_selector (current_thread->h,
1061
        current_thread->context.SegCs);
1062
      puts_filtered ("Selector $ds\n");
1063
      display_selector (current_thread->h,
1064
        current_thread->context.SegDs);
1065
      puts_filtered ("Selector $es\n");
1066
      display_selector (current_thread->h,
1067
        current_thread->context.SegEs);
1068
      puts_filtered ("Selector $ss\n");
1069
      display_selector (current_thread->h,
1070
        current_thread->context.SegSs);
1071
      puts_filtered ("Selector $fs\n");
1072
      display_selector (current_thread->h,
1073
        current_thread->context.SegFs);
1074
      puts_filtered ("Selector $gs\n");
1075
      display_selector (current_thread->h,
1076
        current_thread->context.SegGs);
1077
    }
1078
  else
1079
    {
1080
      int sel;
1081
      sel = parse_and_eval_long (args);
1082
      printf_filtered ("Selector \"%s\"\n",args);
1083
      display_selector (current_thread->h, sel);
1084
    }
1085
}
1086
 
1087
#define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
1088
  printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
1089
    host_address_to_string (\
1090
      current_event.u.Exception.ExceptionRecord.ExceptionAddress))
1091
 
1092
static int
1093
handle_exception (struct target_waitstatus *ourstatus)
1094
{
1095
  thread_info *th;
1096
  DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
1097
 
1098
  ourstatus->kind = TARGET_WAITKIND_STOPPED;
1099
 
1100
  /* Record the context of the current thread */
1101
  th = thread_rec (current_event.dwThreadId, -1);
1102
 
1103
  switch (code)
1104
    {
1105
    case EXCEPTION_ACCESS_VIOLATION:
1106
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1107
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1108
#ifdef __CYGWIN__
1109
      {
1110
        /* See if the access violation happened within the cygwin DLL itself.  Cygwin uses
1111
           a kind of exception handling to deal with passed-in invalid addresses. gdb
1112
           should not treat these as real SEGVs since they will be silently handled by
1113
           cygwin.  A real SEGV will (theoretically) be caught by cygwin later in the process
1114
           and will be sent as a cygwin-specific-signal.  So, ignore SEGVs if they show up
1115
           within the text segment of the DLL itself. */
1116
        char *fn;
1117
        CORE_ADDR addr = (CORE_ADDR) (uintptr_t) current_event.u.Exception.ExceptionRecord.ExceptionAddress;
1118
        if ((!cygwin_exceptions && (addr >= cygwin_load_start && addr < cygwin_load_end))
1119
            || (find_pc_partial_function (addr, &fn, NULL, NULL)
1120
                && strncmp (fn, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0))
1121
          return 0;
1122
      }
1123
#endif
1124
      break;
1125
    case STATUS_STACK_OVERFLOW:
1126
      DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1127
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1128
      break;
1129
    case STATUS_FLOAT_DENORMAL_OPERAND:
1130
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1131
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1132
      break;
1133
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1134
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1135
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1136
      break;
1137
    case STATUS_FLOAT_INEXACT_RESULT:
1138
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1139
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1140
      break;
1141
    case STATUS_FLOAT_INVALID_OPERATION:
1142
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1143
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1144
      break;
1145
    case STATUS_FLOAT_OVERFLOW:
1146
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1147
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1148
      break;
1149
    case STATUS_FLOAT_STACK_CHECK:
1150
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1151
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1152
      break;
1153
    case STATUS_FLOAT_UNDERFLOW:
1154
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1155
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1156
      break;
1157
    case STATUS_FLOAT_DIVIDE_BY_ZERO:
1158
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1159
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1160
      break;
1161
    case STATUS_INTEGER_DIVIDE_BY_ZERO:
1162
      DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1163
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1164
      break;
1165
    case STATUS_INTEGER_OVERFLOW:
1166
      DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1167
      ourstatus->value.sig = TARGET_SIGNAL_FPE;
1168
      break;
1169
    case EXCEPTION_BREAKPOINT:
1170
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1171
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1172
      break;
1173
    case DBG_CONTROL_C:
1174
      DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1175
      ourstatus->value.sig = TARGET_SIGNAL_INT;
1176
      break;
1177
    case DBG_CONTROL_BREAK:
1178
      DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1179
      ourstatus->value.sig = TARGET_SIGNAL_INT;
1180
      break;
1181
    case EXCEPTION_SINGLE_STEP:
1182
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1183
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1184
      break;
1185
    case EXCEPTION_ILLEGAL_INSTRUCTION:
1186
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1187
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1188
      break;
1189
    case EXCEPTION_PRIV_INSTRUCTION:
1190
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1191
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1192
      break;
1193
    case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1194
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1195
      ourstatus->value.sig = TARGET_SIGNAL_ILL;
1196
      break;
1197
    default:
1198
      /* Treat unhandled first chance exceptions specially. */
1199
      if (current_event.u.Exception.dwFirstChance)
1200
        return -1;
1201
      printf_unfiltered ("gdb: unknown target exception 0x%08lx at %s\n",
1202
        current_event.u.Exception.ExceptionRecord.ExceptionCode,
1203
        host_address_to_string (
1204
          current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1205
      ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1206
      break;
1207
    }
1208
  exception_count++;
1209
  last_sig = ourstatus->value.sig;
1210
  return 1;
1211
}
1212
 
1213
/* Resume all artificially suspended threads if we are continuing
1214
   execution */
1215
static BOOL
1216
windows_continue (DWORD continue_status, int id)
1217
{
1218
  int i;
1219
  thread_info *th;
1220
  BOOL res;
1221
 
1222
  DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%lx, %s);\n",
1223
                  current_event.dwProcessId, current_event.dwThreadId,
1224
                  continue_status == DBG_CONTINUE ?
1225
                  "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1226
 
1227
  for (th = &thread_head; (th = th->next) != NULL;)
1228
    if ((id == -1 || id == (int) th->id)
1229
        && th->suspended)
1230
      {
1231
        if (debug_registers_changed)
1232
          {
1233
            th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
1234
            th->context.Dr0 = dr[0];
1235
            th->context.Dr1 = dr[1];
1236
            th->context.Dr2 = dr[2];
1237
            th->context.Dr3 = dr[3];
1238
            th->context.Dr6 = DR6_CLEAR_VALUE;
1239
            th->context.Dr7 = dr[7];
1240
          }
1241
        if (th->context.ContextFlags)
1242
          {
1243
            CHECK (SetThreadContext (th->h, &th->context));
1244
            th->context.ContextFlags = 0;
1245
          }
1246
        if (th->suspended > 0)
1247
          (void) ResumeThread (th->h);
1248
        th->suspended = 0;
1249
      }
1250
 
1251
  res = ContinueDebugEvent (current_event.dwProcessId,
1252
                            current_event.dwThreadId,
1253
                            continue_status);
1254
 
1255
  debug_registers_changed = 0;
1256
  return res;
1257
}
1258
 
1259
/* Called in pathological case where Windows fails to send a
1260
   CREATE_PROCESS_DEBUG_EVENT after an attach.  */
1261
static DWORD
1262
fake_create_process (void)
1263
{
1264
  current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
1265
                                        current_event.dwProcessId);
1266
  if (current_process_handle != NULL)
1267
    open_process_used = 1;
1268
  else
1269
    {
1270
      error (_("OpenProcess call failed, GetLastError = %lud\n"),
1271
       GetLastError ());
1272
      /*  We can not debug anything in that case.  */
1273
    }
1274
  main_thread_id = current_event.dwThreadId;
1275
  current_thread = windows_add_thread (
1276
                     ptid_build (current_event.dwProcessId, 0,
1277
                                 current_event.dwThreadId),
1278
                     current_event.u.CreateThread.hThread,
1279
                     current_event.u.CreateThread.lpThreadLocalBase);
1280
  return main_thread_id;
1281
}
1282
 
1283
static void
1284
windows_resume (struct target_ops *ops,
1285
                ptid_t ptid, int step, enum target_signal sig)
1286
{
1287
  thread_info *th;
1288
  DWORD continue_status = DBG_CONTINUE;
1289
 
1290
  /* A specific PTID means `step only this thread id'.  */
1291
  int resume_all = ptid_equal (ptid, minus_one_ptid);
1292
 
1293
  /* If we're continuing all threads, it's the current inferior that
1294
     should be handled specially.  */
1295
  if (resume_all)
1296
    ptid = inferior_ptid;
1297
 
1298
  if (sig != TARGET_SIGNAL_0)
1299
    {
1300
      if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1301
        {
1302
          DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1303
        }
1304
      else if (sig == last_sig)
1305
        continue_status = DBG_EXCEPTION_NOT_HANDLED;
1306
      else
1307
#if 0
1308
/* This code does not seem to work, because
1309
  the kernel does probably not consider changes in the ExceptionRecord
1310
  structure when passing the exception to the inferior.
1311
  Note that this seems possible in the exception handler itself.  */
1312
        {
1313
          int i;
1314
          for (i = 0; xlate[i].them != -1; i++)
1315
            if (xlate[i].us == sig)
1316
              {
1317
                current_event.u.Exception.ExceptionRecord.ExceptionCode =
1318
                  xlate[i].them;
1319
                continue_status = DBG_EXCEPTION_NOT_HANDLED;
1320
                break;
1321
              }
1322
          if (continue_status == DBG_CONTINUE)
1323
            {
1324
              DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1325
            }
1326
        }
1327
#endif
1328
        DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1329
          last_sig));
1330
    }
1331
 
1332
  last_sig = TARGET_SIGNAL_0;
1333
 
1334
  DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n",
1335
               ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig));
1336
 
1337
  /* Get context for currently selected thread */
1338
  th = thread_rec (ptid_get_tid (inferior_ptid), FALSE);
1339
  if (th)
1340
    {
1341
      if (step)
1342
        {
1343
          /* Single step by setting t bit */
1344
          struct regcache *regcache = get_current_regcache ();
1345
          struct gdbarch *gdbarch = get_regcache_arch (regcache);
1346
          windows_fetch_inferior_registers (ops, regcache,
1347
                                            gdbarch_ps_regnum (gdbarch));
1348
          th->context.EFlags |= FLAG_TRACE_BIT;
1349
        }
1350
 
1351
      if (th->context.ContextFlags)
1352
        {
1353
          if (debug_registers_changed)
1354
            {
1355
              th->context.Dr0 = dr[0];
1356
              th->context.Dr1 = dr[1];
1357
              th->context.Dr2 = dr[2];
1358
              th->context.Dr3 = dr[3];
1359
              th->context.Dr6 = DR6_CLEAR_VALUE;
1360
              th->context.Dr7 = dr[7];
1361
            }
1362
          CHECK (SetThreadContext (th->h, &th->context));
1363
          th->context.ContextFlags = 0;
1364
        }
1365
    }
1366
 
1367
  /* Allow continuing with the same signal that interrupted us.
1368
     Otherwise complain. */
1369
 
1370
  if (resume_all)
1371
    windows_continue (continue_status, -1);
1372
  else
1373
    windows_continue (continue_status, ptid_get_tid (ptid));
1374
}
1375
 
1376
/* Ctrl-C handler used when the inferior is not run in the same console.  The
1377
   handler is in charge of interrupting the inferior using DebugBreakProcess.
1378
   Note that this function is not available prior to Windows XP.  In this case
1379
   we emit a warning.  */
1380
BOOL WINAPI
1381
ctrl_c_handler (DWORD event_type)
1382
{
1383
  const int attach_flag = current_inferior ()->attach_flag;
1384
 
1385
  /* Only handle Ctrl-C and Ctrl-Break events.  Ignore others.  */
1386
  if (event_type != CTRL_C_EVENT && event_type != CTRL_BREAK_EVENT)
1387
    return FALSE;
1388
 
1389
  /* If the inferior and the debugger share the same console, do nothing as
1390
     the inferior has also received the Ctrl-C event.  */
1391
  if (!new_console && !attach_flag)
1392
    return TRUE;
1393
 
1394
  if (!DebugBreakProcess (current_process_handle))
1395
    warning (_("\
1396
Could not interrupt program.  Press Ctrl-c in the program console."));
1397
 
1398
  /* Return true to tell that Ctrl-C has been handled.  */
1399
  return TRUE;
1400
}
1401
 
1402
/* Get the next event from the child.  Return 1 if the event requires
1403
   handling by WFI (or whatever).  */
1404
static int
1405
get_windows_debug_event (struct target_ops *ops,
1406
                         int pid, struct target_waitstatus *ourstatus)
1407
{
1408
  BOOL debug_event;
1409
  DWORD continue_status, event_code;
1410
  thread_info *th;
1411
  static thread_info dummy_thread_info;
1412
  int retval = 0;
1413
 
1414
  last_sig = TARGET_SIGNAL_0;
1415
 
1416
  if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
1417
    goto out;
1418
 
1419
  event_count++;
1420
  continue_status = DBG_CONTINUE;
1421
 
1422
  event_code = current_event.dwDebugEventCode;
1423
  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1424
  th = NULL;
1425
  have_saved_context = 0;
1426
 
1427
  switch (event_code)
1428
    {
1429
    case CREATE_THREAD_DEBUG_EVENT:
1430
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1431
                     (unsigned) current_event.dwProcessId,
1432
                     (unsigned) current_event.dwThreadId,
1433
                     "CREATE_THREAD_DEBUG_EVENT"));
1434
      if (saw_create != 1)
1435
        {
1436
          struct inferior *inf;
1437
          inf = find_inferior_pid (current_event.dwProcessId);
1438
          if (!saw_create && inf->attach_flag)
1439
            {
1440
              /* Kludge around a Windows bug where first event is a create
1441
                 thread event.  Caused when attached process does not have
1442
                 a main thread. */
1443
              retval = fake_create_process ();
1444
              if (retval)
1445
                saw_create++;
1446
            }
1447
          break;
1448
        }
1449
      /* Record the existence of this thread */
1450
      retval = current_event.dwThreadId;
1451
      th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
1452
                                         current_event.dwThreadId),
1453
                             current_event.u.CreateThread.hThread,
1454
                             current_event.u.CreateThread.lpThreadLocalBase);
1455
 
1456
      break;
1457
 
1458
    case EXIT_THREAD_DEBUG_EVENT:
1459
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1460
                     (unsigned) current_event.dwProcessId,
1461
                     (unsigned) current_event.dwThreadId,
1462
                     "EXIT_THREAD_DEBUG_EVENT"));
1463
 
1464
      if (current_event.dwThreadId != main_thread_id)
1465
        {
1466
          windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
1467
                                           current_event.dwThreadId));
1468
          th = &dummy_thread_info;
1469
        }
1470
      break;
1471
 
1472
    case CREATE_PROCESS_DEBUG_EVENT:
1473
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1474
                     (unsigned) current_event.dwProcessId,
1475
                     (unsigned) current_event.dwThreadId,
1476
                     "CREATE_PROCESS_DEBUG_EVENT"));
1477
      CloseHandle (current_event.u.CreateProcessInfo.hFile);
1478
      if (++saw_create != 1)
1479
        break;
1480
 
1481
      current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1482
      if (main_thread_id)
1483
        windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
1484
                                           main_thread_id));
1485
      main_thread_id = current_event.dwThreadId;
1486
      /* Add the main thread */
1487
      th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
1488
                                           current_event.dwThreadId),
1489
             current_event.u.CreateProcessInfo.hThread,
1490
             current_event.u.CreateProcessInfo.lpThreadLocalBase);
1491
      retval = current_event.dwThreadId;
1492
      break;
1493
 
1494
    case EXIT_PROCESS_DEBUG_EVENT:
1495
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1496
                     (unsigned) current_event.dwProcessId,
1497
                     (unsigned) current_event.dwThreadId,
1498
                     "EXIT_PROCESS_DEBUG_EVENT"));
1499
      if (!windows_initialization_done)
1500
        {
1501
          target_terminal_ours ();
1502
          target_mourn_inferior ();
1503
          error (_("During startup program exited with code 0x%x."),
1504
                 (unsigned int) current_event.u.ExitProcess.dwExitCode);
1505
        }
1506
      else if (saw_create == 1)
1507
        {
1508
          ourstatus->kind = TARGET_WAITKIND_EXITED;
1509
          ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1510
          retval = main_thread_id;
1511
        }
1512
      break;
1513
 
1514
    case LOAD_DLL_DEBUG_EVENT:
1515
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1516
                     (unsigned) current_event.dwProcessId,
1517
                     (unsigned) current_event.dwThreadId,
1518
                     "LOAD_DLL_DEBUG_EVENT"));
1519
      CloseHandle (current_event.u.LoadDll.hFile);
1520
      if (saw_create != 1)
1521
        break;
1522
      catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1523
      ourstatus->kind = TARGET_WAITKIND_LOADED;
1524
      ourstatus->value.integer = 0;
1525
      retval = main_thread_id;
1526
      break;
1527
 
1528
    case UNLOAD_DLL_DEBUG_EVENT:
1529
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1530
                     (unsigned) current_event.dwProcessId,
1531
                     (unsigned) current_event.dwThreadId,
1532
                     "UNLOAD_DLL_DEBUG_EVENT"));
1533
      if (saw_create != 1)
1534
        break;
1535
      catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1536
      ourstatus->kind = TARGET_WAITKIND_LOADED;
1537
      ourstatus->value.integer = 0;
1538
      retval = main_thread_id;
1539
      break;
1540
 
1541
    case EXCEPTION_DEBUG_EVENT:
1542
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1543
                     (unsigned) current_event.dwProcessId,
1544
                     (unsigned) current_event.dwThreadId,
1545
                     "EXCEPTION_DEBUG_EVENT"));
1546
      if (saw_create != 1)
1547
        break;
1548
      switch (handle_exception (ourstatus))
1549
        {
1550
        case 0:
1551
          continue_status = DBG_EXCEPTION_NOT_HANDLED;
1552
          break;
1553
        case 1:
1554
          retval = current_event.dwThreadId;
1555
          break;
1556
        case -1:
1557
          last_sig = 1;
1558
          continue_status = -1;
1559
          break;
1560
        }
1561
      break;
1562
 
1563
    case OUTPUT_DEBUG_STRING_EVENT:     /* message from the kernel */
1564
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1565
                     (unsigned) current_event.dwProcessId,
1566
                     (unsigned) current_event.dwThreadId,
1567
                     "OUTPUT_DEBUG_STRING_EVENT"));
1568
      if (saw_create != 1)
1569
        break;
1570
      retval = handle_output_debug_string (ourstatus);
1571
      break;
1572
 
1573
    default:
1574
      if (saw_create != 1)
1575
        break;
1576
      printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1577
                         (DWORD) current_event.dwProcessId,
1578
                         (DWORD) current_event.dwThreadId);
1579
      printf_unfiltered ("                 unknown event code %ld\n",
1580
                         current_event.dwDebugEventCode);
1581
      break;
1582
    }
1583
 
1584
  if (!retval || saw_create != 1)
1585
    {
1586
      if (continue_status == -1)
1587
        windows_resume (ops, minus_one_ptid, 0, 1);
1588
      else
1589
        CHECK (windows_continue (continue_status, -1));
1590
    }
1591
  else
1592
    {
1593
      inferior_ptid = ptid_build (current_event.dwProcessId, 0,
1594
                                  retval);
1595
      current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
1596
    }
1597
 
1598
out:
1599
  return retval;
1600
}
1601
 
1602
/* Wait for interesting events to occur in the target process.  */
1603
static ptid_t
1604
windows_wait (struct target_ops *ops,
1605
              ptid_t ptid, struct target_waitstatus *ourstatus, int options)
1606
{
1607
  int pid = -1;
1608
 
1609
  target_terminal_ours ();
1610
 
1611
  /* We loop when we get a non-standard exception rather than return
1612
     with a SPURIOUS because resume can try and step or modify things,
1613
     which needs a current_thread->h.  But some of these exceptions mark
1614
     the birth or death of threads, which mean that the current thread
1615
     isn't necessarily what you think it is. */
1616
 
1617
  while (1)
1618
    {
1619
      int retval;
1620
 
1621
      /* If the user presses Ctrl-c while the debugger is waiting
1622
         for an event, he expects the debugger to interrupt his program
1623
         and to get the prompt back.  There are two possible situations:
1624
 
1625
           - The debugger and the program do not share the console, in
1626
             which case the Ctrl-c event only reached the debugger.
1627
             In that case, the ctrl_c handler will take care of interrupting
1628
             the inferior. Note that this case is working starting with
1629
             Windows XP. For Windows 2000, Ctrl-C should be pressed in the
1630
             inferior console.
1631
 
1632
           - The debugger and the program share the same console, in which
1633
             case both debugger and inferior will receive the Ctrl-c event.
1634
             In that case the ctrl_c handler will ignore the event, as the
1635
             Ctrl-c event generated inside the inferior will trigger the
1636
             expected debug event.
1637
 
1638
             FIXME: brobecker/2008-05-20: If the inferior receives the
1639
             signal first and the delay until GDB receives that signal
1640
             is sufficiently long, GDB can sometimes receive the SIGINT
1641
             after we have unblocked the CTRL+C handler.  This would
1642
             lead to the debugger stopping prematurely while handling
1643
             the new-thread event that comes with the handling of the SIGINT
1644
             inside the inferior, and then stop again immediately when
1645
             the user tries to resume the execution in the inferior.
1646
             This is a classic race that we should try to fix one day.  */
1647
      SetConsoleCtrlHandler (&ctrl_c_handler, TRUE);
1648
      retval = get_windows_debug_event (ops, pid, ourstatus);
1649
      SetConsoleCtrlHandler (&ctrl_c_handler, FALSE);
1650
 
1651
      if (retval)
1652
        return ptid_build (current_event.dwProcessId, 0, retval);
1653
      else
1654
        {
1655
          int detach = 0;
1656
 
1657
          if (deprecated_ui_loop_hook != NULL)
1658
            detach = deprecated_ui_loop_hook (0);
1659
 
1660
          if (detach)
1661
            windows_kill_inferior (ops);
1662
        }
1663
    }
1664
}
1665
 
1666
static void
1667
do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
1668
{
1669
  extern int stop_after_trap;
1670
  int i;
1671
  struct inferior *inf;
1672
  struct thread_info *tp;
1673
 
1674
  last_sig = TARGET_SIGNAL_0;
1675
  event_count = 0;
1676
  exception_count = 0;
1677
  open_process_used = 0;
1678
  debug_registers_changed = 0;
1679
  debug_registers_used = 0;
1680
  for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1681
    dr[i] = 0;
1682
#ifdef __CYGWIN__
1683
  cygwin_load_start = cygwin_load_end = 0;
1684
#endif
1685
  current_event.dwProcessId = pid;
1686
  memset (&current_event, 0, sizeof (current_event));
1687
  push_target (ops);
1688
  disable_breakpoints_in_shlibs ();
1689
  windows_clear_solib ();
1690
  clear_proceed_status ();
1691
  init_wait_for_inferior ();
1692
 
1693
  inf = current_inferior ();
1694
  inferior_appeared (inf, pid);
1695
  inf->attach_flag = attaching;
1696
 
1697
  /* Make the new process the current inferior, so terminal handling
1698
     can rely on it.  When attaching, we don't know about any thread
1699
     id here, but that's OK --- nothing should be referencing the
1700
     current thread until we report an event out of windows_wait.  */
1701
  inferior_ptid = pid_to_ptid (pid);
1702
 
1703
  terminal_init_inferior_with_pgrp (pid);
1704
  target_terminal_inferior ();
1705
 
1706
  windows_initialization_done = 0;
1707
  inf->stop_soon = STOP_QUIETLY;
1708
  while (1)
1709
    {
1710
      stop_after_trap = 1;
1711
      wait_for_inferior (0);
1712
      tp = inferior_thread ();
1713
      if (tp->stop_signal != TARGET_SIGNAL_TRAP)
1714
        resume (0, tp->stop_signal);
1715
      else
1716
        break;
1717
    }
1718
 
1719
  windows_initialization_done = 1;
1720
  inf->stop_soon = NO_STOP_QUIETLY;
1721
  stop_after_trap = 0;
1722
  return;
1723
}
1724
 
1725
/* Try to set or remove a user privilege to the current process.  Return -1
1726
   if that fails, the previous setting of that privilege otherwise.
1727
 
1728
   This code is copied from the Cygwin source code and rearranged to allow
1729
   dynamically loading of the needed symbols from advapi32 which is only
1730
   available on NT/2K/XP. */
1731
static int
1732
set_process_privilege (const char *privilege, BOOL enable)
1733
{
1734
  HANDLE token_hdl = NULL;
1735
  LUID restore_priv;
1736
  TOKEN_PRIVILEGES new_priv, orig_priv;
1737
  int ret = -1;
1738
  DWORD size;
1739
 
1740
  if (!OpenProcessToken (GetCurrentProcess (),
1741
                         TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
1742
                         &token_hdl))
1743
    goto out;
1744
 
1745
  if (!LookupPrivilegeValueA (NULL, privilege, &restore_priv))
1746
    goto out;
1747
 
1748
  new_priv.PrivilegeCount = 1;
1749
  new_priv.Privileges[0].Luid = restore_priv;
1750
  new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
1751
 
1752
  if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
1753
                              sizeof orig_priv, &orig_priv, &size))
1754
    goto out;
1755
#if 0
1756
  /* Disabled, otherwise every `attach' in an unprivileged user session
1757
     would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1758
     windows_attach(). */
1759
  /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1760
     be enabled. GetLastError () returns an correct error code, though. */
1761
  if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
1762
    goto out;
1763
#endif
1764
 
1765
  ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
1766
 
1767
out:
1768
  if (token_hdl)
1769
    CloseHandle (token_hdl);
1770
 
1771
  return ret;
1772
}
1773
 
1774
/* Attach to process PID, then initialize for debugging it.  */
1775
static void
1776
windows_attach (struct target_ops *ops, char *args, int from_tty)
1777
{
1778
  BOOL ok;
1779
  DWORD pid;
1780
 
1781
  pid = parse_pid_to_attach (args);
1782
 
1783
  if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
1784
    {
1785
      printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1786
      printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1787
    }
1788
 
1789
  windows_init_thread_list ();
1790
  ok = DebugActiveProcess (pid);
1791
  saw_create = 0;
1792
 
1793
#ifdef __CYGWIN__
1794
  if (!ok)
1795
    {
1796
      /* Try fall back to Cygwin pid */
1797
      pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
1798
 
1799
      if (pid > 0)
1800
        ok = DebugActiveProcess (pid);
1801
  }
1802
#endif
1803
 
1804
  if (!ok)
1805
    error (_("Can't attach to process."));
1806
 
1807
  DebugSetProcessKillOnExit (FALSE);
1808
 
1809
  if (from_tty)
1810
    {
1811
      char *exec_file = (char *) get_exec_file (0);
1812
 
1813
      if (exec_file)
1814
        printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1815
                           target_pid_to_str (pid_to_ptid (pid)));
1816
      else
1817
        printf_unfiltered ("Attaching to %s\n",
1818
                           target_pid_to_str (pid_to_ptid (pid)));
1819
 
1820
      gdb_flush (gdb_stdout);
1821
    }
1822
 
1823
  do_initial_windows_stuff (ops, pid, 1);
1824
  target_terminal_ours ();
1825
}
1826
 
1827
static void
1828
windows_detach (struct target_ops *ops, char *args, int from_tty)
1829
{
1830
  int detached = 1;
1831
 
1832
  ptid_t ptid = {-1};
1833
  windows_resume (ops, ptid, 0, TARGET_SIGNAL_0);
1834
 
1835
  if (!DebugActiveProcessStop (current_event.dwProcessId))
1836
    {
1837
      error (_("Can't detach process %lu (error %lu)"),
1838
             current_event.dwProcessId, GetLastError ());
1839
      detached = 0;
1840
    }
1841
  DebugSetProcessKillOnExit (FALSE);
1842
 
1843
  if (detached && from_tty)
1844
    {
1845
      char *exec_file = get_exec_file (0);
1846
      if (exec_file == 0)
1847
        exec_file = "";
1848
      printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1849
                         current_event.dwProcessId);
1850
      gdb_flush (gdb_stdout);
1851
    }
1852
 
1853
  inferior_ptid = null_ptid;
1854
  detach_inferior (current_event.dwProcessId);
1855
 
1856
  unpush_target (ops);
1857
}
1858
 
1859
static char *
1860
windows_pid_to_exec_file (int pid)
1861
{
1862
  static char path[__PMAX];
1863
#ifdef __CYGWIN__
1864
  /* Try to find exe name as symlink target of /proc/<pid>/exe */
1865
  int nchars;
1866
  char procexe[sizeof ("/proc/4294967295/exe")];
1867
  sprintf (procexe, "/proc/%u/exe", pid);
1868
  nchars = readlink (procexe, path, sizeof(path));
1869
  if (nchars > 0 && nchars < sizeof (path))
1870
    {
1871
      path[nchars] = '\0';      /* Got it */
1872
      return path;
1873
    }
1874
#endif
1875
 
1876
  /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
1877
     of gdb, or we're trying to debug a non-Cygwin windows executable. */
1878
  if (!get_module_name (0, path))
1879
    path[0] = '\0';
1880
 
1881
  return path;
1882
}
1883
 
1884
/* Print status information about what we're accessing.  */
1885
 
1886
static void
1887
windows_files_info (struct target_ops *ignore)
1888
{
1889
  struct inferior *inf = current_inferior ();
1890
 
1891
  printf_unfiltered ("\tUsing the running image of %s %s.\n",
1892
                     inf->attach_flag ? "attached" : "child",
1893
                     target_pid_to_str (inferior_ptid));
1894
}
1895
 
1896
static void
1897
windows_open (char *arg, int from_tty)
1898
{
1899
  error (_("Use the \"run\" command to start a Unix child process."));
1900
}
1901
 
1902
/* Modify CreateProcess parameters for use of a new separate console.
1903
   Parameters are:
1904
   *FLAGS: DWORD parameter for general process creation flags.
1905
   *SI: STARTUPINFO structure, for which the console window size and
1906
   console buffer size is filled in if GDB is running in a console.
1907
   to create the new console.
1908
   The size of the used font is not available on all versions of
1909
   Windows OS.  Furthermore, the current font might not be the default
1910
   font, but this is still better than before.
1911
   If the windows and buffer sizes are computed,
1912
   SI->DWFLAGS is changed so that this information is used
1913
   by CreateProcess function.  */
1914
 
1915
static void
1916
windows_set_console_info (STARTUPINFO *si, DWORD *flags)
1917
{
1918
  HANDLE hconsole = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE,
1919
                                FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1920
 
1921
  if (hconsole != INVALID_HANDLE_VALUE)
1922
    {
1923
      CONSOLE_SCREEN_BUFFER_INFO sbinfo;
1924
      COORD font_size;
1925
      CONSOLE_FONT_INFO cfi;
1926
 
1927
      GetCurrentConsoleFont (hconsole, FALSE, &cfi);
1928
      font_size = GetConsoleFontSize (hconsole, cfi.nFont);
1929
      GetConsoleScreenBufferInfo(hconsole, &sbinfo);
1930
      si->dwXSize = sbinfo.srWindow.Right - sbinfo.srWindow.Left + 1;
1931
      si->dwYSize = sbinfo.srWindow.Bottom - sbinfo.srWindow.Top + 1;
1932
      if (font_size.X)
1933
        si->dwXSize *= font_size.X;
1934
      else
1935
        si->dwXSize *= 8;
1936
      if (font_size.Y)
1937
        si->dwYSize *= font_size.Y;
1938
      else
1939
        si->dwYSize *= 12;
1940
      si->dwXCountChars = sbinfo.dwSize.X;
1941
      si->dwYCountChars = sbinfo.dwSize.Y;
1942
      si->dwFlags |= STARTF_USESIZE | STARTF_USECOUNTCHARS;
1943
    }
1944
  *flags |= CREATE_NEW_CONSOLE;
1945
}
1946
 
1947
/* Start an inferior windows child process and sets inferior_ptid to its pid.
1948
   EXEC_FILE is the file to run.
1949
   ALLARGS is a string containing the arguments to the program.
1950
   ENV is the environment vector to pass.  Errors reported with error().  */
1951
 
1952
static void
1953
windows_create_inferior (struct target_ops *ops, char *exec_file,
1954
                       char *allargs, char **in_env, int from_tty)
1955
{
1956
  STARTUPINFO si;
1957
#ifdef __CYGWIN__
1958
  cygwin_buf_t real_path[__PMAX];
1959
  cygwin_buf_t shell[__PMAX]; /* Path to shell */
1960
  const char *sh;
1961
  cygwin_buf_t *toexec;
1962
  cygwin_buf_t *cygallargs;
1963
  cygwin_buf_t *args;
1964
  size_t len;
1965
  int tty;
1966
  int ostdin, ostdout, ostderr;
1967
#else
1968
  char real_path[__PMAX];
1969
  char shell[__PMAX]; /* Path to shell */
1970
  char *toexec;
1971
  char *args;
1972
  HANDLE tty;
1973
#endif
1974
  PROCESS_INFORMATION pi;
1975
  BOOL ret;
1976
  DWORD flags = 0;
1977
  const char *inferior_io_terminal = get_inferior_io_terminal ();
1978
 
1979
  if (!exec_file)
1980
    error (_("No executable specified, use `target exec'."));
1981
 
1982
  memset (&si, 0, sizeof (si));
1983
  si.cb = sizeof (si);
1984
 
1985
  if (new_group)
1986
    flags |= CREATE_NEW_PROCESS_GROUP;
1987
 
1988
  if (new_console)
1989
    windows_set_console_info (&si, &flags);
1990
 
1991
#ifdef __CYGWIN__
1992
  if (!useshell)
1993
    {
1994
      flags |= DEBUG_ONLY_THIS_PROCESS;
1995
      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, exec_file, real_path,
1996
                            __PMAX * sizeof (cygwin_buf_t)) < 0)
1997
        error (_("Error starting executable: %d"), errno);
1998
      toexec = real_path;
1999
#ifdef __USEWIDE
2000
      len = mbstowcs (NULL, allargs, 0) + 1;
2001
      if (len == (size_t) -1)
2002
        error (_("Error starting executable: %d"), errno);
2003
      cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
2004
      mbstowcs (cygallargs, allargs, len);
2005
#else
2006
      cygallargs = allargs;
2007
#endif
2008
    }
2009
  else
2010
    {
2011
      sh = getenv ("SHELL");
2012
      if (!sh)
2013
        sh = "/bin/sh";
2014
      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, __PMAX) < 0)
2015
        error (_("Error starting executable via shell: %d"), errno);
2016
#ifdef __USEWIDE
2017
      len = sizeof (L" -c 'exec  '") + mbstowcs (NULL, exec_file, 0)
2018
            + mbstowcs (NULL, allargs, 0) + 2;
2019
      cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
2020
      swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs);
2021
#else
2022
      cygallargs = (char *) alloca (sizeof (" -c 'exec  '") + strlen (exec_file)
2023
                                    + strlen (allargs) + 2);
2024
      sprintf (cygallargs, " -c 'exec %s %s'", exec_file, allargs);
2025
#endif
2026
      toexec = shell;
2027
      flags |= DEBUG_PROCESS;
2028
    }
2029
 
2030
#ifdef __USEWIDE
2031
  args = (cygwin_buf_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
2032
                                  * sizeof (wchar_t));
2033
  wcscpy (args, toexec);
2034
  wcscat (args, L" ");
2035
  wcscat (args, cygallargs);
2036
#else
2037
  args = (cygwin_buf_t *) alloca (strlen (toexec) + strlen (cygallargs) + 2);
2038
  strcpy (args, toexec);
2039
  strcat (args, " ");
2040
  strcat (args, cygallargs);
2041
#endif
2042
 
2043
  /* Prepare the environment vars for CreateProcess.  */
2044
  cygwin_internal (CW_SYNC_WINENV);
2045
 
2046
  if (!inferior_io_terminal)
2047
    tty = ostdin = ostdout = ostderr = -1;
2048
  else
2049
    {
2050
      tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
2051
      if (tty < 0)
2052
        {
2053
          print_sys_errmsg (inferior_io_terminal, errno);
2054
          ostdin = ostdout = ostderr = -1;
2055
        }
2056
      else
2057
        {
2058
          ostdin = dup (0);
2059
          ostdout = dup (1);
2060
          ostderr = dup (2);
2061
          dup2 (tty, 0);
2062
          dup2 (tty, 1);
2063
          dup2 (tty, 2);
2064
        }
2065
    }
2066
 
2067
  windows_init_thread_list ();
2068
  ret = CreateProcess (0,
2069
                       args,    /* command line */
2070
                       NULL,    /* Security */
2071
                       NULL,    /* thread */
2072
                       TRUE,    /* inherit handles */
2073
                       flags,   /* start flags */
2074
                       NULL,    /* environment */
2075
                       NULL,    /* current directory */
2076
                       &si,
2077
                       &pi);
2078
  if (tty >= 0)
2079
    {
2080
      close (tty);
2081
      dup2 (ostdin, 0);
2082
      dup2 (ostdout, 1);
2083
      dup2 (ostderr, 2);
2084
      close (ostdin);
2085
      close (ostdout);
2086
      close (ostderr);
2087
    }
2088
#else
2089
  toexec = exec_file;
2090
  args = alloca (strlen (toexec) + strlen (allargs) + 2);
2091
  strcpy (args, toexec);
2092
  strcat (args, " ");
2093
  strcat (args, allargs);
2094
 
2095
  flags |= DEBUG_ONLY_THIS_PROCESS;
2096
 
2097
  if (!inferior_io_terminal)
2098
    tty = INVALID_HANDLE_VALUE;
2099
  else
2100
    {
2101
      SECURITY_ATTRIBUTES sa;
2102
      sa.nLength = sizeof(sa);
2103
      sa.lpSecurityDescriptor = 0;
2104
      sa.bInheritHandle = TRUE;
2105
      tty = CreateFileA (inferior_io_terminal, GENERIC_READ | GENERIC_WRITE,
2106
                         0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
2107
      if (tty == INVALID_HANDLE_VALUE)
2108
        warning (_("Warning: Failed to open TTY %s, error %#x."),
2109
                 inferior_io_terminal, (unsigned) GetLastError ());
2110
      else
2111
        {
2112
          si.hStdInput = tty;
2113
          si.hStdOutput = tty;
2114
          si.hStdError = tty;
2115
          si.dwFlags |= STARTF_USESTDHANDLES;
2116
        }
2117
    }
2118
 
2119
  windows_init_thread_list ();
2120
  ret = CreateProcessA (0,
2121
                        args,   /* command line */
2122
                        NULL,   /* Security */
2123
                        NULL,   /* thread */
2124
                        TRUE,   /* inherit handles */
2125
                        flags,  /* start flags */
2126
                        NULL,   /* environment */
2127
                        NULL,   /* current directory */
2128
                        &si,
2129
                        &pi);
2130
  if (tty != INVALID_HANDLE_VALUE)
2131
    CloseHandle (tty);
2132
#endif
2133
 
2134
  if (!ret)
2135
    error (_("Error creating process %s, (error %d)."),
2136
           exec_file, (unsigned) GetLastError ());
2137
 
2138
  CloseHandle (pi.hThread);
2139
  CloseHandle (pi.hProcess);
2140
 
2141
  if (useshell && shell[0] != '\0')
2142
    saw_create = -1;
2143
  else
2144
    saw_create = 0;
2145
 
2146
  do_initial_windows_stuff (ops, pi.dwProcessId, 0);
2147
 
2148
  /* windows_continue (DBG_CONTINUE, -1); */
2149
}
2150
 
2151
static void
2152
windows_mourn_inferior (struct target_ops *ops)
2153
{
2154
  (void) windows_continue (DBG_CONTINUE, -1);
2155
  i386_cleanup_dregs();
2156
  if (open_process_used)
2157
    {
2158
      CHECK (CloseHandle (current_process_handle));
2159
      open_process_used = 0;
2160
    }
2161
  unpush_target (ops);
2162
  generic_mourn_inferior ();
2163
}
2164
 
2165
/* Send a SIGINT to the process group.  This acts just like the user typed a
2166
   ^C on the controlling terminal. */
2167
 
2168
static void
2169
windows_stop (ptid_t ptid)
2170
{
2171
  DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
2172
  CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
2173
  registers_changed ();         /* refresh register state */
2174
}
2175
 
2176
static int
2177
windows_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len,
2178
                   int write, struct mem_attrib *mem,
2179
                   struct target_ops *target)
2180
{
2181
  SIZE_T done = 0;
2182
  if (write)
2183
    {
2184
      DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
2185
                  len, (DWORD) (uintptr_t) memaddr));
2186
      if (!WriteProcessMemory (current_process_handle,
2187
                               (LPVOID) (uintptr_t) memaddr, our,
2188
                               len, &done))
2189
        done = 0;
2190
      FlushInstructionCache (current_process_handle,
2191
                             (LPCVOID) (uintptr_t) memaddr, len);
2192
    }
2193
  else
2194
    {
2195
      DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
2196
                  len, (DWORD) (uintptr_t) memaddr));
2197
      if (!ReadProcessMemory (current_process_handle,
2198
                              (LPCVOID) (uintptr_t) memaddr, our,
2199
                              len, &done))
2200
        done = 0;
2201
    }
2202
  return done;
2203
}
2204
 
2205
static void
2206
windows_kill_inferior (struct target_ops *ops)
2207
{
2208
  CHECK (TerminateProcess (current_process_handle, 0));
2209
 
2210
  for (;;)
2211
    {
2212
      if (!windows_continue (DBG_CONTINUE, -1))
2213
        break;
2214
      if (!WaitForDebugEvent (&current_event, INFINITE))
2215
        break;
2216
      if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
2217
        break;
2218
    }
2219
 
2220
  target_mourn_inferior ();     /* or just windows_mourn_inferior? */
2221
}
2222
 
2223
static void
2224
windows_prepare_to_store (struct regcache *regcache)
2225
{
2226
  /* Do nothing, since we can store individual regs */
2227
}
2228
 
2229
static int
2230
windows_can_run (void)
2231
{
2232
  return 1;
2233
}
2234
 
2235
static void
2236
windows_close (int x)
2237
{
2238
  DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n",
2239
                PIDGET (inferior_ptid)));
2240
}
2241
 
2242
/* Convert pid to printable format. */
2243
static char *
2244
windows_pid_to_str (struct target_ops *ops, ptid_t ptid)
2245
{
2246
  static char buf[80];
2247
 
2248
  if (ptid_get_tid (ptid) != 0)
2249
    {
2250
      snprintf (buf, sizeof (buf), "Thread %d.0x%lx",
2251
                ptid_get_pid (ptid), ptid_get_tid (ptid));
2252
      return buf;
2253
    }
2254
 
2255
  return normal_pid_to_str (ptid);
2256
}
2257
 
2258
static LONGEST
2259
windows_xfer_shared_libraries (struct target_ops *ops,
2260
                             enum target_object object, const char *annex,
2261
                             gdb_byte *readbuf, const gdb_byte *writebuf,
2262
                             ULONGEST offset, LONGEST len)
2263
{
2264
  struct obstack obstack;
2265
  const char *buf;
2266
  LONGEST len_avail;
2267
  struct so_list *so;
2268
 
2269
  if (writebuf)
2270
    return -1;
2271
 
2272
  obstack_init (&obstack);
2273
  obstack_grow_str (&obstack, "<library-list>\n");
2274
  for (so = solib_start.next; so; so = so->next)
2275
    windows_xfer_shared_library (so->so_name, (CORE_ADDR) (uintptr_t) so->lm_info->load_addr,
2276
                                 target_gdbarch, &obstack);
2277
  obstack_grow_str0 (&obstack, "</library-list>\n");
2278
 
2279
  buf = obstack_finish (&obstack);
2280
  len_avail = strlen (buf);
2281
  if (offset >= len_avail)
2282
    return 0;
2283
 
2284
  if (len > len_avail - offset)
2285
    len = len_avail - offset;
2286
  memcpy (readbuf, buf + offset, len);
2287
 
2288
  obstack_free (&obstack, NULL);
2289
  return len;
2290
}
2291
 
2292
static LONGEST
2293
windows_xfer_partial (struct target_ops *ops, enum target_object object,
2294
                    const char *annex, gdb_byte *readbuf,
2295
                    const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
2296
{
2297
  switch (object)
2298
    {
2299
    case TARGET_OBJECT_MEMORY:
2300
      if (readbuf)
2301
        return (*ops->deprecated_xfer_memory) (offset, readbuf,
2302
                                               len, 0/*read*/, NULL, ops);
2303
      if (writebuf)
2304
        return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf,
2305
                                               len, 1/*write*/, NULL, ops);
2306
      return -1;
2307
 
2308
    case TARGET_OBJECT_LIBRARIES:
2309
      return windows_xfer_shared_libraries (ops, object, annex, readbuf,
2310
                                          writebuf, offset, len);
2311
 
2312
    default:
2313
      if (ops->beneath != NULL)
2314
        return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
2315
                                              readbuf, writebuf, offset, len);
2316
      return -1;
2317
    }
2318
}
2319
 
2320
/* Provide thread local base, i.e. Thread Information Block address.
2321
   Returns 1 if ptid is found and sets *ADDR to thread_local_base.  */
2322
 
2323
static int
2324
windows_get_tib_address (ptid_t ptid, CORE_ADDR *addr)
2325
{
2326
  thread_info *th;
2327
 
2328
  th = thread_rec (ptid_get_tid (ptid), 0);
2329
  if (th == NULL)
2330
    return 0;
2331
 
2332
  if (addr != NULL)
2333
    *addr = th->thread_local_base;
2334
 
2335
  return 1;
2336
}
2337
 
2338
static ptid_t
2339
windows_get_ada_task_ptid (long lwp, long thread)
2340
{
2341
  return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
2342
}
2343
 
2344
static void
2345
init_windows_ops (void)
2346
{
2347
  windows_ops.to_shortname = "child";
2348
  windows_ops.to_longname = "Win32 child process";
2349
  windows_ops.to_doc = "Win32 child process (started by the \"run\" command).";
2350
  windows_ops.to_open = windows_open;
2351
  windows_ops.to_close = windows_close;
2352
  windows_ops.to_attach = windows_attach;
2353
  windows_ops.to_attach_no_wait = 1;
2354
  windows_ops.to_detach = windows_detach;
2355
  windows_ops.to_resume = windows_resume;
2356
  windows_ops.to_wait = windows_wait;
2357
  windows_ops.to_fetch_registers = windows_fetch_inferior_registers;
2358
  windows_ops.to_store_registers = windows_store_inferior_registers;
2359
  windows_ops.to_prepare_to_store = windows_prepare_to_store;
2360
  windows_ops.deprecated_xfer_memory = windows_xfer_memory;
2361
  windows_ops.to_xfer_partial = windows_xfer_partial;
2362
  windows_ops.to_files_info = windows_files_info;
2363
  windows_ops.to_insert_breakpoint = memory_insert_breakpoint;
2364
  windows_ops.to_remove_breakpoint = memory_remove_breakpoint;
2365
  windows_ops.to_terminal_init = terminal_init_inferior;
2366
  windows_ops.to_terminal_inferior = terminal_inferior;
2367
  windows_ops.to_terminal_ours_for_output = terminal_ours_for_output;
2368
  windows_ops.to_terminal_ours = terminal_ours;
2369
  windows_ops.to_terminal_save_ours = terminal_save_ours;
2370
  windows_ops.to_terminal_info = child_terminal_info;
2371
  windows_ops.to_kill = windows_kill_inferior;
2372
  windows_ops.to_create_inferior = windows_create_inferior;
2373
  windows_ops.to_mourn_inferior = windows_mourn_inferior;
2374
  windows_ops.to_can_run = windows_can_run;
2375
  windows_ops.to_thread_alive = windows_thread_alive;
2376
  windows_ops.to_pid_to_str = windows_pid_to_str;
2377
  windows_ops.to_stop = windows_stop;
2378
  windows_ops.to_stratum = process_stratum;
2379
  windows_ops.to_has_all_memory = default_child_has_all_memory;
2380
  windows_ops.to_has_memory = default_child_has_memory;
2381
  windows_ops.to_has_stack = default_child_has_stack;
2382
  windows_ops.to_has_registers = default_child_has_registers;
2383
  windows_ops.to_has_execution = default_child_has_execution;
2384
  windows_ops.to_pid_to_exec_file = windows_pid_to_exec_file;
2385
  windows_ops.to_get_ada_task_ptid = windows_get_ada_task_ptid;
2386
  windows_ops.to_get_tib_address = windows_get_tib_address;
2387
 
2388
  i386_use_watchpoints (&windows_ops);
2389
 
2390
  i386_dr_low.set_control = cygwin_set_dr7;
2391
  i386_dr_low.set_addr = cygwin_set_dr;
2392
  i386_dr_low.reset_addr = NULL;
2393
  i386_dr_low.get_status = cygwin_get_dr6;
2394
 
2395
  /* i386_dr_low.debug_register_length field is set by
2396
     calling i386_set_debug_register_length function
2397
     in processor windows specific native file.  */
2398
 
2399
  windows_ops.to_magic = OPS_MAGIC;
2400
}
2401
 
2402
static void
2403
set_windows_aliases (char *argv0)
2404
{
2405
  add_info_alias ("dll", "sharedlibrary", 1);
2406
}
2407
 
2408
void
2409
_initialize_windows_nat (void)
2410
{
2411
  struct cmd_list_element *c;
2412
 
2413
  init_windows_ops ();
2414
 
2415
#ifdef __CYGWIN__
2416
  cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
2417
#endif
2418
 
2419
  c = add_com ("dll-symbols", class_files, dll_symbol_command,
2420
               _("Load dll library symbols from FILE."));
2421
  set_cmd_completer (c, filename_completer);
2422
 
2423
  add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
2424
 
2425
  add_com_alias ("add-shared-symbol-files", "dll-symbols", class_alias, 1);
2426
 
2427
  add_com_alias ("assf", "dll-symbols", class_alias, 1);
2428
 
2429
#ifdef __CYGWIN__
2430
  add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
2431
Set use of shell to start subprocess."), _("\
2432
Show use of shell to start subprocess."), NULL,
2433
                           NULL,
2434
                           NULL, /* FIXME: i18n: */
2435
                           &setlist, &showlist);
2436
 
2437
  add_setshow_boolean_cmd ("cygwin-exceptions", class_support, &cygwin_exceptions, _("\
2438
Break when an exception is detected in the Cygwin DLL itself."), _("\
2439
Show whether gdb breaks on exceptions in the Cygwin DLL itself."), NULL,
2440
                           NULL,
2441
                           NULL, /* FIXME: i18n: */
2442
                           &setlist, &showlist);
2443
#endif
2444
 
2445
  add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\
2446
Set creation of new console when creating child process."), _("\
2447
Show creation of new console when creating child process."), NULL,
2448
                           NULL,
2449
                           NULL, /* FIXME: i18n: */
2450
                           &setlist, &showlist);
2451
 
2452
  add_setshow_boolean_cmd ("new-group", class_support, &new_group, _("\
2453
Set creation of new group when creating child process."), _("\
2454
Show creation of new group when creating child process."), NULL,
2455
                           NULL,
2456
                           NULL, /* FIXME: i18n: */
2457
                           &setlist, &showlist);
2458
 
2459
  add_setshow_boolean_cmd ("debugexec", class_support, &debug_exec, _("\
2460
Set whether to display execution in child process."), _("\
2461
Show whether to display execution in child process."), NULL,
2462
                           NULL,
2463
                           NULL, /* FIXME: i18n: */
2464
                           &setlist, &showlist);
2465
 
2466
  add_setshow_boolean_cmd ("debugevents", class_support, &debug_events, _("\
2467
Set whether to display kernel events in child process."), _("\
2468
Show whether to display kernel events in child process."), NULL,
2469
                           NULL,
2470
                           NULL, /* FIXME: i18n: */
2471
                           &setlist, &showlist);
2472
 
2473
  add_setshow_boolean_cmd ("debugmemory", class_support, &debug_memory, _("\
2474
Set whether to display memory accesses in child process."), _("\
2475
Show whether to display memory accesses in child process."), NULL,
2476
                           NULL,
2477
                           NULL, /* FIXME: i18n: */
2478
                           &setlist, &showlist);
2479
 
2480
  add_setshow_boolean_cmd ("debugexceptions", class_support,
2481
                           &debug_exceptions, _("\
2482
Set whether to display kernel exceptions in child process."), _("\
2483
Show whether to display kernel exceptions in child process."), NULL,
2484
                           NULL,
2485
                           NULL, /* FIXME: i18n: */
2486
                           &setlist, &showlist);
2487
 
2488
  init_w32_command_list ();
2489
 
2490
  add_cmd ("selector", class_info, display_selectors,
2491
           _("Display selectors infos."),
2492
           &info_w32_cmdlist);
2493
  add_target (&windows_ops);
2494
  deprecated_init_ui_hook = set_windows_aliases;
2495
}
2496
 
2497
/* Hardware watchpoint support, adapted from go32-nat.c code.  */
2498
 
2499
/* Pass the address ADDR to the inferior in the I'th debug register.
2500
   Here we just store the address in dr array, the registers will be
2501
   actually set up when windows_continue is called.  */
2502
static void
2503
cygwin_set_dr (int i, CORE_ADDR addr)
2504
{
2505
  if (i < 0 || i > 3)
2506
    internal_error (__FILE__, __LINE__,
2507
                    _("Invalid register %d in cygwin_set_dr.\n"), i);
2508
  dr[i] = addr;
2509
  debug_registers_changed = 1;
2510
  debug_registers_used = 1;
2511
}
2512
 
2513
/* Pass the value VAL to the inferior in the DR7 debug control
2514
   register.  Here we just store the address in D_REGS, the watchpoint
2515
   will be actually set up in windows_wait.  */
2516
static void
2517
cygwin_set_dr7 (unsigned long val)
2518
{
2519
  dr[7] = (CORE_ADDR) val;
2520
  debug_registers_changed = 1;
2521
  debug_registers_used = 1;
2522
}
2523
 
2524
/* Get the value of the DR6 debug status register from the inferior.
2525
   Here we just return the value stored in dr[6]
2526
   by the last call to thread_rec for current_event.dwThreadId id.  */
2527
static unsigned long
2528
cygwin_get_dr6 (void)
2529
{
2530
  return (unsigned long) dr[6];
2531
}
2532
 
2533
/* Determine if the thread referenced by "ptid" is alive
2534
   by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
2535
   it means that the thread has died.  Otherwise it is assumed to be alive. */
2536
static int
2537
windows_thread_alive (struct target_ops *ops, ptid_t ptid)
2538
{
2539
  int tid;
2540
 
2541
  gdb_assert (ptid_get_tid (ptid) != 0);
2542
  tid = ptid_get_tid (ptid);
2543
 
2544
  return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
2545
    FALSE : TRUE;
2546
}
2547
 
2548
void
2549
_initialize_check_for_gdb_ini (void)
2550
{
2551
  char *homedir;
2552
  if (inhibit_gdbinit)
2553
    return;
2554
 
2555
  homedir = getenv ("HOME");
2556
  if (homedir)
2557
    {
2558
      char *p;
2559
      char *oldini = (char *) alloca (strlen (homedir) +
2560
                                      sizeof ("/gdb.ini"));
2561
      strcpy (oldini, homedir);
2562
      p = strchr (oldini, '\0');
2563
      if (p > oldini && p[-1] != '/')
2564
        *p++ = '/';
2565
      strcpy (p, "gdb.ini");
2566
      if (access (oldini, 0) == 0)
2567
        {
2568
          int len = strlen (oldini);
2569
          char *newini = alloca (len + 1);
2570
          sprintf (newini, "%.*s.gdbinit",
2571
            (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
2572
          warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini);
2573
        }
2574
    }
2575
}
2576
 
2577
/* Define dummy functions which always return error for the rare cases where
2578
   these functions could not be found. */
2579
static BOOL WINAPI
2580
bad_DebugActiveProcessStop (DWORD w)
2581
{
2582
  return FALSE;
2583
}
2584
static BOOL WINAPI
2585
bad_DebugBreakProcess (HANDLE w)
2586
{
2587
  return FALSE;
2588
}
2589
static BOOL WINAPI
2590
bad_DebugSetProcessKillOnExit (BOOL w)
2591
{
2592
  return FALSE;
2593
}
2594
static BOOL WINAPI
2595
bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
2596
{
2597
  return FALSE;
2598
}
2599
 
2600
#ifdef __USEWIDE
2601
static DWORD WINAPI
2602
bad_GetModuleFileNameExW (HANDLE w, HMODULE x, LPWSTR y, DWORD z)
2603
{
2604
  return 0;
2605
}
2606
#else
2607
static DWORD WINAPI
2608
bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
2609
{
2610
  return 0;
2611
}
2612
#endif
2613
 
2614
static BOOL WINAPI
2615
bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
2616
{
2617
  return FALSE;
2618
}
2619
 
2620
static BOOL WINAPI
2621
bad_OpenProcessToken (HANDLE w, DWORD x, PHANDLE y)
2622
{
2623
  return FALSE;
2624
}
2625
 
2626
static BOOL WINAPI
2627
bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
2628
{
2629
  f->nFont = 0;
2630
  return 1;
2631
}
2632
static COORD WINAPI
2633
bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
2634
{
2635
  COORD size;
2636
  size.X = 8;
2637
  size.Y = 12;
2638
  return size;
2639
}
2640
 
2641
/* Load any functions which may not be available in ancient versions
2642
   of Windows. */
2643
void
2644
_initialize_loadable (void)
2645
{
2646
  HMODULE hm = NULL;
2647
 
2648
  hm = LoadLibrary ("kernel32.dll");
2649
  if (hm)
2650
    {
2651
      DebugActiveProcessStop = (void *)
2652
        GetProcAddress (hm, "DebugActiveProcessStop");
2653
      DebugBreakProcess = (void *)
2654
        GetProcAddress (hm, "DebugBreakProcess");
2655
      DebugSetProcessKillOnExit = (void *)
2656
        GetProcAddress (hm, "DebugSetProcessKillOnExit");
2657
      GetConsoleFontSize = (void *)
2658
        GetProcAddress (hm, "GetConsoleFontSize");
2659
      GetCurrentConsoleFont = (void *)
2660
        GetProcAddress (hm, "GetCurrentConsoleFont");
2661
    }
2662
 
2663
  /* Set variables to dummy versions of these processes if the function
2664
     wasn't found in kernel32.dll. */
2665
  if (!DebugBreakProcess)
2666
    DebugBreakProcess = bad_DebugBreakProcess;
2667
  if (!DebugActiveProcessStop || !DebugSetProcessKillOnExit)
2668
    {
2669
      DebugActiveProcessStop = bad_DebugActiveProcessStop;
2670
      DebugSetProcessKillOnExit = bad_DebugSetProcessKillOnExit;
2671
    }
2672
  if (!GetConsoleFontSize)
2673
    GetConsoleFontSize = bad_GetConsoleFontSize;
2674
  if (!GetCurrentConsoleFont)
2675
    GetCurrentConsoleFont = bad_GetCurrentConsoleFont;
2676
 
2677
  /* Load optional functions used for retrieving filename information
2678
     associated with the currently debugged process or its dlls. */
2679
  hm = LoadLibrary ("psapi.dll");
2680
  if (hm)
2681
    {
2682
      EnumProcessModules = (void *)
2683
        GetProcAddress (hm, "EnumProcessModules");
2684
      GetModuleInformation = (void *)
2685
        GetProcAddress (hm, "GetModuleInformation");
2686
      GetModuleFileNameEx = (void *)
2687
        GetProcAddress (hm, GetModuleFileNameEx_name);
2688
    }
2689
 
2690
  if (!EnumProcessModules || !GetModuleInformation || !GetModuleFileNameEx)
2691
    {
2692
      /* Set variables to dummy versions of these processes if the function
2693
         wasn't found in psapi.dll. */
2694
      EnumProcessModules = bad_EnumProcessModules;
2695
      GetModuleInformation = bad_GetModuleInformation;
2696
      GetModuleFileNameEx = bad_GetModuleFileNameEx;
2697
      /* This will probably fail on Windows 9x/Me.  Let the user know that we're
2698
         missing some functionality. */
2699
      warning(_("cannot automatically find executable file or library to read symbols.\nUse \"file\" or \"dll\" command to load executable/libraries directly."));
2700
    }
2701
 
2702
  hm = LoadLibrary ("advapi32.dll");
2703
  if (hm)
2704
    {
2705
      OpenProcessToken = (void *) GetProcAddress (hm, "OpenProcessToken");
2706
      LookupPrivilegeValueA = (void *)
2707
        GetProcAddress (hm, "LookupPrivilegeValueA");
2708
      AdjustTokenPrivileges = (void *)
2709
        GetProcAddress (hm, "AdjustTokenPrivileges");
2710
      /* Only need to set one of these since if OpenProcessToken fails nothing
2711
         else is needed. */
2712
      if (!OpenProcessToken || !LookupPrivilegeValueA || !AdjustTokenPrivileges)
2713
        OpenProcessToken = bad_OpenProcessToken;
2714
    }
2715
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.