GDB (API)
/home/stan/gdb/src/gdb/windows-nat.c
Go to the documentation of this file.
00001 /* Target-vector operations for controlling windows child processes, for GDB.
00002 
00003    Copyright (C) 1995-2013 Free Software Foundation, Inc.
00004 
00005    Contributed by Cygnus Solutions, A Red Hat Company.
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 /* Originally by Steve Chamberlain, sac@cygnus.com */
00023 
00024 #include "defs.h"
00025 #include "frame.h"              /* required by inferior.h */
00026 #include "inferior.h"
00027 #include "target.h"
00028 #include "exceptions.h"
00029 #include "gdbcore.h"
00030 #include "command.h"
00031 #include "completer.h"
00032 #include "regcache.h"
00033 #include "top.h"
00034 #include <signal.h>
00035 #include <sys/types.h>
00036 #include <fcntl.h>
00037 #include <stdlib.h>
00038 #include <windows.h>
00039 #include <imagehlp.h>
00040 #include <psapi.h>
00041 #ifdef __CYGWIN__
00042 #include <wchar.h>
00043 #include <sys/cygwin.h>
00044 #include <cygwin/version.h>
00045 #endif
00046 #include <signal.h>
00047 
00048 #include "buildsym.h"
00049 #include "filenames.h"
00050 #include "symfile.h"
00051 #include "objfiles.h"
00052 #include "gdb_bfd.h"
00053 #include "gdb_obstack.h"
00054 #include "gdb_string.h"
00055 #include "gdbthread.h"
00056 #include "gdbcmd.h"
00057 #include <unistd.h>
00058 #include "exec.h"
00059 #include "solist.h"
00060 #include "solib.h"
00061 #include "xml-support.h"
00062 
00063 #include "i386-tdep.h"
00064 #include "i387-tdep.h"
00065 
00066 #include "windows-tdep.h"
00067 #include "windows-nat.h"
00068 #include "i386-nat.h"
00069 #include "complaints.h"
00070 
00071 #define AdjustTokenPrivileges           dyn_AdjustTokenPrivileges
00072 #define DebugActiveProcessStop          dyn_DebugActiveProcessStop
00073 #define DebugBreakProcess               dyn_DebugBreakProcess
00074 #define DebugSetProcessKillOnExit       dyn_DebugSetProcessKillOnExit
00075 #define EnumProcessModules              dyn_EnumProcessModules
00076 #define GetModuleInformation            dyn_GetModuleInformation
00077 #define LookupPrivilegeValueA           dyn_LookupPrivilegeValueA
00078 #define OpenProcessToken                dyn_OpenProcessToken
00079 #define GetConsoleFontSize              dyn_GetConsoleFontSize
00080 #define GetCurrentConsoleFont           dyn_GetCurrentConsoleFont
00081 
00082 static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
00083                                             DWORD, PTOKEN_PRIVILEGES, PDWORD);
00084 static BOOL WINAPI (*DebugActiveProcessStop) (DWORD);
00085 static BOOL WINAPI (*DebugBreakProcess) (HANDLE);
00086 static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
00087 static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
00088                                           LPDWORD);
00089 static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
00090                                             DWORD);
00091 static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
00092 static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
00093 static BOOL WINAPI (*GetCurrentConsoleFont) (HANDLE, BOOL,
00094                                              CONSOLE_FONT_INFO *);
00095 static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD);
00096 
00097 static struct target_ops windows_ops;
00098 
00099 #undef STARTUPINFO
00100 #undef CreateProcess
00101 #undef GetModuleFileNameEx
00102 
00103 #ifndef __CYGWIN__
00104 # define __PMAX (MAX_PATH + 1)
00105   static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD);
00106 # define STARTUPINFO STARTUPINFOA
00107 # define CreateProcess CreateProcessA
00108 # define GetModuleFileNameEx_name "GetModuleFileNameExA"
00109 # define bad_GetModuleFileNameEx bad_GetModuleFileNameExA
00110 #else
00111 # define __PMAX PATH_MAX
00112 /* The starting and ending address of the cygwin1.dll text segment.  */
00113   static CORE_ADDR cygwin_load_start;
00114   static CORE_ADDR cygwin_load_end;
00115 #   define __USEWIDE
00116     typedef wchar_t cygwin_buf_t;
00117     static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE,
00118                                                 LPWSTR, DWORD);
00119 #   define STARTUPINFO STARTUPINFOW
00120 #   define CreateProcess CreateProcessW
00121 #   define GetModuleFileNameEx_name "GetModuleFileNameExW"
00122 #   define bad_GetModuleFileNameEx bad_GetModuleFileNameExW
00123 #endif
00124 
00125 static int have_saved_context;  /* True if we've saved context from a
00126                                    cygwin signal.  */
00127 static CONTEXT saved_context;   /* Containes the saved context from a
00128                                    cygwin signal.  */
00129 
00130 /* If we're not using the old Cygwin header file set, define the
00131    following which never should have been in the generic Win32 API
00132    headers in the first place since they were our own invention...  */
00133 #ifndef _GNU_H_WINDOWS_H
00134 enum
00135   {
00136     FLAG_TRACE_BIT = 0x100,
00137     CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
00138   };
00139 #endif
00140 
00141 #ifndef CONTEXT_EXTENDED_REGISTERS
00142 /* This macro is only defined on ia32.  It only makes sense on this target,
00143    so define it as zero if not already defined.  */
00144 #define CONTEXT_EXTENDED_REGISTERS 0
00145 #endif
00146 
00147 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
00148         | CONTEXT_EXTENDED_REGISTERS
00149 
00150 static uintptr_t dr[8];
00151 static int debug_registers_changed;
00152 static int debug_registers_used;
00153 
00154 static int windows_initialization_done;
00155 #define DR6_CLEAR_VALUE 0xffff0ff0
00156 
00157 /* The string sent by cygwin when it processes a signal.
00158    FIXME: This should be in a cygwin include file.  */
00159 #ifndef _CYGWIN_SIGNAL_STRING
00160 #define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
00161 #endif
00162 
00163 #define CHECK(x)        check (x, __FILE__,__LINE__)
00164 #define DEBUG_EXEC(x)   if (debug_exec)         printf_unfiltered x
00165 #define DEBUG_EVENTS(x) if (debug_events)       printf_unfiltered x
00166 #define DEBUG_MEM(x)    if (debug_memory)       printf_unfiltered x
00167 #define DEBUG_EXCEPT(x) if (debug_exceptions)   printf_unfiltered x
00168 
00169 static void windows_stop (ptid_t);
00170 static int windows_thread_alive (struct target_ops *, ptid_t);
00171 static void windows_kill_inferior (struct target_ops *);
00172 
00173 static void cygwin_set_dr (int i, CORE_ADDR addr);
00174 static void cygwin_set_dr7 (unsigned long val);
00175 static CORE_ADDR cygwin_get_dr (int i);
00176 static unsigned long cygwin_get_dr6 (void);
00177 static unsigned long cygwin_get_dr7 (void);
00178 
00179 static enum gdb_signal last_sig = GDB_SIGNAL_0;
00180 /* Set if a signal was received from the debugged process.  */
00181 
00182 /* Thread information structure used to track information that is
00183    not available in gdb's thread structure.  */
00184 typedef struct thread_info_struct
00185   {
00186     struct thread_info_struct *next;
00187     DWORD id;
00188     HANDLE h;
00189     CORE_ADDR thread_local_base;
00190     char *name;
00191     int suspended;
00192     int reload_context;
00193     CONTEXT context;
00194     STACKFRAME sf;
00195   }
00196 thread_info;
00197 
00198 static thread_info thread_head;
00199 
00200 /* The process and thread handles for the above context.  */
00201 
00202 static DEBUG_EVENT current_event;       /* The current debug event from
00203                                            WaitForDebugEvent */
00204 static HANDLE current_process_handle;   /* Currently executing process */
00205 static thread_info *current_thread;     /* Info on currently selected thread */
00206 static DWORD main_thread_id;            /* Thread ID of the main thread */
00207 
00208 /* Counts of things.  */
00209 static int exception_count = 0;
00210 static int event_count = 0;
00211 static int saw_create;
00212 static int open_process_used = 0;
00213 
00214 /* User options.  */
00215 static int new_console = 0;
00216 #ifdef __CYGWIN__
00217 static int cygwin_exceptions = 0;
00218 #endif
00219 static int new_group = 1;
00220 static int debug_exec = 0;              /* show execution */
00221 static int debug_events = 0;            /* show events from kernel */
00222 static int debug_memory = 0;            /* show target memory accesses */
00223 static int debug_exceptions = 0;        /* show target exceptions */
00224 static int useshell = 0;                /* use shell for subprocesses */
00225 
00226 /* This vector maps GDB's idea of a register's number into an offset
00227    in the windows exception context vector.
00228 
00229    It also contains the bit mask needed to load the register in question.
00230 
00231    The contents of this table can only be computed by the units
00232    that provide CPU-specific support for Windows native debugging.
00233    These units should set the table by calling
00234    windows_set_context_register_offsets.
00235 
00236    One day we could read a reg, we could inspect the context we
00237    already have loaded, if it doesn't have the bit set that we need,
00238    we read that set of registers in using GetThreadContext.  If the
00239    context already contains what we need, we just unpack it.  Then to
00240    write a register, first we have to ensure that the context contains
00241    the other regs of the group, and then we copy the info in and set
00242    out bit.  */
00243 
00244 static const int *mappings;
00245 
00246 /* The function to use in order to determine whether a register is
00247    a segment register or not.  */
00248 static segment_register_p_ftype *segment_register_p;
00249 
00250 /* This vector maps the target's idea of an exception (extracted
00251    from the DEBUG_EVENT structure) to GDB's idea.  */
00252 
00253 struct xlate_exception
00254   {
00255     int them;
00256     enum gdb_signal us;
00257   };
00258 
00259 static const struct xlate_exception
00260   xlate[] =
00261 {
00262   {EXCEPTION_ACCESS_VIOLATION, GDB_SIGNAL_SEGV},
00263   {STATUS_STACK_OVERFLOW, GDB_SIGNAL_SEGV},
00264   {EXCEPTION_BREAKPOINT, GDB_SIGNAL_TRAP},
00265   {DBG_CONTROL_C, GDB_SIGNAL_INT},
00266   {EXCEPTION_SINGLE_STEP, GDB_SIGNAL_TRAP},
00267   {STATUS_FLOAT_DIVIDE_BY_ZERO, GDB_SIGNAL_FPE},
00268   {-1, -1}};
00269 
00270 /* Set the MAPPINGS static global to OFFSETS.
00271    See the description of MAPPINGS for more details.  */
00272 
00273 void
00274 windows_set_context_register_offsets (const int *offsets)
00275 {
00276   mappings = offsets;
00277 }
00278 
00279 /* See windows-nat.h.  */
00280 
00281 void
00282 windows_set_segment_register_p (segment_register_p_ftype *fun)
00283 {
00284   segment_register_p = fun;
00285 }
00286 
00287 static void
00288 check (BOOL ok, const char *file, int line)
00289 {
00290   if (!ok)
00291     printf_filtered ("error return %s:%d was %u\n", file, line,
00292                      (unsigned) GetLastError ());
00293 }
00294 
00295 /* Find a thread record given a thread id.  If GET_CONTEXT is not 0,
00296    then also retrieve the context for this thread.  If GET_CONTEXT is
00297    negative, then don't suspend the thread.  */
00298 static thread_info *
00299 thread_rec (DWORD id, int get_context)
00300 {
00301   thread_info *th;
00302 
00303   for (th = &thread_head; (th = th->next) != NULL;)
00304     if (th->id == id)
00305       {
00306         if (!th->suspended && get_context)
00307           {
00308             if (get_context > 0 && id != current_event.dwThreadId)
00309               {
00310                 if (SuspendThread (th->h) == (DWORD) -1)
00311                   {
00312                     DWORD err = GetLastError ();
00313 
00314                     warning (_("SuspendThread (tid=0x%x) failed."
00315                                " (winerr %u)"),
00316                              (unsigned) id, (unsigned) err);
00317                     return NULL;
00318                   }
00319                 th->suspended = 1;
00320               }
00321             else if (get_context < 0)
00322               th->suspended = -1;
00323             th->reload_context = 1;
00324           }
00325         return th;
00326       }
00327 
00328   return NULL;
00329 }
00330 
00331 /* Add a thread to the thread list.  */
00332 static thread_info *
00333 windows_add_thread (ptid_t ptid, HANDLE h, void *tlb)
00334 {
00335   thread_info *th;
00336   DWORD id;
00337 
00338   gdb_assert (ptid_get_tid (ptid) != 0);
00339 
00340   id = ptid_get_tid (ptid);
00341 
00342   if ((th = thread_rec (id, FALSE)))
00343     return th;
00344 
00345   th = XZALLOC (thread_info);
00346   th->id = id;
00347   th->h = h;
00348   th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb;
00349   th->next = thread_head.next;
00350   thread_head.next = th;
00351   add_thread (ptid);
00352   /* Set the debug registers for the new thread if they are used.  */
00353   if (debug_registers_used)
00354     {
00355       /* Only change the value of the debug registers.  */
00356       th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
00357       CHECK (GetThreadContext (th->h, &th->context));
00358       th->context.Dr0 = dr[0];
00359       th->context.Dr1 = dr[1];
00360       th->context.Dr2 = dr[2];
00361       th->context.Dr3 = dr[3];
00362       th->context.Dr6 = DR6_CLEAR_VALUE;
00363       th->context.Dr7 = dr[7];
00364       CHECK (SetThreadContext (th->h, &th->context));
00365       th->context.ContextFlags = 0;
00366     }
00367   return th;
00368 }
00369 
00370 /* Clear out any old thread list and reintialize it to a
00371    pristine state.  */
00372 static void
00373 windows_init_thread_list (void)
00374 {
00375   thread_info *th = &thread_head;
00376 
00377   DEBUG_EVENTS (("gdb: windows_init_thread_list\n"));
00378   init_thread_list ();
00379   while (th->next != NULL)
00380     {
00381       thread_info *here = th->next;
00382       th->next = here->next;
00383       xfree (here);
00384     }
00385   thread_head.next = NULL;
00386 }
00387 
00388 /* Delete a thread from the list of threads.  */
00389 static void
00390 windows_delete_thread (ptid_t ptid, DWORD exit_code)
00391 {
00392   thread_info *th;
00393   DWORD id;
00394 
00395   gdb_assert (ptid_get_tid (ptid) != 0);
00396 
00397   id = ptid_get_tid (ptid);
00398 
00399   if (info_verbose)
00400     printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid));
00401   else if (print_thread_events && id != main_thread_id)
00402     printf_unfiltered (_("[%s exited with code %u]\n"),
00403                        target_pid_to_str (ptid), (unsigned) exit_code);
00404   delete_thread (ptid);
00405 
00406   for (th = &thread_head;
00407        th->next != NULL && th->next->id != id;
00408        th = th->next)
00409     continue;
00410 
00411   if (th->next != NULL)
00412     {
00413       thread_info *here = th->next;
00414       th->next = here->next;
00415       xfree (here);
00416     }
00417 }
00418 
00419 static void
00420 do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
00421 {
00422   char *context_offset = ((char *) &current_thread->context) + mappings[r];
00423   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00424   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00425   long l;
00426 
00427   if (!current_thread)
00428     return;     /* Windows sometimes uses a non-existent thread id in its
00429                    events.  */
00430 
00431   if (current_thread->reload_context)
00432     {
00433 #ifdef __COPY_CONTEXT_SIZE
00434       if (have_saved_context)
00435         {
00436           /* Lie about where the program actually is stopped since
00437              cygwin has informed us that we should consider the signal
00438              to have occurred at another location which is stored in
00439              "saved_context.  */
00440           memcpy (&current_thread->context, &saved_context,
00441                   __COPY_CONTEXT_SIZE);
00442           have_saved_context = 0;
00443         }
00444       else
00445 #endif
00446         {
00447           thread_info *th = current_thread;
00448           th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
00449           GetThreadContext (th->h, &th->context);
00450           /* Copy dr values from that thread.
00451              But only if there were not modified since last stop.
00452              PR gdb/2388 */
00453           if (!debug_registers_changed)
00454             {
00455               dr[0] = th->context.Dr0;
00456               dr[1] = th->context.Dr1;
00457               dr[2] = th->context.Dr2;
00458               dr[3] = th->context.Dr3;
00459               dr[6] = th->context.Dr6;
00460               dr[7] = th->context.Dr7;
00461             }
00462         }
00463       current_thread->reload_context = 0;
00464     }
00465 
00466   if (r == I387_FISEG_REGNUM (tdep))
00467     {
00468       l = *((long *) context_offset) & 0xffff;
00469       regcache_raw_supply (regcache, r, (char *) &l);
00470     }
00471   else if (r == I387_FOP_REGNUM (tdep))
00472     {
00473       l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
00474       regcache_raw_supply (regcache, r, (char *) &l);
00475     }
00476   else if (segment_register_p (r))
00477     {
00478       /* GDB treats segment registers as 32bit registers, but they are
00479          in fact only 16 bits long.  Make sure we do not read extra
00480          bits from our source buffer.  */
00481       l = *((long *) context_offset) & 0xffff;
00482       regcache_raw_supply (regcache, r, (char *) &l);
00483     }
00484   else if (r >= 0)
00485     regcache_raw_supply (regcache, r, context_offset);
00486   else
00487     {
00488       for (r = 0; r < gdbarch_num_regs (gdbarch); r++)
00489         do_windows_fetch_inferior_registers (regcache, r);
00490     }
00491 }
00492 
00493 static void
00494 windows_fetch_inferior_registers (struct target_ops *ops,
00495                                   struct regcache *regcache, int r)
00496 {
00497   current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
00498   /* Check if current_thread exists.  Windows sometimes uses a non-existent
00499      thread id in its events.  */
00500   if (current_thread)
00501     do_windows_fetch_inferior_registers (regcache, r);
00502 }
00503 
00504 static void
00505 do_windows_store_inferior_registers (const struct regcache *regcache, int r)
00506 {
00507   if (!current_thread)
00508     /* Windows sometimes uses a non-existent thread id in its events.  */;
00509   else if (r >= 0)
00510     regcache_raw_collect (regcache, r,
00511                           ((char *) &current_thread->context) + mappings[r]);
00512   else
00513     {
00514       for (r = 0; r < gdbarch_num_regs (get_regcache_arch (regcache)); r++)
00515         do_windows_store_inferior_registers (regcache, r);
00516     }
00517 }
00518 
00519 /* Store a new register value into the current thread context.  */
00520 static void
00521 windows_store_inferior_registers (struct target_ops *ops,
00522                                   struct regcache *regcache, int r)
00523 {
00524   current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
00525   /* Check if current_thread exists.  Windows sometimes uses a non-existent
00526      thread id in its events.  */
00527   if (current_thread)
00528     do_windows_store_inferior_registers (regcache, r);
00529 }
00530 
00531 /* Get the name of a given module at given base address.  If base_address
00532    is zero return the first loaded module (which is always the name of the
00533    executable).  */
00534 static int
00535 get_module_name (LPVOID base_address, char *dll_name_ret)
00536 {
00537   DWORD len;
00538   MODULEINFO mi;
00539   int i;
00540   HMODULE dh_buf[1];
00541   HMODULE *DllHandle = dh_buf;  /* Set to temporary storage for
00542                                    initial query.  */
00543   DWORD cbNeeded;
00544 #ifdef __CYGWIN__
00545   cygwin_buf_t pathbuf[__PMAX]; /* Temporary storage prior to converting to
00546                                    posix form.  __PMAX is always enough
00547                                    as long as SO_NAME_MAX_PATH_SIZE is defined
00548                                    as 512.  */
00549 #endif
00550 
00551   cbNeeded = 0;
00552   /* Find size of buffer needed to handle list of modules loaded in
00553      inferior.  */
00554   if (!EnumProcessModules (current_process_handle, DllHandle,
00555                            sizeof (HMODULE), &cbNeeded) || !cbNeeded)
00556     goto failed;
00557 
00558   /* Allocate correct amount of space for module list.  */
00559   DllHandle = (HMODULE *) alloca (cbNeeded);
00560   if (!DllHandle)
00561     goto failed;
00562 
00563   /* Get the list of modules.  */
00564   if (!EnumProcessModules (current_process_handle, DllHandle, cbNeeded,
00565                                  &cbNeeded))
00566     goto failed;
00567 
00568   for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
00569     {
00570       /* Get information on this module.  */
00571       if (!GetModuleInformation (current_process_handle, DllHandle[i],
00572                                  &mi, sizeof (mi)))
00573         error (_("Can't get module info"));
00574 
00575       if (!base_address || mi.lpBaseOfDll == base_address)
00576         {
00577           /* Try to find the name of the given module.  */
00578 #ifdef __CYGWIN__
00579           /* Cygwin prefers that the path be in /x/y/z format.  */
00580           len = GetModuleFileNameEx (current_process_handle,
00581                                       DllHandle[i], pathbuf, __PMAX);
00582           if (len == 0)
00583             error (_("Error getting dll name: %u."),
00584                    (unsigned) GetLastError ());
00585           if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, dll_name_ret,
00586                                 __PMAX) < 0)
00587             error (_("Error converting dll name to POSIX: %d."), errno);
00588 #else
00589           len = GetModuleFileNameEx (current_process_handle,
00590                                       DllHandle[i], dll_name_ret, __PMAX);
00591           if (len == 0)
00592             error (_("Error getting dll name: %u."),
00593                    (unsigned) GetLastError ());
00594 #endif
00595           return 1;     /* success */
00596         }
00597     }
00598 
00599 failed:
00600   dll_name_ret[0] = '\0';
00601   return 0;             /* failure */
00602 }
00603 
00604 /* Encapsulate the information required in a call to
00605    symbol_file_add_args.  */
00606 struct safe_symbol_file_add_args
00607 {
00608   char *name;
00609   int from_tty;
00610   struct section_addr_info *addrs;
00611   int mainline;
00612   int flags;
00613   struct ui_file *err, *out;
00614   struct objfile *ret;
00615 };
00616 
00617 /* Maintain a linked list of "so" information.  */
00618 struct lm_info
00619 {
00620   LPVOID load_addr;
00621 };
00622 
00623 static struct so_list solib_start, *solib_end;
00624 
00625 /* Call symbol_file_add with stderr redirected.  We don't care if there
00626    are errors.  */
00627 static int
00628 safe_symbol_file_add_stub (void *argv)
00629 {
00630 #define p ((struct safe_symbol_file_add_args *) argv)
00631   const int add_flags = ((p->from_tty ? SYMFILE_VERBOSE : 0)
00632                          | (p->mainline ? SYMFILE_MAINLINE : 0));
00633   p->ret = symbol_file_add (p->name, add_flags, p->addrs, p->flags);
00634   return !!p->ret;
00635 #undef p
00636 }
00637 
00638 /* Restore gdb's stderr after calling symbol_file_add.  */
00639 static void
00640 safe_symbol_file_add_cleanup (void *p)
00641 {
00642 #define sp ((struct safe_symbol_file_add_args *)p)
00643   gdb_flush (gdb_stderr);
00644   gdb_flush (gdb_stdout);
00645   ui_file_delete (gdb_stderr);
00646   ui_file_delete (gdb_stdout);
00647   gdb_stderr = sp->err;
00648   gdb_stdout = sp->out;
00649 #undef sp
00650 }
00651 
00652 /* symbol_file_add wrapper that prevents errors from being displayed.  */
00653 static struct objfile *
00654 safe_symbol_file_add (char *name, int from_tty,
00655                       struct section_addr_info *addrs,
00656                       int mainline, int flags)
00657 {
00658   struct safe_symbol_file_add_args p;
00659   struct cleanup *cleanup;
00660 
00661   cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
00662 
00663   p.err = gdb_stderr;
00664   p.out = gdb_stdout;
00665   gdb_flush (gdb_stderr);
00666   gdb_flush (gdb_stdout);
00667   gdb_stderr = ui_file_new ();
00668   gdb_stdout = ui_file_new ();
00669   p.name = name;
00670   p.from_tty = from_tty;
00671   p.addrs = addrs;
00672   p.mainline = mainline;
00673   p.flags = flags;
00674   catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
00675 
00676   do_cleanups (cleanup);
00677   return p.ret;
00678 }
00679 
00680 static struct so_list *
00681 windows_make_so (const char *name, LPVOID load_addr)
00682 {
00683   struct so_list *so;
00684   char *p;
00685 #ifndef __CYGWIN__
00686   char buf[__PMAX];
00687   char cwd[__PMAX];
00688   WIN32_FIND_DATA w32_fd;
00689   HANDLE h = FindFirstFile(name, &w32_fd);
00690 
00691   if (h == INVALID_HANDLE_VALUE)
00692     strcpy (buf, name);
00693   else
00694     {
00695       FindClose (h);
00696       strcpy (buf, name);
00697       if (GetCurrentDirectory (MAX_PATH + 1, cwd))
00698         {
00699           p = strrchr (buf, '\\');
00700           if (p)
00701             p[1] = '\0';
00702           SetCurrentDirectory (buf);
00703           GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
00704           SetCurrentDirectory (cwd);
00705         }
00706     }
00707   if (strcasecmp (buf, "ntdll.dll") == 0)
00708     {
00709       GetSystemDirectory (buf, sizeof (buf));
00710       strcat (buf, "\\ntdll.dll");
00711     }
00712 #else
00713   cygwin_buf_t buf[__PMAX];
00714 
00715   buf[0] = 0;
00716   if (access (name, F_OK) != 0)
00717     {
00718       if (strcasecmp (name, "ntdll.dll") == 0)
00719 #ifdef __USEWIDE
00720         {
00721           GetSystemDirectoryW (buf, sizeof (buf) / sizeof (wchar_t));
00722           wcscat (buf, L"\\ntdll.dll");
00723         }
00724 #else
00725         {
00726           GetSystemDirectoryA (buf, sizeof (buf) / sizeof (wchar_t));
00727           strcat (buf, "\\ntdll.dll");
00728         }
00729 #endif
00730     }
00731 #endif
00732   so = XZALLOC (struct so_list);
00733   so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
00734   so->lm_info->load_addr = load_addr;
00735   strcpy (so->so_original_name, name);
00736 #ifndef __CYGWIN__
00737   strcpy (so->so_name, buf);
00738 #else
00739   if (buf[0])
00740     cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
00741                       SO_NAME_MAX_PATH_SIZE);
00742   else
00743     {
00744       char *rname = realpath (name, NULL);
00745       if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE)
00746         {
00747           strcpy (so->so_name, rname);
00748           free (rname);
00749         }
00750       else
00751         error (_("dll path too long"));
00752     }
00753   /* Record cygwin1.dll .text start/end.  */
00754   p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
00755   if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
00756     {
00757       bfd *abfd;
00758       asection *text = NULL;
00759       CORE_ADDR text_vma;
00760 
00761       abfd = gdb_bfd_open (so->so_name, "pei-i386", -1);
00762 
00763       if (!abfd)
00764         return so;
00765 
00766       if (bfd_check_format (abfd, bfd_object))
00767         text = bfd_get_section_by_name (abfd, ".text");
00768 
00769       if (!text)
00770         {
00771           gdb_bfd_unref (abfd);
00772           return so;
00773         }
00774 
00775       /* The symbols in a dll are offset by 0x1000, which is the
00776          offset from 0 of the first byte in an image - because of the
00777          file header and the section alignment.  */
00778       cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *)
00779                                                    load_addr + 0x1000);
00780       cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text);
00781 
00782       gdb_bfd_unref (abfd);
00783     }
00784 #endif
00785 
00786   return so;
00787 }
00788 
00789 static char *
00790 get_image_name (HANDLE h, void *address, int unicode)
00791 {
00792 #ifdef __CYGWIN__
00793   static char buf[__PMAX];
00794 #else
00795   static char buf[(2 * __PMAX) + 1];
00796 #endif
00797   DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
00798   char *address_ptr;
00799   int len = 0;
00800   char b[2];
00801   SIZE_T done;
00802 
00803   /* Attempt to read the name of the dll that was detected.
00804      This is documented to work only when actively debugging
00805      a program.  It will not work for attached processes.  */
00806   if (address == NULL)
00807     return NULL;
00808 
00809   /* See if we could read the address of a string, and that the
00810      address isn't null.  */
00811   if (!ReadProcessMemory (h, address,  &address_ptr,
00812                           sizeof (address_ptr), &done)
00813       || done != sizeof (address_ptr) || !address_ptr)
00814     return NULL;
00815 
00816   /* Find the length of the string.  */
00817   while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
00818          && (b[0] != 0 || b[size - 1] != 0) && done == size)
00819     continue;
00820 
00821   if (!unicode)
00822     ReadProcessMemory (h, address_ptr, buf, len, &done);
00823   else
00824     {
00825       WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
00826       ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
00827                          &done);
00828 #ifdef __CYGWIN__
00829       wcstombs (buf, unicode_address, __PMAX);
00830 #else
00831       WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
00832                            0, 0);
00833 #endif
00834     }
00835 
00836   return buf;
00837 }
00838 
00839 /* Wait for child to do something.  Return pid of child, or -1 in case
00840    of error; store status through argument pointer OURSTATUS.  */
00841 static int
00842 handle_load_dll (void *dummy)
00843 {
00844   LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
00845   char dll_buf[__PMAX];
00846   char *dll_name = NULL;
00847 
00848   dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
00849 
00850   if (!get_module_name (event->lpBaseOfDll, dll_buf))
00851     dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
00852 
00853   dll_name = dll_buf;
00854 
00855   if (*dll_name == '\0')
00856     dll_name = get_image_name (current_process_handle,
00857                                event->lpImageName, event->fUnicode);
00858   if (!dll_name)
00859     return 1;
00860 
00861   solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
00862   solib_end = solib_end->next;
00863 
00864   DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name,
00865                  host_address_to_string (solib_end->lm_info->load_addr)));
00866 
00867   return 1;
00868 }
00869 
00870 static void
00871 windows_free_so (struct so_list *so)
00872 {
00873   if (so->lm_info)
00874     xfree (so->lm_info);
00875   xfree (so);
00876 }
00877 
00878 static int
00879 handle_unload_dll (void *dummy)
00880 {
00881   LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
00882   struct so_list *so;
00883 
00884   for (so = &solib_start; so->next != NULL; so = so->next)
00885     if (so->next->lm_info->load_addr == lpBaseOfDll)
00886       {
00887         struct so_list *sodel = so->next;
00888 
00889         so->next = sodel->next;
00890         if (!so->next)
00891           solib_end = so;
00892         DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
00893 
00894         windows_free_so (sodel);
00895         return 1;
00896       }
00897 
00898   /* We did not find any DLL that was previously loaded at this address,
00899      so register a complaint.  We do not report an error, because we have
00900      observed that this may be happening under some circumstances.  For
00901      instance, running 32bit applications on x64 Windows causes us to receive
00902      4 mysterious UNLOAD_DLL_DEBUG_EVENTs during the startup phase (these
00903      events are apparently caused by the WOW layer, the interface between
00904      32bit and 64bit worlds).  */
00905   complaint (&symfile_complaints, _("dll starting at %s not found."),
00906              host_address_to_string (lpBaseOfDll));
00907 
00908   return 0;
00909 }
00910 
00911 /* Clear list of loaded DLLs.  */
00912 static void
00913 windows_clear_solib (void)
00914 {
00915   solib_start.next = NULL;
00916   solib_end = &solib_start;
00917 }
00918 
00919 /* Load DLL symbol info.  */
00920 static void
00921 dll_symbol_command (char *args, int from_tty)
00922 {
00923   int n;
00924   dont_repeat ();
00925 
00926   if (args == NULL)
00927     error (_("dll-symbols requires a file name"));
00928 
00929   n = strlen (args);
00930   if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
00931     {
00932       char *newargs = (char *) alloca (n + 4 + 1);
00933       strcpy (newargs, args);
00934       strcat (newargs, ".dll");
00935       args = newargs;
00936     }
00937 
00938   safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
00939 }
00940 
00941 /* Handle DEBUG_STRING output from child process.
00942    Cygwin prepends its messages with a "cygwin:".  Interpret this as
00943    a Cygwin signal.  Otherwise just print the string as a warning.  */
00944 static int
00945 handle_output_debug_string (struct target_waitstatus *ourstatus)
00946 {
00947   char *s = NULL;
00948   int retval = 0;
00949 
00950   if (!target_read_string
00951         ((CORE_ADDR) (uintptr_t) current_event.u.DebugString.lpDebugStringData,
00952         &s, 1024, 0)
00953       || !s || !*s)
00954     /* nothing to do */;
00955   else if (strncmp (s, _CYGWIN_SIGNAL_STRING,
00956                     sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0)
00957     {
00958 #ifdef __CYGWIN__
00959       if (strncmp (s, "cYg", 3) != 0)
00960 #endif
00961         warning (("%s"), s);
00962     }
00963 #ifdef __COPY_CONTEXT_SIZE
00964   else
00965     {
00966       /* Got a cygwin signal marker.  A cygwin signal is followed by
00967          the signal number itself and then optionally followed by the
00968          thread id and address to saved context within the DLL.  If
00969          these are supplied, then the given thread is assumed to have
00970          issued the signal and the context from the thread is assumed
00971          to be stored at the given address in the inferior.  Tell gdb
00972          to treat this like a real signal.  */
00973       char *p;
00974       int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
00975       int gotasig = gdb_signal_from_host (sig);
00976 
00977       ourstatus->value.sig = gotasig;
00978       if (gotasig)
00979         {
00980           LPCVOID x;
00981           SIZE_T n;
00982 
00983           ourstatus->kind = TARGET_WAITKIND_STOPPED;
00984           retval = strtoul (p, &p, 0);
00985           if (!retval)
00986             retval = main_thread_id;
00987           else if ((x = (LPCVOID) (uintptr_t) strtoull (p, NULL, 0))
00988                    && ReadProcessMemory (current_process_handle, x,
00989                                          &saved_context,
00990                                          __COPY_CONTEXT_SIZE, &n)
00991                    && n == __COPY_CONTEXT_SIZE)
00992             have_saved_context = 1;
00993           current_event.dwThreadId = retval;
00994         }
00995     }
00996 #endif
00997 
00998   if (s)
00999     xfree (s);
01000   return retval;
01001 }
01002 
01003 static int
01004 display_selector (HANDLE thread, DWORD sel)
01005 {
01006   LDT_ENTRY info;
01007   if (GetThreadSelectorEntry (thread, sel, &info))
01008     {
01009       int base, limit;
01010       printf_filtered ("0x%03x: ", (unsigned) sel);
01011       if (!info.HighWord.Bits.Pres)
01012         {
01013           puts_filtered ("Segment not present\n");
01014           return 0;
01015         }
01016       base = (info.HighWord.Bits.BaseHi << 24) +
01017              (info.HighWord.Bits.BaseMid << 16)
01018              + info.BaseLow;
01019       limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
01020       if (info.HighWord.Bits.Granularity)
01021         limit = (limit << 12) | 0xfff;
01022       printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
01023       if (info.HighWord.Bits.Default_Big)
01024         puts_filtered(" 32-bit ");
01025       else
01026         puts_filtered(" 16-bit ");
01027       switch ((info.HighWord.Bits.Type & 0xf) >> 1)
01028         {
01029         case 0:
01030           puts_filtered ("Data (Read-Only, Exp-up");
01031           break;
01032         case 1:
01033           puts_filtered ("Data (Read/Write, Exp-up");
01034           break;
01035         case 2:
01036           puts_filtered ("Unused segment (");
01037           break;
01038         case 3:
01039           puts_filtered ("Data (Read/Write, Exp-down");
01040           break;
01041         case 4:
01042           puts_filtered ("Code (Exec-Only, N.Conf");
01043           break;
01044         case 5:
01045           puts_filtered ("Code (Exec/Read, N.Conf");
01046           break;
01047         case 6:
01048           puts_filtered ("Code (Exec-Only, Conf");
01049           break;
01050         case 7:
01051           puts_filtered ("Code (Exec/Read, Conf");
01052           break;
01053         default:
01054           printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
01055         }
01056       if ((info.HighWord.Bits.Type & 0x1) == 0)
01057         puts_filtered(", N.Acc");
01058       puts_filtered (")\n");
01059       if ((info.HighWord.Bits.Type & 0x10) == 0)
01060         puts_filtered("System selector ");
01061       printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
01062       if (info.HighWord.Bits.Granularity)
01063         puts_filtered ("Page granular.\n");
01064       else
01065         puts_filtered ("Byte granular.\n");
01066       return 1;
01067     }
01068   else
01069     {
01070       DWORD err = GetLastError ();
01071       if (err == ERROR_NOT_SUPPORTED)
01072         printf_filtered ("Function not supported\n");
01073       else
01074         printf_filtered ("Invalid selector 0x%x.\n", (unsigned) sel);
01075       return 0;
01076     }
01077 }
01078 
01079 static void
01080 display_selectors (char * args, int from_tty)
01081 {
01082   if (!current_thread)
01083     {
01084       puts_filtered ("Impossible to display selectors now.\n");
01085       return;
01086     }
01087   if (!args)
01088     {
01089 
01090       puts_filtered ("Selector $cs\n");
01091       display_selector (current_thread->h,
01092         current_thread->context.SegCs);
01093       puts_filtered ("Selector $ds\n");
01094       display_selector (current_thread->h,
01095         current_thread->context.SegDs);
01096       puts_filtered ("Selector $es\n");
01097       display_selector (current_thread->h,
01098         current_thread->context.SegEs);
01099       puts_filtered ("Selector $ss\n");
01100       display_selector (current_thread->h,
01101         current_thread->context.SegSs);
01102       puts_filtered ("Selector $fs\n");
01103       display_selector (current_thread->h,
01104         current_thread->context.SegFs);
01105       puts_filtered ("Selector $gs\n");
01106       display_selector (current_thread->h,
01107         current_thread->context.SegGs);
01108     }
01109   else
01110     {
01111       int sel;
01112       sel = parse_and_eval_long (args);
01113       printf_filtered ("Selector \"%s\"\n",args);
01114       display_selector (current_thread->h, sel);
01115     }
01116 }
01117 
01118 #define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
01119   printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
01120     host_address_to_string (\
01121       current_event.u.Exception.ExceptionRecord.ExceptionAddress))
01122 
01123 static int
01124 handle_exception (struct target_waitstatus *ourstatus)
01125 {
01126   thread_info *th;
01127   DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
01128 
01129   ourstatus->kind = TARGET_WAITKIND_STOPPED;
01130 
01131   /* Record the context of the current thread.  */
01132   th = thread_rec (current_event.dwThreadId, -1);
01133 
01134   switch (code)
01135     {
01136     case EXCEPTION_ACCESS_VIOLATION:
01137       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
01138       ourstatus->value.sig = GDB_SIGNAL_SEGV;
01139 #ifdef __CYGWIN__
01140       {
01141         /* See if the access violation happened within the cygwin DLL
01142            itself.  Cygwin uses a kind of exception handling to deal
01143            with passed-in invalid addresses.  gdb should not treat
01144            these as real SEGVs since they will be silently handled by
01145            cygwin.  A real SEGV will (theoretically) be caught by
01146            cygwin later in the process and will be sent as a
01147            cygwin-specific-signal.  So, ignore SEGVs if they show up
01148            within the text segment of the DLL itself.  */
01149         const char *fn;
01150         CORE_ADDR addr = (CORE_ADDR) (uintptr_t)
01151           current_event.u.Exception.ExceptionRecord.ExceptionAddress;
01152 
01153         if ((!cygwin_exceptions && (addr >= cygwin_load_start
01154                                     && addr < cygwin_load_end))
01155             || (find_pc_partial_function (addr, &fn, NULL, NULL)
01156                 && strncmp (fn, "KERNEL32!IsBad",
01157                             strlen ("KERNEL32!IsBad")) == 0))
01158           return 0;
01159       }
01160 #endif
01161       break;
01162     case STATUS_STACK_OVERFLOW:
01163       DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
01164       ourstatus->value.sig = GDB_SIGNAL_SEGV;
01165       break;
01166     case STATUS_FLOAT_DENORMAL_OPERAND:
01167       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
01168       ourstatus->value.sig = GDB_SIGNAL_FPE;
01169       break;
01170     case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
01171       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
01172       ourstatus->value.sig = GDB_SIGNAL_FPE;
01173       break;
01174     case STATUS_FLOAT_INEXACT_RESULT:
01175       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
01176       ourstatus->value.sig = GDB_SIGNAL_FPE;
01177       break;
01178     case STATUS_FLOAT_INVALID_OPERATION:
01179       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
01180       ourstatus->value.sig = GDB_SIGNAL_FPE;
01181       break;
01182     case STATUS_FLOAT_OVERFLOW:
01183       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
01184       ourstatus->value.sig = GDB_SIGNAL_FPE;
01185       break;
01186     case STATUS_FLOAT_STACK_CHECK:
01187       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
01188       ourstatus->value.sig = GDB_SIGNAL_FPE;
01189       break;
01190     case STATUS_FLOAT_UNDERFLOW:
01191       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
01192       ourstatus->value.sig = GDB_SIGNAL_FPE;
01193       break;
01194     case STATUS_FLOAT_DIVIDE_BY_ZERO:
01195       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
01196       ourstatus->value.sig = GDB_SIGNAL_FPE;
01197       break;
01198     case STATUS_INTEGER_DIVIDE_BY_ZERO:
01199       DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
01200       ourstatus->value.sig = GDB_SIGNAL_FPE;
01201       break;
01202     case STATUS_INTEGER_OVERFLOW:
01203       DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
01204       ourstatus->value.sig = GDB_SIGNAL_FPE;
01205       break;
01206     case EXCEPTION_BREAKPOINT:
01207       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
01208       ourstatus->value.sig = GDB_SIGNAL_TRAP;
01209       break;
01210     case DBG_CONTROL_C:
01211       DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
01212       ourstatus->value.sig = GDB_SIGNAL_INT;
01213       break;
01214     case DBG_CONTROL_BREAK:
01215       DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
01216       ourstatus->value.sig = GDB_SIGNAL_INT;
01217       break;
01218     case EXCEPTION_SINGLE_STEP:
01219       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
01220       ourstatus->value.sig = GDB_SIGNAL_TRAP;
01221       break;
01222     case EXCEPTION_ILLEGAL_INSTRUCTION:
01223       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
01224       ourstatus->value.sig = GDB_SIGNAL_ILL;
01225       break;
01226     case EXCEPTION_PRIV_INSTRUCTION:
01227       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
01228       ourstatus->value.sig = GDB_SIGNAL_ILL;
01229       break;
01230     case EXCEPTION_NONCONTINUABLE_EXCEPTION:
01231       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
01232       ourstatus->value.sig = GDB_SIGNAL_ILL;
01233       break;
01234     default:
01235       /* Treat unhandled first chance exceptions specially.  */
01236       if (current_event.u.Exception.dwFirstChance)
01237         return -1;
01238       printf_unfiltered ("gdb: unknown target exception 0x%08x at %s\n",
01239         (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
01240         host_address_to_string (
01241           current_event.u.Exception.ExceptionRecord.ExceptionAddress));
01242       ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
01243       break;
01244     }
01245   exception_count++;
01246   last_sig = ourstatus->value.sig;
01247   return 1;
01248 }
01249 
01250 /* Resume all artificially suspended threads if we are continuing
01251    execution.  */
01252 static BOOL
01253 windows_continue (DWORD continue_status, int id)
01254 {
01255   int i;
01256   thread_info *th;
01257   BOOL res;
01258 
01259   DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s);\n",
01260                   (unsigned) current_event.dwProcessId,
01261                   (unsigned) current_event.dwThreadId,
01262                   continue_status == DBG_CONTINUE ?
01263                   "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
01264 
01265   for (th = &thread_head; (th = th->next) != NULL;)
01266     if ((id == -1 || id == (int) th->id)
01267         && th->suspended)
01268       {
01269         if (debug_registers_changed)
01270           {
01271             th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
01272             th->context.Dr0 = dr[0];
01273             th->context.Dr1 = dr[1];
01274             th->context.Dr2 = dr[2];
01275             th->context.Dr3 = dr[3];
01276             th->context.Dr6 = DR6_CLEAR_VALUE;
01277             th->context.Dr7 = dr[7];
01278           }
01279         if (th->context.ContextFlags)
01280           {
01281             CHECK (SetThreadContext (th->h, &th->context));
01282             th->context.ContextFlags = 0;
01283           }
01284         if (th->suspended > 0)
01285           (void) ResumeThread (th->h);
01286         th->suspended = 0;
01287       }
01288 
01289   res = ContinueDebugEvent (current_event.dwProcessId,
01290                             current_event.dwThreadId,
01291                             continue_status);
01292 
01293   debug_registers_changed = 0;
01294   return res;
01295 }
01296 
01297 /* Called in pathological case where Windows fails to send a
01298    CREATE_PROCESS_DEBUG_EVENT after an attach.  */
01299 static DWORD
01300 fake_create_process (void)
01301 {
01302   current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
01303                                         current_event.dwProcessId);
01304   if (current_process_handle != NULL)
01305     open_process_used = 1;
01306   else
01307     {
01308       error (_("OpenProcess call failed, GetLastError = %u"),
01309        (unsigned) GetLastError ());
01310       /*  We can not debug anything in that case.  */
01311     }
01312   main_thread_id = current_event.dwThreadId;
01313   current_thread = windows_add_thread (
01314                      ptid_build (current_event.dwProcessId, 0,
01315                                  current_event.dwThreadId),
01316                      current_event.u.CreateThread.hThread,
01317                      current_event.u.CreateThread.lpThreadLocalBase);
01318   return main_thread_id;
01319 }
01320 
01321 static void
01322 windows_resume (struct target_ops *ops,
01323                 ptid_t ptid, int step, enum gdb_signal sig)
01324 {
01325   thread_info *th;
01326   DWORD continue_status = DBG_CONTINUE;
01327 
01328   /* A specific PTID means `step only this thread id'.  */
01329   int resume_all = ptid_equal (ptid, minus_one_ptid);
01330 
01331   /* If we're continuing all threads, it's the current inferior that
01332      should be handled specially.  */
01333   if (resume_all)
01334     ptid = inferior_ptid;
01335 
01336   if (sig != GDB_SIGNAL_0)
01337     {
01338       if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
01339         {
01340           DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
01341         }
01342       else if (sig == last_sig)
01343         continue_status = DBG_EXCEPTION_NOT_HANDLED;
01344       else
01345 #if 0
01346 /* This code does not seem to work, because
01347   the kernel does probably not consider changes in the ExceptionRecord
01348   structure when passing the exception to the inferior.
01349   Note that this seems possible in the exception handler itself.  */
01350         {
01351           int i;
01352           for (i = 0; xlate[i].them != -1; i++)
01353             if (xlate[i].us == sig)
01354               {
01355                 current_event.u.Exception.ExceptionRecord.ExceptionCode
01356                   = xlate[i].them;
01357                 continue_status = DBG_EXCEPTION_NOT_HANDLED;
01358                 break;
01359               }
01360           if (continue_status == DBG_CONTINUE)
01361             {
01362               DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
01363             }
01364         }
01365 #endif
01366         DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
01367           last_sig));
01368     }
01369 
01370   last_sig = GDB_SIGNAL_0;
01371 
01372   DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n",
01373                ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig));
01374 
01375   /* Get context for currently selected thread.  */
01376   th = thread_rec (ptid_get_tid (inferior_ptid), FALSE);
01377   if (th)
01378     {
01379       if (step)
01380         {
01381           /* Single step by setting t bit.  */
01382           struct regcache *regcache = get_current_regcache ();
01383           struct gdbarch *gdbarch = get_regcache_arch (regcache);
01384           windows_fetch_inferior_registers (ops, regcache,
01385                                             gdbarch_ps_regnum (gdbarch));
01386           th->context.EFlags |= FLAG_TRACE_BIT;
01387         }
01388 
01389       if (th->context.ContextFlags)
01390         {
01391           if (debug_registers_changed)
01392             {
01393               th->context.Dr0 = dr[0];
01394               th->context.Dr1 = dr[1];
01395               th->context.Dr2 = dr[2];
01396               th->context.Dr3 = dr[3];
01397               th->context.Dr6 = DR6_CLEAR_VALUE;
01398               th->context.Dr7 = dr[7];
01399             }
01400           CHECK (SetThreadContext (th->h, &th->context));
01401           th->context.ContextFlags = 0;
01402         }
01403     }
01404 
01405   /* Allow continuing with the same signal that interrupted us.
01406      Otherwise complain.  */
01407 
01408   if (resume_all)
01409     windows_continue (continue_status, -1);
01410   else
01411     windows_continue (continue_status, ptid_get_tid (ptid));
01412 }
01413 
01414 /* Ctrl-C handler used when the inferior is not run in the same console.  The
01415    handler is in charge of interrupting the inferior using DebugBreakProcess.
01416    Note that this function is not available prior to Windows XP.  In this case
01417    we emit a warning.  */
01418 static BOOL WINAPI
01419 ctrl_c_handler (DWORD event_type)
01420 {
01421   const int attach_flag = current_inferior ()->attach_flag;
01422 
01423   /* Only handle Ctrl-C and Ctrl-Break events.  Ignore others.  */
01424   if (event_type != CTRL_C_EVENT && event_type != CTRL_BREAK_EVENT)
01425     return FALSE;
01426 
01427   /* If the inferior and the debugger share the same console, do nothing as
01428      the inferior has also received the Ctrl-C event.  */
01429   if (!new_console && !attach_flag)
01430     return TRUE;
01431 
01432   if (!DebugBreakProcess (current_process_handle))
01433     warning (_("Could not interrupt program.  "
01434                "Press Ctrl-c in the program console."));
01435 
01436   /* Return true to tell that Ctrl-C has been handled.  */
01437   return TRUE;
01438 }
01439 
01440 /* Get the next event from the child.  Return 1 if the event requires
01441    handling by WFI (or whatever).  */
01442 static int
01443 get_windows_debug_event (struct target_ops *ops,
01444                          int pid, struct target_waitstatus *ourstatus)
01445 {
01446   BOOL debug_event;
01447   DWORD continue_status, event_code;
01448   thread_info *th;
01449   static thread_info dummy_thread_info;
01450   int retval = 0;
01451 
01452   last_sig = GDB_SIGNAL_0;
01453 
01454   if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
01455     goto out;
01456 
01457   event_count++;
01458   continue_status = DBG_CONTINUE;
01459 
01460   event_code = current_event.dwDebugEventCode;
01461   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
01462   th = NULL;
01463   have_saved_context = 0;
01464 
01465   switch (event_code)
01466     {
01467     case CREATE_THREAD_DEBUG_EVENT:
01468       DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
01469                      (unsigned) current_event.dwProcessId,
01470                      (unsigned) current_event.dwThreadId,
01471                      "CREATE_THREAD_DEBUG_EVENT"));
01472       if (saw_create != 1)
01473         {
01474           struct inferior *inf;
01475           inf = find_inferior_pid (current_event.dwProcessId);
01476           if (!saw_create && inf->attach_flag)
01477             {
01478               /* Kludge around a Windows bug where first event is a create
01479                  thread event.  Caused when attached process does not have
01480                  a main thread.  */
01481               retval = fake_create_process ();
01482               if (retval)
01483                 saw_create++;
01484             }
01485           break;
01486         }
01487       /* Record the existence of this thread.  */
01488       retval = current_event.dwThreadId;
01489       th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
01490                                          current_event.dwThreadId),
01491                              current_event.u.CreateThread.hThread,
01492                              current_event.u.CreateThread.lpThreadLocalBase);
01493 
01494       break;
01495 
01496     case EXIT_THREAD_DEBUG_EVENT:
01497       DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
01498                      (unsigned) current_event.dwProcessId,
01499                      (unsigned) current_event.dwThreadId,
01500                      "EXIT_THREAD_DEBUG_EVENT"));
01501 
01502       if (current_event.dwThreadId != main_thread_id)
01503         {
01504           windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
01505                                              current_event.dwThreadId),
01506                                  current_event.u.ExitThread.dwExitCode);
01507           th = &dummy_thread_info;
01508         }
01509       break;
01510 
01511     case CREATE_PROCESS_DEBUG_EVENT:
01512       DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
01513                      (unsigned) current_event.dwProcessId,
01514                      (unsigned) current_event.dwThreadId,
01515                      "CREATE_PROCESS_DEBUG_EVENT"));
01516       CloseHandle (current_event.u.CreateProcessInfo.hFile);
01517       if (++saw_create != 1)
01518         break;
01519 
01520       current_process_handle = current_event.u.CreateProcessInfo.hProcess;
01521       if (main_thread_id)
01522         windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
01523                                            main_thread_id),
01524                                0);
01525       main_thread_id = current_event.dwThreadId;
01526       /* Add the main thread.  */
01527       th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
01528                                            current_event.dwThreadId),
01529              current_event.u.CreateProcessInfo.hThread,
01530              current_event.u.CreateProcessInfo.lpThreadLocalBase);
01531       retval = current_event.dwThreadId;
01532       break;
01533 
01534     case EXIT_PROCESS_DEBUG_EVENT:
01535       DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
01536                      (unsigned) current_event.dwProcessId,
01537                      (unsigned) current_event.dwThreadId,
01538                      "EXIT_PROCESS_DEBUG_EVENT"));
01539       if (!windows_initialization_done)
01540         {
01541           target_terminal_ours ();
01542           target_mourn_inferior ();
01543           error (_("During startup program exited with code 0x%x."),
01544                  (unsigned int) current_event.u.ExitProcess.dwExitCode);
01545         }
01546       else if (saw_create == 1)
01547         {
01548           ourstatus->kind = TARGET_WAITKIND_EXITED;
01549           ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
01550           retval = main_thread_id;
01551         }
01552       break;
01553 
01554     case LOAD_DLL_DEBUG_EVENT:
01555       DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
01556                      (unsigned) current_event.dwProcessId,
01557                      (unsigned) current_event.dwThreadId,
01558                      "LOAD_DLL_DEBUG_EVENT"));
01559       CloseHandle (current_event.u.LoadDll.hFile);
01560       if (saw_create != 1)
01561         break;
01562       catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
01563       ourstatus->kind = TARGET_WAITKIND_LOADED;
01564       ourstatus->value.integer = 0;
01565       retval = main_thread_id;
01566       break;
01567 
01568     case UNLOAD_DLL_DEBUG_EVENT:
01569       DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
01570                      (unsigned) current_event.dwProcessId,
01571                      (unsigned) current_event.dwThreadId,
01572                      "UNLOAD_DLL_DEBUG_EVENT"));
01573       if (saw_create != 1)
01574         break;
01575       catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
01576       ourstatus->kind = TARGET_WAITKIND_LOADED;
01577       ourstatus->value.integer = 0;
01578       retval = main_thread_id;
01579       break;
01580 
01581     case EXCEPTION_DEBUG_EVENT:
01582       DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
01583                      (unsigned) current_event.dwProcessId,
01584                      (unsigned) current_event.dwThreadId,
01585                      "EXCEPTION_DEBUG_EVENT"));
01586       if (saw_create != 1)
01587         break;
01588       switch (handle_exception (ourstatus))
01589         {
01590         case 0:
01591           continue_status = DBG_EXCEPTION_NOT_HANDLED;
01592           break;
01593         case 1:
01594           retval = current_event.dwThreadId;
01595           break;
01596         case -1:
01597           last_sig = 1;
01598           continue_status = -1;
01599           break;
01600         }
01601       break;
01602 
01603     case OUTPUT_DEBUG_STRING_EVENT:     /* Message from the kernel.  */
01604       DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
01605                      (unsigned) current_event.dwProcessId,
01606                      (unsigned) current_event.dwThreadId,
01607                      "OUTPUT_DEBUG_STRING_EVENT"));
01608       if (saw_create != 1)
01609         break;
01610       retval = handle_output_debug_string (ourstatus);
01611       break;
01612 
01613     default:
01614       if (saw_create != 1)
01615         break;
01616       printf_unfiltered ("gdb: kernel event for pid=%u tid=0x%x\n",
01617                          (unsigned) current_event.dwProcessId,
01618                          (unsigned) current_event.dwThreadId);
01619       printf_unfiltered ("                 unknown event code %u\n",
01620                          (unsigned) current_event.dwDebugEventCode);
01621       break;
01622     }
01623 
01624   if (!retval || saw_create != 1)
01625     {
01626       if (continue_status == -1)
01627         windows_resume (ops, minus_one_ptid, 0, 1);
01628       else
01629         CHECK (windows_continue (continue_status, -1));
01630     }
01631   else
01632     {
01633       inferior_ptid = ptid_build (current_event.dwProcessId, 0,
01634                                   retval);
01635       current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
01636     }
01637 
01638 out:
01639   return retval;
01640 }
01641 
01642 /* Wait for interesting events to occur in the target process.  */
01643 static ptid_t
01644 windows_wait (struct target_ops *ops,
01645               ptid_t ptid, struct target_waitstatus *ourstatus, int options)
01646 {
01647   int pid = -1;
01648 
01649   target_terminal_ours ();
01650 
01651   /* We loop when we get a non-standard exception rather than return
01652      with a SPURIOUS because resume can try and step or modify things,
01653      which needs a current_thread->h.  But some of these exceptions mark
01654      the birth or death of threads, which mean that the current thread
01655      isn't necessarily what you think it is.  */
01656 
01657   while (1)
01658     {
01659       int retval;
01660 
01661       /* If the user presses Ctrl-c while the debugger is waiting
01662          for an event, he expects the debugger to interrupt his program
01663          and to get the prompt back.  There are two possible situations:
01664 
01665            - The debugger and the program do not share the console, in
01666              which case the Ctrl-c event only reached the debugger.
01667              In that case, the ctrl_c handler will take care of interrupting
01668              the inferior.  Note that this case is working starting with
01669              Windows XP.  For Windows 2000, Ctrl-C should be pressed in the
01670              inferior console.
01671 
01672            - The debugger and the program share the same console, in which
01673              case both debugger and inferior will receive the Ctrl-c event.
01674              In that case the ctrl_c handler will ignore the event, as the
01675              Ctrl-c event generated inside the inferior will trigger the
01676              expected debug event.
01677 
01678              FIXME: brobecker/2008-05-20: If the inferior receives the
01679              signal first and the delay until GDB receives that signal
01680              is sufficiently long, GDB can sometimes receive the SIGINT
01681              after we have unblocked the CTRL+C handler.  This would
01682              lead to the debugger stopping prematurely while handling
01683              the new-thread event that comes with the handling of the SIGINT
01684              inside the inferior, and then stop again immediately when
01685              the user tries to resume the execution in the inferior.
01686              This is a classic race that we should try to fix one day.  */
01687       SetConsoleCtrlHandler (&ctrl_c_handler, TRUE);
01688       retval = get_windows_debug_event (ops, pid, ourstatus);
01689       SetConsoleCtrlHandler (&ctrl_c_handler, FALSE);
01690 
01691       if (retval)
01692         return ptid_build (current_event.dwProcessId, 0, retval);
01693       else
01694         {
01695           int detach = 0;
01696 
01697           if (deprecated_ui_loop_hook != NULL)
01698             detach = deprecated_ui_loop_hook (0);
01699 
01700           if (detach)
01701             windows_kill_inferior (ops);
01702         }
01703     }
01704 }
01705 
01706 static void
01707 do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
01708 {
01709   extern int stop_after_trap;
01710   int i;
01711   struct inferior *inf;
01712   struct thread_info *tp;
01713 
01714   last_sig = GDB_SIGNAL_0;
01715   event_count = 0;
01716   exception_count = 0;
01717   open_process_used = 0;
01718   debug_registers_changed = 0;
01719   debug_registers_used = 0;
01720   for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
01721     dr[i] = 0;
01722 #ifdef __CYGWIN__
01723   cygwin_load_start = cygwin_load_end = 0;
01724 #endif
01725   current_event.dwProcessId = pid;
01726   memset (&current_event, 0, sizeof (current_event));
01727   push_target (ops);
01728   disable_breakpoints_in_shlibs ();
01729   windows_clear_solib ();
01730   clear_proceed_status ();
01731   init_wait_for_inferior ();
01732 
01733   inf = current_inferior ();
01734   inferior_appeared (inf, pid);
01735   inf->attach_flag = attaching;
01736 
01737   /* Make the new process the current inferior, so terminal handling
01738      can rely on it.  When attaching, we don't know about any thread
01739      id here, but that's OK --- nothing should be referencing the
01740      current thread until we report an event out of windows_wait.  */
01741   inferior_ptid = pid_to_ptid (pid);
01742 
01743   terminal_init_inferior_with_pgrp (pid);
01744   target_terminal_inferior ();
01745 
01746   windows_initialization_done = 0;
01747   inf->control.stop_soon = STOP_QUIETLY;
01748   while (1)
01749     {
01750       stop_after_trap = 1;
01751       wait_for_inferior ();
01752       tp = inferior_thread ();
01753       if (tp->suspend.stop_signal != GDB_SIGNAL_TRAP)
01754         resume (0, tp->suspend.stop_signal);
01755       else
01756         break;
01757     }
01758 
01759   windows_initialization_done = 1;
01760   inf->control.stop_soon = NO_STOP_QUIETLY;
01761   stop_after_trap = 0;
01762   return;
01763 }
01764 
01765 /* Try to set or remove a user privilege to the current process.  Return -1
01766    if that fails, the previous setting of that privilege otherwise.
01767 
01768    This code is copied from the Cygwin source code and rearranged to allow
01769    dynamically loading of the needed symbols from advapi32 which is only
01770    available on NT/2K/XP.  */
01771 static int
01772 set_process_privilege (const char *privilege, BOOL enable)
01773 {
01774   HANDLE token_hdl = NULL;
01775   LUID restore_priv;
01776   TOKEN_PRIVILEGES new_priv, orig_priv;
01777   int ret = -1;
01778   DWORD size;
01779 
01780   if (!OpenProcessToken (GetCurrentProcess (),
01781                          TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
01782                          &token_hdl))
01783     goto out;
01784 
01785   if (!LookupPrivilegeValueA (NULL, privilege, &restore_priv))
01786     goto out;
01787 
01788   new_priv.PrivilegeCount = 1;
01789   new_priv.Privileges[0].Luid = restore_priv;
01790   new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
01791 
01792   if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
01793                               sizeof orig_priv, &orig_priv, &size))
01794     goto out;
01795 #if 0
01796   /* Disabled, otherwise every `attach' in an unprivileged user session
01797      would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
01798      windows_attach().  */
01799   /* AdjustTokenPrivileges returns TRUE even if the privilege could not
01800      be enabled.  GetLastError () returns an correct error code, though.  */
01801   if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
01802     goto out;
01803 #endif
01804 
01805   ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
01806 
01807 out:
01808   if (token_hdl)
01809     CloseHandle (token_hdl);
01810 
01811   return ret;
01812 }
01813 
01814 /* Attach to process PID, then initialize for debugging it.  */
01815 static void
01816 windows_attach (struct target_ops *ops, char *args, int from_tty)
01817 {
01818   BOOL ok;
01819   DWORD pid;
01820 
01821   pid = parse_pid_to_attach (args);
01822 
01823   if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
01824     {
01825       printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
01826       printf_unfiltered ("This can cause attach to "
01827                          "fail on Windows NT/2K/XP\n");
01828     }
01829 
01830   windows_init_thread_list ();
01831   ok = DebugActiveProcess (pid);
01832   saw_create = 0;
01833 
01834 #ifdef __CYGWIN__
01835   if (!ok)
01836     {
01837       /* Try fall back to Cygwin pid.  */
01838       pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
01839 
01840       if (pid > 0)
01841         ok = DebugActiveProcess (pid);
01842   }
01843 #endif
01844 
01845   if (!ok)
01846     error (_("Can't attach to process."));
01847 
01848   DebugSetProcessKillOnExit (FALSE);
01849 
01850   if (from_tty)
01851     {
01852       char *exec_file = (char *) get_exec_file (0);
01853 
01854       if (exec_file)
01855         printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
01856                            target_pid_to_str (pid_to_ptid (pid)));
01857       else
01858         printf_unfiltered ("Attaching to %s\n",
01859                            target_pid_to_str (pid_to_ptid (pid)));
01860 
01861       gdb_flush (gdb_stdout);
01862     }
01863 
01864   do_initial_windows_stuff (ops, pid, 1);
01865   target_terminal_ours ();
01866 }
01867 
01868 static void
01869 windows_detach (struct target_ops *ops, char *args, int from_tty)
01870 {
01871   int detached = 1;
01872 
01873   ptid_t ptid = {-1};
01874   windows_resume (ops, ptid, 0, GDB_SIGNAL_0);
01875 
01876   if (!DebugActiveProcessStop (current_event.dwProcessId))
01877     {
01878       error (_("Can't detach process %u (error %u)"),
01879              (unsigned) current_event.dwProcessId, (unsigned) GetLastError ());
01880       detached = 0;
01881     }
01882   DebugSetProcessKillOnExit (FALSE);
01883 
01884   if (detached && from_tty)
01885     {
01886       char *exec_file = get_exec_file (0);
01887       if (exec_file == 0)
01888         exec_file = "";
01889       printf_unfiltered ("Detaching from program: %s, Pid %u\n", exec_file,
01890                          (unsigned) current_event.dwProcessId);
01891       gdb_flush (gdb_stdout);
01892     }
01893 
01894   i386_cleanup_dregs ();
01895   inferior_ptid = null_ptid;
01896   detach_inferior (current_event.dwProcessId);
01897 
01898   unpush_target (ops);
01899 }
01900 
01901 static char *
01902 windows_pid_to_exec_file (int pid)
01903 {
01904   static char path[__PMAX];
01905 #ifdef __CYGWIN__
01906   /* Try to find exe name as symlink target of /proc/<pid>/exe.  */
01907   int nchars;
01908   char procexe[sizeof ("/proc/4294967295/exe")];
01909 
01910   xsnprintf (procexe, sizeof (procexe), "/proc/%u/exe", pid);
01911   nchars = readlink (procexe, path, sizeof(path));
01912   if (nchars > 0 && nchars < sizeof (path))
01913     {
01914       path[nchars] = '\0';      /* Got it */
01915       return path;
01916     }
01917 #endif
01918 
01919   /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
01920      of gdb, or we're trying to debug a non-Cygwin windows executable.  */
01921   if (!get_module_name (0, path))
01922     path[0] = '\0';
01923 
01924   return path;
01925 }
01926 
01927 /* Print status information about what we're accessing.  */
01928 
01929 static void
01930 windows_files_info (struct target_ops *ignore)
01931 {
01932   struct inferior *inf = current_inferior ();
01933 
01934   printf_unfiltered ("\tUsing the running image of %s %s.\n",
01935                      inf->attach_flag ? "attached" : "child",
01936                      target_pid_to_str (inferior_ptid));
01937 }
01938 
01939 static void
01940 windows_open (char *arg, int from_tty)
01941 {
01942   error (_("Use the \"run\" command to start a Unix child process."));
01943 }
01944 
01945 /* Modify CreateProcess parameters for use of a new separate console.
01946    Parameters are:
01947    *FLAGS: DWORD parameter for general process creation flags.
01948    *SI: STARTUPINFO structure, for which the console window size and
01949    console buffer size is filled in if GDB is running in a console.
01950    to create the new console.
01951    The size of the used font is not available on all versions of
01952    Windows OS.  Furthermore, the current font might not be the default
01953    font, but this is still better than before.
01954    If the windows and buffer sizes are computed,
01955    SI->DWFLAGS is changed so that this information is used
01956    by CreateProcess function.  */
01957 
01958 static void
01959 windows_set_console_info (STARTUPINFO *si, DWORD *flags)
01960 {
01961   HANDLE hconsole = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE,
01962                                 FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
01963 
01964   if (hconsole != INVALID_HANDLE_VALUE)
01965     {
01966       CONSOLE_SCREEN_BUFFER_INFO sbinfo;
01967       COORD font_size;
01968       CONSOLE_FONT_INFO cfi;
01969 
01970       GetCurrentConsoleFont (hconsole, FALSE, &cfi);
01971       font_size = GetConsoleFontSize (hconsole, cfi.nFont);
01972       GetConsoleScreenBufferInfo(hconsole, &sbinfo);
01973       si->dwXSize = sbinfo.srWindow.Right - sbinfo.srWindow.Left + 1;
01974       si->dwYSize = sbinfo.srWindow.Bottom - sbinfo.srWindow.Top + 1;
01975       if (font_size.X)
01976         si->dwXSize *= font_size.X;
01977       else
01978         si->dwXSize *= 8;
01979       if (font_size.Y)
01980         si->dwYSize *= font_size.Y;
01981       else
01982         si->dwYSize *= 12;
01983       si->dwXCountChars = sbinfo.dwSize.X;
01984       si->dwYCountChars = sbinfo.dwSize.Y;
01985       si->dwFlags |= STARTF_USESIZE | STARTF_USECOUNTCHARS;
01986     }
01987   *flags |= CREATE_NEW_CONSOLE;
01988 }
01989 
01990 #ifndef __CYGWIN__
01991 /* Function called by qsort to sort environment strings.  */
01992 
01993 static int
01994 envvar_cmp (const void *a, const void *b)
01995 {
01996   const char **p = (const char **) a;
01997   const char **q = (const char **) b;
01998   return strcasecmp (*p, *q);
01999 }
02000 #endif
02001 
02002 #ifdef __CYGWIN__
02003 static void
02004 clear_win32_environment (char **env)
02005 {
02006   int i;
02007   size_t len;
02008   wchar_t *copy = NULL, *equalpos;
02009 
02010   for (i = 0; env[i] && *env[i]; i++)
02011     {
02012       len = mbstowcs (NULL, env[i], 0) + 1;
02013       copy = (wchar_t *) xrealloc (copy, len * sizeof (wchar_t));
02014       mbstowcs (copy, env[i], len);
02015       equalpos = wcschr (copy, L'=');
02016       if (equalpos)
02017         *equalpos = L'\0';
02018       SetEnvironmentVariableW (copy, NULL);
02019     }
02020   xfree (copy);
02021 }
02022 #endif
02023 
02024 /* Start an inferior windows child process and sets inferior_ptid to its pid.
02025    EXEC_FILE is the file to run.
02026    ALLARGS is a string containing the arguments to the program.
02027    ENV is the environment vector to pass.  Errors reported with error().  */
02028 
02029 static void
02030 windows_create_inferior (struct target_ops *ops, char *exec_file,
02031                        char *allargs, char **in_env, int from_tty)
02032 {
02033   STARTUPINFO si;
02034 #ifdef __CYGWIN__
02035   cygwin_buf_t real_path[__PMAX];
02036   cygwin_buf_t shell[__PMAX]; /* Path to shell */
02037   const char *sh;
02038   cygwin_buf_t *toexec;
02039   cygwin_buf_t *cygallargs;
02040   cygwin_buf_t *args;
02041   char **old_env = NULL;
02042   PWCHAR w32_env;
02043   size_t len;
02044   int tty;
02045   int ostdin, ostdout, ostderr;
02046 #else
02047   char real_path[__PMAX];
02048   char shell[__PMAX]; /* Path to shell */
02049   char *toexec;
02050   char *args;
02051   size_t args_len;
02052   HANDLE tty;
02053   char *w32env;
02054   char *temp;
02055   size_t envlen;
02056   int i;
02057   size_t envsize;
02058   char **env;
02059 #endif
02060   PROCESS_INFORMATION pi;
02061   BOOL ret;
02062   DWORD flags = 0;
02063   const char *inferior_io_terminal = get_inferior_io_terminal ();
02064 
02065   if (!exec_file)
02066     error (_("No executable specified, use `target exec'."));
02067 
02068   memset (&si, 0, sizeof (si));
02069   si.cb = sizeof (si);
02070 
02071   if (new_group)
02072     flags |= CREATE_NEW_PROCESS_GROUP;
02073 
02074   if (new_console)
02075     windows_set_console_info (&si, &flags);
02076 
02077 #ifdef __CYGWIN__
02078   if (!useshell)
02079     {
02080       flags |= DEBUG_ONLY_THIS_PROCESS;
02081       if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, exec_file, real_path,
02082                             __PMAX * sizeof (cygwin_buf_t)) < 0)
02083         error (_("Error starting executable: %d"), errno);
02084       toexec = real_path;
02085 #ifdef __USEWIDE
02086       len = mbstowcs (NULL, allargs, 0) + 1;
02087       if (len == (size_t) -1)
02088         error (_("Error starting executable: %d"), errno);
02089       cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
02090       mbstowcs (cygallargs, allargs, len);
02091 #else
02092       cygallargs = allargs;
02093 #endif
02094     }
02095   else
02096     {
02097       sh = getenv ("SHELL");
02098       if (!sh)
02099         sh = "/bin/sh";
02100       if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, __PMAX) < 0)
02101         error (_("Error starting executable via shell: %d"), errno);
02102 #ifdef __USEWIDE
02103       len = sizeof (L" -c 'exec  '") + mbstowcs (NULL, exec_file, 0)
02104             + mbstowcs (NULL, allargs, 0) + 2;
02105       cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
02106       swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs);
02107 #else
02108       len = (sizeof (" -c 'exec  '") + strlen (exec_file)
02109              + strlen (allargs) + 2);
02110       cygallargs = (char *) alloca (len);
02111       xsnprintf (cygallargs, len, " -c 'exec %s %s'", exec_file, allargs);
02112 #endif
02113       toexec = shell;
02114       flags |= DEBUG_PROCESS;
02115     }
02116 
02117 #ifdef __USEWIDE
02118   args = (cygwin_buf_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
02119                                   * sizeof (wchar_t));
02120   wcscpy (args, toexec);
02121   wcscat (args, L" ");
02122   wcscat (args, cygallargs);
02123 #else
02124   args = (cygwin_buf_t *) alloca (strlen (toexec) + strlen (cygallargs) + 2);
02125   strcpy (args, toexec);
02126   strcat (args, " ");
02127   strcat (args, cygallargs);
02128 #endif
02129 
02130 #ifdef CW_CVT_ENV_TO_WINENV
02131   /* First try to create a direct Win32 copy of the POSIX environment. */
02132   w32_env = (PWCHAR) cygwin_internal (CW_CVT_ENV_TO_WINENV, in_env);
02133   if (w32_env != (PWCHAR) -1)
02134     flags |= CREATE_UNICODE_ENVIRONMENT;
02135   else
02136     /* If that fails, fall back to old method tweaking GDB's environment. */
02137 #endif
02138     {
02139       /* Reset all Win32 environment variables to avoid leftover on next run. */
02140       clear_win32_environment (environ);
02141       /* Prepare the environment vars for CreateProcess.  */
02142       old_env = environ;
02143       environ = in_env;
02144       cygwin_internal (CW_SYNC_WINENV);
02145       w32_env = NULL;
02146     }
02147 
02148   if (!inferior_io_terminal)
02149     tty = ostdin = ostdout = ostderr = -1;
02150   else
02151     {
02152       tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
02153       if (tty < 0)
02154         {
02155           print_sys_errmsg (inferior_io_terminal, errno);
02156           ostdin = ostdout = ostderr = -1;
02157         }
02158       else
02159         {
02160           ostdin = dup (0);
02161           ostdout = dup (1);
02162           ostderr = dup (2);
02163           dup2 (tty, 0);
02164           dup2 (tty, 1);
02165           dup2 (tty, 2);
02166         }
02167     }
02168 
02169   windows_init_thread_list ();
02170   ret = CreateProcess (0,
02171                        args,    /* command line */
02172                        NULL,    /* Security */
02173                        NULL,    /* thread */
02174                        TRUE,    /* inherit handles */
02175                        flags,   /* start flags */
02176                        w32_env, /* environment */
02177                        NULL,    /* current directory */
02178                        &si,
02179                        &pi);
02180   if (w32_env)
02181     /* Just free the Win32 environment, if it could be created. */
02182     free (w32_env);
02183   else
02184     {
02185       /* Reset all environment variables to avoid leftover on next run. */
02186       clear_win32_environment (in_env);
02187       /* Restore normal GDB environment variables.  */
02188       environ = old_env;
02189       cygwin_internal (CW_SYNC_WINENV);
02190     }
02191 
02192   if (tty >= 0)
02193     {
02194       close (tty);
02195       dup2 (ostdin, 0);
02196       dup2 (ostdout, 1);
02197       dup2 (ostderr, 2);
02198       close (ostdin);
02199       close (ostdout);
02200       close (ostderr);
02201     }
02202 #else
02203   toexec = exec_file;
02204   /* Build the command line, a space-separated list of tokens where
02205      the first token is the name of the module to be executed.
02206      To avoid ambiguities introduced by spaces in the module name,
02207      we quote it.  */
02208   args_len = strlen (toexec) + 2 /* quotes */ + strlen (allargs) + 2;
02209   args = alloca (args_len);
02210   xsnprintf (args, args_len, "\"%s\" %s", toexec, allargs);
02211 
02212   flags |= DEBUG_ONLY_THIS_PROCESS;
02213 
02214   if (!inferior_io_terminal)
02215     tty = INVALID_HANDLE_VALUE;
02216   else
02217     {
02218       SECURITY_ATTRIBUTES sa;
02219       sa.nLength = sizeof(sa);
02220       sa.lpSecurityDescriptor = 0;
02221       sa.bInheritHandle = TRUE;
02222       tty = CreateFileA (inferior_io_terminal, GENERIC_READ | GENERIC_WRITE,
02223                          0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
02224       if (tty == INVALID_HANDLE_VALUE)
02225         warning (_("Warning: Failed to open TTY %s, error %#x."),
02226                  inferior_io_terminal, (unsigned) GetLastError ());
02227       else
02228         {
02229           si.hStdInput = tty;
02230           si.hStdOutput = tty;
02231           si.hStdError = tty;
02232           si.dwFlags |= STARTF_USESTDHANDLES;
02233         }
02234     }
02235 
02236   /* CreateProcess takes the environment list as a null terminated set of
02237      strings (i.e. two nulls terminate the list).  */
02238 
02239   /* Get total size for env strings.  */
02240   for (envlen = 0, i = 0; in_env[i] && *in_env[i]; i++)
02241     envlen += strlen (in_env[i]) + 1;
02242 
02243   envsize = sizeof (in_env[0]) * (i + 1);
02244   env = (char **) alloca (envsize);
02245   memcpy (env, in_env, envsize);
02246   /* Windows programs expect the environment block to be sorted.  */
02247   qsort (env, i, sizeof (char *), envvar_cmp);
02248 
02249   w32env = alloca (envlen + 1);
02250 
02251   /* Copy env strings into new buffer.  */
02252   for (temp = w32env, i = 0; env[i] && *env[i]; i++)
02253     {
02254       strcpy (temp, env[i]);
02255       temp += strlen (temp) + 1;
02256     }
02257 
02258   /* Final nil string to terminate new env.  */
02259   *temp = 0;
02260 
02261   windows_init_thread_list ();
02262   ret = CreateProcessA (0,
02263                         args,   /* command line */
02264                         NULL,   /* Security */
02265                         NULL,   /* thread */
02266                         TRUE,   /* inherit handles */
02267                         flags,  /* start flags */
02268                         w32env, /* environment */
02269                         NULL,   /* current directory */
02270                         &si,
02271                         &pi);
02272   if (tty != INVALID_HANDLE_VALUE)
02273     CloseHandle (tty);
02274 #endif
02275 
02276   if (!ret)
02277     error (_("Error creating process %s, (error %u)."),
02278            exec_file, (unsigned) GetLastError ());
02279 
02280   CloseHandle (pi.hThread);
02281   CloseHandle (pi.hProcess);
02282 
02283   if (useshell && shell[0] != '\0')
02284     saw_create = -1;
02285   else
02286     saw_create = 0;
02287 
02288   do_initial_windows_stuff (ops, pi.dwProcessId, 0);
02289 
02290   /* windows_continue (DBG_CONTINUE, -1); */
02291 }
02292 
02293 static void
02294 windows_mourn_inferior (struct target_ops *ops)
02295 {
02296   (void) windows_continue (DBG_CONTINUE, -1);
02297   i386_cleanup_dregs();
02298   if (open_process_used)
02299     {
02300       CHECK (CloseHandle (current_process_handle));
02301       open_process_used = 0;
02302     }
02303   unpush_target (ops);
02304   generic_mourn_inferior ();
02305 }
02306 
02307 /* Send a SIGINT to the process group.  This acts just like the user typed a
02308    ^C on the controlling terminal.  */
02309 
02310 static void
02311 windows_stop (ptid_t ptid)
02312 {
02313   DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
02314   CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
02315   registers_changed ();         /* refresh register state */
02316 }
02317 
02318 /* Helper for windows_xfer_partial that handles memory transfers.
02319    Arguments are like target_xfer_partial.  */
02320 
02321 static LONGEST
02322 windows_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
02323                      ULONGEST memaddr, LONGEST len)
02324 {
02325   SIZE_T done = 0;
02326   BOOL success;
02327   DWORD lasterror = 0;
02328 
02329   if (writebuf != NULL)
02330     {
02331       DEBUG_MEM (("gdb: write target memory, %s bytes at %s\n",
02332                   plongest (len), core_addr_to_string (memaddr)));
02333       success = WriteProcessMemory (current_process_handle,
02334                                     (LPVOID) (uintptr_t) memaddr, writebuf,
02335                                     len, &done);
02336       if (!success)
02337         lasterror = GetLastError ();
02338       FlushInstructionCache (current_process_handle,
02339                              (LPCVOID) (uintptr_t) memaddr, len);
02340     }
02341   else
02342     {
02343       DEBUG_MEM (("gdb: read target memory, %s bytes at %s\n",
02344                   plongest (len), core_addr_to_string (memaddr)));
02345       success = ReadProcessMemory (current_process_handle,
02346                                    (LPCVOID) (uintptr_t) memaddr, readbuf,
02347                                    len, &done);
02348       if (!success)
02349         lasterror = GetLastError ();
02350     }
02351   if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0)
02352     return done;
02353   else
02354     return success ? done : TARGET_XFER_E_IO;
02355 }
02356 
02357 static void
02358 windows_kill_inferior (struct target_ops *ops)
02359 {
02360   CHECK (TerminateProcess (current_process_handle, 0));
02361 
02362   for (;;)
02363     {
02364       if (!windows_continue (DBG_CONTINUE, -1))
02365         break;
02366       if (!WaitForDebugEvent (&current_event, INFINITE))
02367         break;
02368       if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
02369         break;
02370     }
02371 
02372   target_mourn_inferior ();     /* Or just windows_mourn_inferior?  */
02373 }
02374 
02375 static void
02376 windows_prepare_to_store (struct regcache *regcache)
02377 {
02378   /* Do nothing, since we can store individual regs.  */
02379 }
02380 
02381 static int
02382 windows_can_run (void)
02383 {
02384   return 1;
02385 }
02386 
02387 static void
02388 windows_close (void)
02389 {
02390   DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n",
02391                 ptid_get_pid (inferior_ptid)));
02392 }
02393 
02394 /* Convert pid to printable format.  */
02395 static char *
02396 windows_pid_to_str (struct target_ops *ops, ptid_t ptid)
02397 {
02398   static char buf[80];
02399 
02400   if (ptid_get_tid (ptid) != 0)
02401     {
02402       snprintf (buf, sizeof (buf), "Thread %d.0x%lx",
02403                 ptid_get_pid (ptid), ptid_get_tid (ptid));
02404       return buf;
02405     }
02406 
02407   return normal_pid_to_str (ptid);
02408 }
02409 
02410 static LONGEST
02411 windows_xfer_shared_libraries (struct target_ops *ops,
02412                              enum target_object object, const char *annex,
02413                              gdb_byte *readbuf, const gdb_byte *writebuf,
02414                              ULONGEST offset, LONGEST len)
02415 {
02416   struct obstack obstack;
02417   const char *buf;
02418   LONGEST len_avail;
02419   struct so_list *so;
02420 
02421   if (writebuf)
02422     return -1;
02423 
02424   obstack_init (&obstack);
02425   obstack_grow_str (&obstack, "<library-list>\n");
02426   for (so = solib_start.next; so; so = so->next)
02427     windows_xfer_shared_library (so->so_name, (CORE_ADDR)
02428                                  (uintptr_t) so->lm_info->load_addr,
02429                                  target_gdbarch (), &obstack);
02430   obstack_grow_str0 (&obstack, "</library-list>\n");
02431 
02432   buf = obstack_finish (&obstack);
02433   len_avail = strlen (buf);
02434   if (offset >= len_avail)
02435     len= 0;
02436   else
02437     {
02438       if (len > len_avail - offset)
02439         len = len_avail - offset;
02440       memcpy (readbuf, buf + offset, len);
02441     }
02442 
02443   obstack_free (&obstack, NULL);
02444   return len;
02445 }
02446 
02447 static LONGEST
02448 windows_xfer_partial (struct target_ops *ops, enum target_object object,
02449                     const char *annex, gdb_byte *readbuf,
02450                     const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
02451 {
02452   switch (object)
02453     {
02454     case TARGET_OBJECT_MEMORY:
02455       return windows_xfer_memory (readbuf, writebuf, offset, len);
02456 
02457     case TARGET_OBJECT_LIBRARIES:
02458       return windows_xfer_shared_libraries (ops, object, annex, readbuf,
02459                                           writebuf, offset, len);
02460 
02461     default:
02462       if (ops->beneath != NULL)
02463         return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
02464                                               readbuf, writebuf, offset, len);
02465       return -1;
02466     }
02467 }
02468 
02469 /* Provide thread local base, i.e. Thread Information Block address.
02470    Returns 1 if ptid is found and sets *ADDR to thread_local_base.  */
02471 
02472 static int
02473 windows_get_tib_address (ptid_t ptid, CORE_ADDR *addr)
02474 {
02475   thread_info *th;
02476 
02477   th = thread_rec (ptid_get_tid (ptid), 0);
02478   if (th == NULL)
02479     return 0;
02480 
02481   if (addr != NULL)
02482     *addr = th->thread_local_base;
02483 
02484   return 1;
02485 }
02486 
02487 static ptid_t
02488 windows_get_ada_task_ptid (long lwp, long thread)
02489 {
02490   return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
02491 }
02492 
02493 static void
02494 init_windows_ops (void)
02495 {
02496   windows_ops.to_shortname = "child";
02497   windows_ops.to_longname = "Win32 child process";
02498   windows_ops.to_doc = "Win32 child process (started by the \"run\" command).";
02499   windows_ops.to_open = windows_open;
02500   windows_ops.to_close = windows_close;
02501   windows_ops.to_attach = windows_attach;
02502   windows_ops.to_attach_no_wait = 1;
02503   windows_ops.to_detach = windows_detach;
02504   windows_ops.to_resume = windows_resume;
02505   windows_ops.to_wait = windows_wait;
02506   windows_ops.to_fetch_registers = windows_fetch_inferior_registers;
02507   windows_ops.to_store_registers = windows_store_inferior_registers;
02508   windows_ops.to_prepare_to_store = windows_prepare_to_store;
02509   windows_ops.to_xfer_partial = windows_xfer_partial;
02510   windows_ops.to_files_info = windows_files_info;
02511   windows_ops.to_insert_breakpoint = memory_insert_breakpoint;
02512   windows_ops.to_remove_breakpoint = memory_remove_breakpoint;
02513   windows_ops.to_terminal_init = terminal_init_inferior;
02514   windows_ops.to_terminal_inferior = terminal_inferior;
02515   windows_ops.to_terminal_ours_for_output = terminal_ours_for_output;
02516   windows_ops.to_terminal_ours = terminal_ours;
02517   windows_ops.to_terminal_save_ours = terminal_save_ours;
02518   windows_ops.to_terminal_info = child_terminal_info;
02519   windows_ops.to_kill = windows_kill_inferior;
02520   windows_ops.to_create_inferior = windows_create_inferior;
02521   windows_ops.to_mourn_inferior = windows_mourn_inferior;
02522   windows_ops.to_can_run = windows_can_run;
02523   windows_ops.to_thread_alive = windows_thread_alive;
02524   windows_ops.to_pid_to_str = windows_pid_to_str;
02525   windows_ops.to_stop = windows_stop;
02526   windows_ops.to_stratum = process_stratum;
02527   windows_ops.to_has_all_memory = default_child_has_all_memory;
02528   windows_ops.to_has_memory = default_child_has_memory;
02529   windows_ops.to_has_stack = default_child_has_stack;
02530   windows_ops.to_has_registers = default_child_has_registers;
02531   windows_ops.to_has_execution = default_child_has_execution;
02532   windows_ops.to_pid_to_exec_file = windows_pid_to_exec_file;
02533   windows_ops.to_get_ada_task_ptid = windows_get_ada_task_ptid;
02534   windows_ops.to_get_tib_address = windows_get_tib_address;
02535 
02536   i386_use_watchpoints (&windows_ops);
02537 
02538   i386_dr_low.set_control = cygwin_set_dr7;
02539   i386_dr_low.set_addr = cygwin_set_dr;
02540   i386_dr_low.get_addr = cygwin_get_dr;
02541   i386_dr_low.get_status = cygwin_get_dr6;
02542   i386_dr_low.get_control = cygwin_get_dr7;
02543 
02544   /* i386_dr_low.debug_register_length field is set by
02545      calling i386_set_debug_register_length function
02546      in processor windows specific native file.  */
02547 
02548   windows_ops.to_magic = OPS_MAGIC;
02549 }
02550 
02551 static void
02552 set_windows_aliases (char *argv0)
02553 {
02554   add_info_alias ("dll", "sharedlibrary", 1);
02555 }
02556 
02557 /* -Wmissing-prototypes */
02558 extern initialize_file_ftype _initialize_windows_nat;
02559 
02560 void
02561 _initialize_windows_nat (void)
02562 {
02563   struct cmd_list_element *c;
02564 
02565   init_windows_ops ();
02566 
02567 #ifdef __CYGWIN__
02568   cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
02569 #endif
02570 
02571   c = add_com ("dll-symbols", class_files, dll_symbol_command,
02572                _("Load dll library symbols from FILE."));
02573   set_cmd_completer (c, filename_completer);
02574 
02575   add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
02576 
02577   add_com_alias ("add-shared-symbol-files", "dll-symbols", class_alias, 1);
02578 
02579   add_com_alias ("assf", "dll-symbols", class_alias, 1);
02580 
02581 #ifdef __CYGWIN__
02582   add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
02583 Set use of shell to start subprocess."), _("\
02584 Show use of shell to start subprocess."), NULL,
02585                            NULL,
02586                            NULL, /* FIXME: i18n: */
02587                            &setlist, &showlist);
02588 
02589   add_setshow_boolean_cmd ("cygwin-exceptions", class_support,
02590                            &cygwin_exceptions, _("\
02591 Break when an exception is detected in the Cygwin DLL itself."), _("\
02592 Show whether gdb breaks on exceptions in the Cygwin DLL itself."), NULL,
02593                            NULL,
02594                            NULL, /* FIXME: i18n: */
02595                            &setlist, &showlist);
02596 #endif
02597 
02598   add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\
02599 Set creation of new console when creating child process."), _("\
02600 Show creation of new console when creating child process."), NULL,
02601                            NULL,
02602                            NULL, /* FIXME: i18n: */
02603                            &setlist, &showlist);
02604 
02605   add_setshow_boolean_cmd ("new-group", class_support, &new_group, _("\
02606 Set creation of new group when creating child process."), _("\
02607 Show creation of new group when creating child process."), NULL,
02608                            NULL,
02609                            NULL, /* FIXME: i18n: */
02610                            &setlist, &showlist);
02611 
02612   add_setshow_boolean_cmd ("debugexec", class_support, &debug_exec, _("\
02613 Set whether to display execution in child process."), _("\
02614 Show whether to display execution in child process."), NULL,
02615                            NULL,
02616                            NULL, /* FIXME: i18n: */
02617                            &setlist, &showlist);
02618 
02619   add_setshow_boolean_cmd ("debugevents", class_support, &debug_events, _("\
02620 Set whether to display kernel events in child process."), _("\
02621 Show whether to display kernel events in child process."), NULL,
02622                            NULL,
02623                            NULL, /* FIXME: i18n: */
02624                            &setlist, &showlist);
02625 
02626   add_setshow_boolean_cmd ("debugmemory", class_support, &debug_memory, _("\
02627 Set whether to display memory accesses in child process."), _("\
02628 Show whether to display memory accesses in child process."), NULL,
02629                            NULL,
02630                            NULL, /* FIXME: i18n: */
02631                            &setlist, &showlist);
02632 
02633   add_setshow_boolean_cmd ("debugexceptions", class_support,
02634                            &debug_exceptions, _("\
02635 Set whether to display kernel exceptions in child process."), _("\
02636 Show whether to display kernel exceptions in child process."), NULL,
02637                            NULL,
02638                            NULL, /* FIXME: i18n: */
02639                            &setlist, &showlist);
02640 
02641   init_w32_command_list ();
02642 
02643   add_cmd ("selector", class_info, display_selectors,
02644            _("Display selectors infos."),
02645            &info_w32_cmdlist);
02646   add_target (&windows_ops);
02647   deprecated_init_ui_hook = set_windows_aliases;
02648 }
02649 
02650 /* Hardware watchpoint support, adapted from go32-nat.c code.  */
02651 
02652 /* Pass the address ADDR to the inferior in the I'th debug register.
02653    Here we just store the address in dr array, the registers will be
02654    actually set up when windows_continue is called.  */
02655 static void
02656 cygwin_set_dr (int i, CORE_ADDR addr)
02657 {
02658   if (i < 0 || i > 3)
02659     internal_error (__FILE__, __LINE__,
02660                     _("Invalid register %d in cygwin_set_dr.\n"), i);
02661   dr[i] = addr;
02662   debug_registers_changed = 1;
02663   debug_registers_used = 1;
02664 }
02665 
02666 /* Pass the value VAL to the inferior in the DR7 debug control
02667    register.  Here we just store the address in D_REGS, the watchpoint
02668    will be actually set up in windows_wait.  */
02669 static void
02670 cygwin_set_dr7 (unsigned long val)
02671 {
02672   dr[7] = (CORE_ADDR) val;
02673   debug_registers_changed = 1;
02674   debug_registers_used = 1;
02675 }
02676 
02677 /* Get the value of debug register I from the inferior.  */
02678 
02679 static CORE_ADDR
02680 cygwin_get_dr (int i)
02681 {
02682   return dr[i];
02683 }
02684 
02685 /* Get the value of the DR6 debug status register from the inferior.
02686    Here we just return the value stored in dr[6]
02687    by the last call to thread_rec for current_event.dwThreadId id.  */
02688 static unsigned long
02689 cygwin_get_dr6 (void)
02690 {
02691   return (unsigned long) dr[6];
02692 }
02693 
02694 /* Get the value of the DR7 debug status register from the inferior.
02695    Here we just return the value stored in dr[7] by the last call to
02696    thread_rec for current_event.dwThreadId id.  */
02697 
02698 static unsigned long
02699 cygwin_get_dr7 (void)
02700 {
02701   return (unsigned long) dr[7];
02702 }
02703 
02704 /* Determine if the thread referenced by "ptid" is alive
02705    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
02706    it means that the thread has died.  Otherwise it is assumed to be alive.  */
02707 static int
02708 windows_thread_alive (struct target_ops *ops, ptid_t ptid)
02709 {
02710   int tid;
02711 
02712   gdb_assert (ptid_get_tid (ptid) != 0);
02713   tid = ptid_get_tid (ptid);
02714 
02715   return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0
02716     ? FALSE : TRUE;
02717 }
02718 
02719 /* -Wmissing-prototypes */
02720 extern initialize_file_ftype _initialize_check_for_gdb_ini;
02721 
02722 void
02723 _initialize_check_for_gdb_ini (void)
02724 {
02725   char *homedir;
02726   if (inhibit_gdbinit)
02727     return;
02728 
02729   homedir = getenv ("HOME");
02730   if (homedir)
02731     {
02732       char *p;
02733       char *oldini = (char *) alloca (strlen (homedir) +
02734                                       sizeof ("/gdb.ini"));
02735       strcpy (oldini, homedir);
02736       p = strchr (oldini, '\0');
02737       if (p > oldini && !IS_DIR_SEPARATOR (p[-1]))
02738         *p++ = '/';
02739       strcpy (p, "gdb.ini");
02740       if (access (oldini, 0) == 0)
02741         {
02742           int len = strlen (oldini);
02743           char *newini = alloca (len + 1);
02744 
02745           xsnprintf (newini, len + 1, "%.*s.gdbinit",
02746                      (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
02747           warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini);
02748         }
02749     }
02750 }
02751 
02752 /* Define dummy functions which always return error for the rare cases where
02753    these functions could not be found.  */
02754 static BOOL WINAPI
02755 bad_DebugActiveProcessStop (DWORD w)
02756 {
02757   return FALSE;
02758 }
02759 static BOOL WINAPI
02760 bad_DebugBreakProcess (HANDLE w)
02761 {
02762   return FALSE;
02763 }
02764 static BOOL WINAPI
02765 bad_DebugSetProcessKillOnExit (BOOL w)
02766 {
02767   return FALSE;
02768 }
02769 static BOOL WINAPI
02770 bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
02771 {
02772   return FALSE;
02773 }
02774 
02775 #ifdef __USEWIDE
02776 static DWORD WINAPI
02777 bad_GetModuleFileNameExW (HANDLE w, HMODULE x, LPWSTR y, DWORD z)
02778 {
02779   return 0;
02780 }
02781 #else
02782 static DWORD WINAPI
02783 bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
02784 {
02785   return 0;
02786 }
02787 #endif
02788 
02789 static BOOL WINAPI
02790 bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
02791 {
02792   return FALSE;
02793 }
02794 
02795 static BOOL WINAPI
02796 bad_OpenProcessToken (HANDLE w, DWORD x, PHANDLE y)
02797 {
02798   return FALSE;
02799 }
02800 
02801 static BOOL WINAPI
02802 bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
02803 {
02804   f->nFont = 0;
02805   return 1;
02806 }
02807 static COORD WINAPI
02808 bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
02809 {
02810   COORD size;
02811   size.X = 8;
02812   size.Y = 12;
02813   return size;
02814 }
02815  
02816 /* -Wmissing-prototypes */
02817 extern initialize_file_ftype _initialize_loadable;
02818 
02819 /* Load any functions which may not be available in ancient versions
02820    of Windows.  */
02821 
02822 void
02823 _initialize_loadable (void)
02824 {
02825   HMODULE hm = NULL;
02826 
02827   hm = LoadLibrary ("kernel32.dll");
02828   if (hm)
02829     {
02830       DebugActiveProcessStop = (void *)
02831         GetProcAddress (hm, "DebugActiveProcessStop");
02832       DebugBreakProcess = (void *)
02833         GetProcAddress (hm, "DebugBreakProcess");
02834       DebugSetProcessKillOnExit = (void *)
02835         GetProcAddress (hm, "DebugSetProcessKillOnExit");
02836       GetConsoleFontSize = (void *) 
02837         GetProcAddress (hm, "GetConsoleFontSize");
02838       GetCurrentConsoleFont = (void *) 
02839         GetProcAddress (hm, "GetCurrentConsoleFont");
02840     }
02841 
02842   /* Set variables to dummy versions of these processes if the function
02843      wasn't found in kernel32.dll.  */
02844   if (!DebugBreakProcess)
02845     DebugBreakProcess = bad_DebugBreakProcess;
02846   if (!DebugActiveProcessStop || !DebugSetProcessKillOnExit)
02847     {
02848       DebugActiveProcessStop = bad_DebugActiveProcessStop;
02849       DebugSetProcessKillOnExit = bad_DebugSetProcessKillOnExit;
02850     }
02851   if (!GetConsoleFontSize)
02852     GetConsoleFontSize = bad_GetConsoleFontSize;
02853   if (!GetCurrentConsoleFont)
02854     GetCurrentConsoleFont = bad_GetCurrentConsoleFont;
02855 
02856   /* Load optional functions used for retrieving filename information
02857      associated with the currently debugged process or its dlls.  */
02858   hm = LoadLibrary ("psapi.dll");
02859   if (hm)
02860     {
02861       EnumProcessModules = (void *)
02862         GetProcAddress (hm, "EnumProcessModules");
02863       GetModuleInformation = (void *)
02864         GetProcAddress (hm, "GetModuleInformation");
02865       GetModuleFileNameEx = (void *)
02866         GetProcAddress (hm, GetModuleFileNameEx_name);
02867     }
02868 
02869   if (!EnumProcessModules || !GetModuleInformation || !GetModuleFileNameEx)
02870     {
02871       /* Set variables to dummy versions of these processes if the function
02872          wasn't found in psapi.dll.  */
02873       EnumProcessModules = bad_EnumProcessModules;
02874       GetModuleInformation = bad_GetModuleInformation;
02875       GetModuleFileNameEx = bad_GetModuleFileNameEx;
02876       /* This will probably fail on Windows 9x/Me.  Let the user know
02877          that we're missing some functionality.  */
02878       warning(_("\
02879 cannot automatically find executable file or library to read symbols.\n\
02880 Use \"file\" or \"dll\" command to load executable/libraries directly."));
02881     }
02882 
02883   hm = LoadLibrary ("advapi32.dll");
02884   if (hm)
02885     {
02886       OpenProcessToken = (void *) GetProcAddress (hm, "OpenProcessToken");
02887       LookupPrivilegeValueA = (void *)
02888         GetProcAddress (hm, "LookupPrivilegeValueA");
02889       AdjustTokenPrivileges = (void *)
02890         GetProcAddress (hm, "AdjustTokenPrivileges");
02891       /* Only need to set one of these since if OpenProcessToken fails nothing
02892          else is needed.  */
02893       if (!OpenProcessToken || !LookupPrivilegeValueA
02894           || !AdjustTokenPrivileges)
02895         OpenProcessToken = bad_OpenProcessToken;
02896     }
02897 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines