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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [windows-nat.c] - Blame information for rev 862

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

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

powered by: WebSVN 2.1.0

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