gdb/windows-nat.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "frame.h"
- #include "inferior.h"
- #include "infrun.h"
- #include "target.h"
- #include "gdbcore.h"
- #include "command.h"
- #include "completer.h"
- #include "regcache.h"
- #include "top.h"
- #include <signal.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <windows.h>
- #include <imagehlp.h>
- #include <psapi.h>
- #ifdef __CYGWIN__
- #include <wchar.h>
- #include <sys/cygwin.h>
- #include <cygwin/version.h>
- #endif
- #include "buildsym.h"
- #include "filenames.h"
- #include "symfile.h"
- #include "objfiles.h"
- #include "gdb_bfd.h"
- #include "gdb_obstack.h"
- #include "gdbthread.h"
- #include "gdbcmd.h"
- #include <unistd.h>
- #include "exec.h"
- #include "solist.h"
- #include "solib.h"
- #include "xml-support.h"
- #include "i386-tdep.h"
- #include "i387-tdep.h"
- #include "windows-tdep.h"
- #include "windows-nat.h"
- #include "x86-nat.h"
- #include "complaints.h"
- #include "inf-child.h"
- #define AdjustTokenPrivileges dyn_AdjustTokenPrivileges
- #define DebugActiveProcessStop dyn_DebugActiveProcessStop
- #define DebugBreakProcess dyn_DebugBreakProcess
- #define DebugSetProcessKillOnExit dyn_DebugSetProcessKillOnExit
- #define EnumProcessModules dyn_EnumProcessModules
- #define GetModuleInformation dyn_GetModuleInformation
- #define LookupPrivilegeValueA dyn_LookupPrivilegeValueA
- #define OpenProcessToken dyn_OpenProcessToken
- #define GetConsoleFontSize dyn_GetConsoleFontSize
- #define GetCurrentConsoleFont dyn_GetCurrentConsoleFont
- static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
- DWORD, PTOKEN_PRIVILEGES, PDWORD);
- static BOOL WINAPI (*DebugActiveProcessStop) (DWORD);
- static BOOL WINAPI (*DebugBreakProcess) (HANDLE);
- static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
- static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
- LPDWORD);
- static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
- DWORD);
- static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
- static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
- static BOOL WINAPI (*GetCurrentConsoleFont) (HANDLE, BOOL,
- CONSOLE_FONT_INFO *);
- static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD);
- #undef STARTUPINFO
- #undef CreateProcess
- #undef GetModuleFileNameEx
- #ifndef __CYGWIN__
- # define __PMAX (MAX_PATH + 1)
- static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD);
- # define STARTUPINFO STARTUPINFOA
- # define CreateProcess CreateProcessA
- # define GetModuleFileNameEx_name "GetModuleFileNameExA"
- # define bad_GetModuleFileNameEx bad_GetModuleFileNameExA
- #else
- # define __PMAX PATH_MAX
- static CORE_ADDR cygwin_load_start;
- static CORE_ADDR cygwin_load_end;
- # define __USEWIDE
- typedef wchar_t cygwin_buf_t;
- static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE,
- LPWSTR, DWORD);
- # define STARTUPINFO STARTUPINFOW
- # define CreateProcess CreateProcessW
- # define GetModuleFileNameEx_name "GetModuleFileNameExW"
- # define bad_GetModuleFileNameEx bad_GetModuleFileNameExW
- #endif
- static int have_saved_context;
- static CONTEXT saved_context;
- #ifndef _GNU_H_WINDOWS_H
- enum
- {
- FLAG_TRACE_BIT = 0x100,
- CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
- };
- #endif
- #ifndef CONTEXT_EXTENDED_REGISTERS
- #define CONTEXT_EXTENDED_REGISTERS 0
- #endif
- #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
- | CONTEXT_EXTENDED_REGISTERS
- static uintptr_t dr[8];
- static int debug_registers_changed;
- static int debug_registers_used;
- static int windows_initialization_done;
- #define DR6_CLEAR_VALUE 0xffff0ff0
- FIXME
- #ifndef _CYGWIN_SIGNAL_STRING
- #define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
- #endif
- #define CHECK(x) check (x, __FILE__,__LINE__)
- #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
- #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
- #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
- #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
- static void windows_stop (struct target_ops *self, ptid_t);
- static int windows_thread_alive (struct target_ops *, ptid_t);
- static void windows_kill_inferior (struct target_ops *);
- static void cygwin_set_dr (int i, CORE_ADDR addr);
- static void cygwin_set_dr7 (unsigned long val);
- static CORE_ADDR cygwin_get_dr (int i);
- static unsigned long cygwin_get_dr6 (void);
- static unsigned long cygwin_get_dr7 (void);
- static enum gdb_signal last_sig = GDB_SIGNAL_0;
- typedef struct thread_info_struct
- {
- struct thread_info_struct *next;
- DWORD id;
- HANDLE h;
- CORE_ADDR thread_local_base;
- char *name;
- int suspended;
- int reload_context;
- CONTEXT context;
- STACKFRAME sf;
- }
- thread_info;
- static thread_info thread_head;
- static DEBUG_EVENT current_event;
- static HANDLE current_process_handle;
- static thread_info *current_thread;
- static DWORD main_thread_id;
- static int exception_count = 0;
- static int event_count = 0;
- static int saw_create;
- static int open_process_used = 0;
- static int new_console = 0;
- #ifdef __CYGWIN__
- static int cygwin_exceptions = 0;
- #endif
- static int new_group = 1;
- static int debug_exec = 0;
- static int debug_events = 0;
- static int debug_memory = 0;
- static int debug_exceptions = 0;
- static int useshell = 0;
- static const int *mappings;
- static segment_register_p_ftype *segment_register_p;
- struct xlate_exception
- {
- int them;
- enum gdb_signal us;
- };
- static const struct xlate_exception
- xlate[] =
- {
- {EXCEPTION_ACCESS_VIOLATION, GDB_SIGNAL_SEGV},
- {STATUS_STACK_OVERFLOW, GDB_SIGNAL_SEGV},
- {EXCEPTION_BREAKPOINT, GDB_SIGNAL_TRAP},
- {DBG_CONTROL_C, GDB_SIGNAL_INT},
- {EXCEPTION_SINGLE_STEP, GDB_SIGNAL_TRAP},
- {STATUS_FLOAT_DIVIDE_BY_ZERO, GDB_SIGNAL_FPE},
- {-1, -1}};
- void
- windows_set_context_register_offsets (const int *offsets)
- {
- mappings = offsets;
- }
- void
- windows_set_segment_register_p (segment_register_p_ftype *fun)
- {
- segment_register_p = fun;
- }
- static void
- check (BOOL ok, const char *file, int line)
- {
- if (!ok)
- printf_filtered ("error return %s:%d was %u\n", file, line,
- (unsigned) GetLastError ());
- }
- static thread_info *
- thread_rec (DWORD id, int get_context)
- {
- thread_info *th;
- for (th = &thread_head; (th = th->next) != NULL;)
- if (th->id == id)
- {
- if (!th->suspended && get_context)
- {
- if (get_context > 0 && id != current_event.dwThreadId)
- {
- if (SuspendThread (th->h) == (DWORD) -1)
- {
- DWORD err = GetLastError ();
-
- if (err != ERROR_ACCESS_DENIED)
- warning (_("SuspendThread (tid=0x%x) failed."
- " (winerr %u)"),
- (unsigned) id, (unsigned) err);
- th->suspended = -1;
- }
- else
- th->suspended = 1;
- }
- else if (get_context < 0)
- th->suspended = -1;
- th->reload_context = 1;
- }
- return th;
- }
- return NULL;
- }
- static thread_info *
- windows_add_thread (ptid_t ptid, HANDLE h, void *tlb)
- {
- thread_info *th;
- DWORD id;
- gdb_assert (ptid_get_tid (ptid) != 0);
- id = ptid_get_tid (ptid);
- if ((th = thread_rec (id, FALSE)))
- return th;
- th = XCNEW (thread_info);
- th->id = id;
- th->h = h;
- th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb;
- th->next = thread_head.next;
- thread_head.next = th;
- add_thread (ptid);
-
- if (debug_registers_used)
- {
-
- th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
- CHECK (GetThreadContext (th->h, &th->context));
- th->context.Dr0 = dr[0];
- th->context.Dr1 = dr[1];
- th->context.Dr2 = dr[2];
- th->context.Dr3 = dr[3];
- th->context.Dr6 = DR6_CLEAR_VALUE;
- th->context.Dr7 = dr[7];
- CHECK (SetThreadContext (th->h, &th->context));
- th->context.ContextFlags = 0;
- }
- return th;
- }
- static void
- windows_init_thread_list (void)
- {
- thread_info *th = &thread_head;
- DEBUG_EVENTS (("gdb: windows_init_thread_list\n"));
- init_thread_list ();
- while (th->next != NULL)
- {
- thread_info *here = th->next;
- th->next = here->next;
- xfree (here);
- }
- thread_head.next = NULL;
- }
- static void
- windows_delete_thread (ptid_t ptid, DWORD exit_code)
- {
- thread_info *th;
- DWORD id;
- gdb_assert (ptid_get_tid (ptid) != 0);
- id = ptid_get_tid (ptid);
- if (info_verbose)
- printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid));
- else if (print_thread_events && id != main_thread_id)
- printf_unfiltered (_("[%s exited with code %u]\n"),
- target_pid_to_str (ptid), (unsigned) exit_code);
- delete_thread (ptid);
- for (th = &thread_head;
- th->next != NULL && th->next->id != id;
- th = th->next)
- continue;
- if (th->next != NULL)
- {
- thread_info *here = th->next;
- th->next = here->next;
- xfree (here);
- }
- }
- static void
- do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
- {
- char *context_offset = ((char *) ¤t_thread->context) + mappings[r];
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- long l;
- if (!current_thread)
- return;
- if (current_thread->reload_context)
- {
- #ifdef __COPY_CONTEXT_SIZE
- if (have_saved_context)
- {
-
- memcpy (¤t_thread->context, &saved_context,
- __COPY_CONTEXT_SIZE);
- have_saved_context = 0;
- }
- else
- #endif
- {
- thread_info *th = current_thread;
- th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
- CHECK (GetThreadContext (th->h, &th->context));
-
- if (!debug_registers_changed)
- {
- dr[0] = th->context.Dr0;
- dr[1] = th->context.Dr1;
- dr[2] = th->context.Dr2;
- dr[3] = th->context.Dr3;
- dr[6] = th->context.Dr6;
- dr[7] = th->context.Dr7;
- }
- }
- current_thread->reload_context = 0;
- }
- if (r == I387_FISEG_REGNUM (tdep))
- {
- l = *((long *) context_offset) & 0xffff;
- regcache_raw_supply (regcache, r, (char *) &l);
- }
- else if (r == I387_FOP_REGNUM (tdep))
- {
- l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
- regcache_raw_supply (regcache, r, (char *) &l);
- }
- else if (segment_register_p (r))
- {
-
- l = *((long *) context_offset) & 0xffff;
- regcache_raw_supply (regcache, r, (char *) &l);
- }
- else if (r >= 0)
- regcache_raw_supply (regcache, r, context_offset);
- else
- {
- for (r = 0; r < gdbarch_num_regs (gdbarch); r++)
- do_windows_fetch_inferior_registers (regcache, r);
- }
- }
- static void
- windows_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int r)
- {
- current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
-
- if (current_thread)
- do_windows_fetch_inferior_registers (regcache, r);
- }
- static void
- do_windows_store_inferior_registers (const struct regcache *regcache, int r)
- {
- if (!current_thread)
- ;
- else if (r >= 0)
- regcache_raw_collect (regcache, r,
- ((char *) ¤t_thread->context) + mappings[r]);
- else
- {
- for (r = 0; r < gdbarch_num_regs (get_regcache_arch (regcache)); r++)
- do_windows_store_inferior_registers (regcache, r);
- }
- }
- static void
- windows_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int r)
- {
- current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
-
- if (current_thread)
- do_windows_store_inferior_registers (regcache, r);
- }
- struct safe_symbol_file_add_args
- {
- char *name;
- int from_tty;
- struct section_addr_info *addrs;
- int mainline;
- int flags;
- struct ui_file *err, *out;
- struct objfile *ret;
- };
- struct lm_info
- {
- LPVOID load_addr;
- };
- static struct so_list solib_start, *solib_end;
- static struct so_list *
- windows_make_so (const char *name, LPVOID load_addr)
- {
- struct so_list *so;
- char *p;
- #ifndef __CYGWIN__
- char buf[__PMAX];
- char cwd[__PMAX];
- WIN32_FIND_DATA w32_fd;
- HANDLE h = FindFirstFile(name, &w32_fd);
- if (h == INVALID_HANDLE_VALUE)
- strcpy (buf, name);
- else
- {
- FindClose (h);
- strcpy (buf, name);
- if (GetCurrentDirectory (MAX_PATH + 1, cwd))
- {
- p = strrchr (buf, '\\');
- if (p)
- p[1] = '\0';
- SetCurrentDirectory (buf);
- GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
- SetCurrentDirectory (cwd);
- }
- }
- if (strcasecmp (buf, "ntdll.dll") == 0)
- {
- GetSystemDirectory (buf, sizeof (buf));
- strcat (buf, "\\ntdll.dll");
- }
- #else
- cygwin_buf_t buf[__PMAX];
- buf[0] = 0;
- if (access (name, F_OK) != 0)
- {
- if (strcasecmp (name, "ntdll.dll") == 0)
- #ifdef __USEWIDE
- {
- GetSystemDirectoryW (buf, sizeof (buf) / sizeof (wchar_t));
- wcscat (buf, L"\\ntdll.dll");
- }
- #else
- {
- GetSystemDirectoryA (buf, sizeof (buf) / sizeof (wchar_t));
- strcat (buf, "\\ntdll.dll");
- }
- #endif
- }
- #endif
- so = XCNEW (struct so_list);
- so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
- so->lm_info->load_addr = load_addr;
- strcpy (so->so_original_name, name);
- #ifndef __CYGWIN__
- strcpy (so->so_name, buf);
- #else
- if (buf[0])
- cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
- SO_NAME_MAX_PATH_SIZE);
- else
- {
- char *rname = realpath (name, NULL);
- if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE)
- {
- strcpy (so->so_name, rname);
- free (rname);
- }
- else
- error (_("dll path too long"));
- }
-
- p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
- if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
- {
- bfd *abfd;
- asection *text = NULL;
- CORE_ADDR text_vma;
- abfd = gdb_bfd_open (so->so_name, "pei-i386", -1);
- if (!abfd)
- return so;
- if (bfd_check_format (abfd, bfd_object))
- text = bfd_get_section_by_name (abfd, ".text");
- if (!text)
- {
- gdb_bfd_unref (abfd);
- return so;
- }
-
- cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *)
- load_addr + 0x1000);
- cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text);
- gdb_bfd_unref (abfd);
- }
- #endif
- return so;
- }
- static char *
- get_image_name (HANDLE h, void *address, int unicode)
- {
- #ifdef __CYGWIN__
- static char buf[__PMAX];
- #else
- static char buf[(2 * __PMAX) + 1];
- #endif
- DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
- char *address_ptr;
- int len = 0;
- char b[2];
- SIZE_T done;
-
- if (address == NULL)
- return NULL;
-
- if (!ReadProcessMemory (h, address, &address_ptr,
- sizeof (address_ptr), &done)
- || done != sizeof (address_ptr) || !address_ptr)
- return NULL;
-
- while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
- && (b[0] != 0 || b[size - 1] != 0) && done == size)
- continue;
- if (!unicode)
- ReadProcessMemory (h, address_ptr, buf, len, &done);
- else
- {
- WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
- ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
- &done);
- #ifdef __CYGWIN__
- wcstombs (buf, unicode_address, __PMAX);
- #else
- WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
- 0, 0);
- #endif
- }
- return buf;
- }
- static int
- handle_load_dll (void *dummy)
- {
- LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
- char *dll_name;
-
- dll_name = get_image_name (current_process_handle,
- event->lpImageName, event->fUnicode);
- if (!dll_name)
- return 1;
- solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
- solib_end = solib_end->next;
- DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name,
- host_address_to_string (solib_end->lm_info->load_addr)));
- return 1;
- }
- static void
- windows_free_so (struct so_list *so)
- {
- if (so->lm_info)
- xfree (so->lm_info);
- xfree (so);
- }
- static int
- handle_unload_dll (void *dummy)
- {
- LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
- struct so_list *so;
- for (so = &solib_start; so->next != NULL; so = so->next)
- if (so->next->lm_info->load_addr == lpBaseOfDll)
- {
- struct so_list *sodel = so->next;
- so->next = sodel->next;
- if (!so->next)
- solib_end = so;
- DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
- windows_free_so (sodel);
- return 1;
- }
-
- complaint (&symfile_complaints, _("dll starting at %s not found."),
- host_address_to_string (lpBaseOfDll));
- return 0;
- }
- static void
- windows_clear_solib (void)
- {
- solib_start.next = NULL;
- solib_end = &solib_start;
- }
- static int
- handle_output_debug_string (struct target_waitstatus *ourstatus)
- {
- char *s = NULL;
- int retval = 0;
- if (!target_read_string
- ((CORE_ADDR) (uintptr_t) current_event.u.DebugString.lpDebugStringData,
- &s, 1024, 0)
- || !s || !*s)
- ;
- else if (strncmp (s, _CYGWIN_SIGNAL_STRING,
- sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0)
- {
- #ifdef __CYGWIN__
- if (strncmp (s, "cYg", 3) != 0)
- #endif
- warning (("%s"), s);
- }
- #ifdef __COPY_CONTEXT_SIZE
- else
- {
-
- char *p;
- int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
- int gotasig = gdb_signal_from_host (sig);
- ourstatus->value.sig = gotasig;
- if (gotasig)
- {
- LPCVOID x;
- SIZE_T n;
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
- retval = strtoul (p, &p, 0);
- if (!retval)
- retval = main_thread_id;
- else if ((x = (LPCVOID) (uintptr_t) strtoull (p, NULL, 0))
- && ReadProcessMemory (current_process_handle, x,
- &saved_context,
- __COPY_CONTEXT_SIZE, &n)
- && n == __COPY_CONTEXT_SIZE)
- have_saved_context = 1;
- current_event.dwThreadId = retval;
- }
- }
- #endif
- if (s)
- xfree (s);
- return retval;
- }
- static int
- display_selector (HANDLE thread, DWORD sel)
- {
- LDT_ENTRY info;
- if (GetThreadSelectorEntry (thread, sel, &info))
- {
- int base, limit;
- printf_filtered ("0x%03x: ", (unsigned) sel);
- if (!info.HighWord.Bits.Pres)
- {
- puts_filtered ("Segment not present\n");
- return 0;
- }
- base = (info.HighWord.Bits.BaseHi << 24) +
- (info.HighWord.Bits.BaseMid << 16)
- + info.BaseLow;
- limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
- if (info.HighWord.Bits.Granularity)
- limit = (limit << 12) | 0xfff;
- printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
- if (info.HighWord.Bits.Default_Big)
- puts_filtered(" 32-bit ");
- else
- puts_filtered(" 16-bit ");
- switch ((info.HighWord.Bits.Type & 0xf) >> 1)
- {
- case 0:
- puts_filtered ("Data (Read-Only, Exp-up");
- break;
- case 1:
- puts_filtered ("Data (Read/Write, Exp-up");
- break;
- case 2:
- puts_filtered ("Unused segment (");
- break;
- case 3:
- puts_filtered ("Data (Read/Write, Exp-down");
- break;
- case 4:
- puts_filtered ("Code (Exec-Only, N.Conf");
- break;
- case 5:
- puts_filtered ("Code (Exec/Read, N.Conf");
- break;
- case 6:
- puts_filtered ("Code (Exec-Only, Conf");
- break;
- case 7:
- puts_filtered ("Code (Exec/Read, Conf");
- break;
- default:
- printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
- }
- if ((info.HighWord.Bits.Type & 0x1) == 0)
- puts_filtered(", N.Acc");
- puts_filtered (")\n");
- if ((info.HighWord.Bits.Type & 0x10) == 0)
- puts_filtered("System selector ");
- printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
- if (info.HighWord.Bits.Granularity)
- puts_filtered ("Page granular.\n");
- else
- puts_filtered ("Byte granular.\n");
- return 1;
- }
- else
- {
- DWORD err = GetLastError ();
- if (err == ERROR_NOT_SUPPORTED)
- printf_filtered ("Function not supported\n");
- else
- printf_filtered ("Invalid selector 0x%x.\n", (unsigned) sel);
- return 0;
- }
- }
- static void
- display_selectors (char * args, int from_tty)
- {
- if (!current_thread)
- {
- puts_filtered ("Impossible to display selectors now.\n");
- return;
- }
- if (!args)
- {
- puts_filtered ("Selector $cs\n");
- display_selector (current_thread->h,
- current_thread->context.SegCs);
- puts_filtered ("Selector $ds\n");
- display_selector (current_thread->h,
- current_thread->context.SegDs);
- puts_filtered ("Selector $es\n");
- display_selector (current_thread->h,
- current_thread->context.SegEs);
- puts_filtered ("Selector $ss\n");
- display_selector (current_thread->h,
- current_thread->context.SegSs);
- puts_filtered ("Selector $fs\n");
- display_selector (current_thread->h,
- current_thread->context.SegFs);
- puts_filtered ("Selector $gs\n");
- display_selector (current_thread->h,
- current_thread->context.SegGs);
- }
- else
- {
- int sel;
- sel = parse_and_eval_long (args);
- printf_filtered ("Selector \"%s\"\n",args);
- display_selector (current_thread->h, sel);
- }
- }
- #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
- printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
- host_address_to_string (\
- current_event.u.Exception.ExceptionRecord.ExceptionAddress))
- static int
- handle_exception (struct target_waitstatus *ourstatus)
- {
- thread_info *th;
- DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
-
- th = thread_rec (current_event.dwThreadId, -1);
- switch (code)
- {
- case EXCEPTION_ACCESS_VIOLATION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
- #ifdef __CYGWIN__
- {
-
- const char *fn;
- CORE_ADDR addr = (CORE_ADDR) (uintptr_t)
- current_event.u.Exception.ExceptionRecord.ExceptionAddress;
- if ((!cygwin_exceptions && (addr >= cygwin_load_start
- && addr < cygwin_load_end))
- || (find_pc_partial_function (addr, &fn, NULL, NULL)
- && strncmp (fn, "KERNEL32!IsBad",
- strlen ("KERNEL32!IsBad")) == 0))
- return 0;
- }
- #endif
- break;
- case STATUS_STACK_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
- break;
- case STATUS_FLOAT_DENORMAL_OPERAND:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INEXACT_RESULT:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INVALID_OPERATION:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_STACK_CHECK:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_UNDERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_DIVIDE_BY_ZERO:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_DIVIDE_BY_ZERO:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_BREAKPOINT:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case DBG_CONTROL_C:
- DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case DBG_CONTROL_BREAK:
- DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case EXCEPTION_SINGLE_STEP:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_PRIV_INSTRUCTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- default:
-
- if (current_event.u.Exception.dwFirstChance)
- return -1;
- printf_unfiltered ("gdb: unknown target exception 0x%08x at %s\n",
- (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
- host_address_to_string (
- current_event.u.Exception.ExceptionRecord.ExceptionAddress));
- ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
- break;
- }
- exception_count++;
- last_sig = ourstatus->value.sig;
- return 1;
- }
- static BOOL
- windows_continue (DWORD continue_status, int id, int killed)
- {
- int i;
- thread_info *th;
- BOOL res;
- DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s);\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- continue_status == DBG_CONTINUE ?
- "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
- for (th = &thread_head; (th = th->next) != NULL;)
- if ((id == -1 || id == (int) th->id)
- && th->suspended)
- {
- if (debug_registers_changed)
- {
- th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
- th->context.Dr0 = dr[0];
- th->context.Dr1 = dr[1];
- th->context.Dr2 = dr[2];
- th->context.Dr3 = dr[3];
- th->context.Dr6 = DR6_CLEAR_VALUE;
- th->context.Dr7 = dr[7];
- }
- if (th->context.ContextFlags)
- {
- DWORD ec = 0;
- if (GetExitCodeThread (th->h, &ec)
- && ec == STILL_ACTIVE)
- {
- BOOL status = SetThreadContext (th->h, &th->context);
- if (!killed)
- CHECK (status);
- }
- th->context.ContextFlags = 0;
- }
- if (th->suspended > 0)
- (void) ResumeThread (th->h);
- th->suspended = 0;
- }
- res = ContinueDebugEvent (current_event.dwProcessId,
- current_event.dwThreadId,
- continue_status);
- debug_registers_changed = 0;
- return res;
- }
- static DWORD
- fake_create_process (void)
- {
- current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
- current_event.dwProcessId);
- if (current_process_handle != NULL)
- open_process_used = 1;
- else
- {
- error (_("OpenProcess call failed, GetLastError = %u"),
- (unsigned) GetLastError ());
-
- }
- main_thread_id = current_event.dwThreadId;
- current_thread = windows_add_thread (
- ptid_build (current_event.dwProcessId, 0,
- current_event.dwThreadId),
- current_event.u.CreateThread.hThread,
- current_event.u.CreateThread.lpThreadLocalBase);
- return main_thread_id;
- }
- static void
- windows_resume (struct target_ops *ops,
- ptid_t ptid, int step, enum gdb_signal sig)
- {
- thread_info *th;
- DWORD continue_status = DBG_CONTINUE;
-
- int resume_all = ptid_equal (ptid, minus_one_ptid);
-
- if (resume_all)
- ptid = inferior_ptid;
- if (sig != GDB_SIGNAL_0)
- {
- if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
- {
- DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
- }
- else if (sig == last_sig)
- continue_status = DBG_EXCEPTION_NOT_HANDLED;
- else
- #if 0
- #endif
- DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
- last_sig));
- }
- last_sig = GDB_SIGNAL_0;
- DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n",
- ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig));
-
- th = thread_rec (ptid_get_tid (inferior_ptid), FALSE);
- if (th)
- {
- if (step)
- {
-
- struct regcache *regcache = get_current_regcache ();
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- windows_fetch_inferior_registers (ops, regcache,
- gdbarch_ps_regnum (gdbarch));
- th->context.EFlags |= FLAG_TRACE_BIT;
- }
- if (th->context.ContextFlags)
- {
- if (debug_registers_changed)
- {
- th->context.Dr0 = dr[0];
- th->context.Dr1 = dr[1];
- th->context.Dr2 = dr[2];
- th->context.Dr3 = dr[3];
- th->context.Dr6 = DR6_CLEAR_VALUE;
- th->context.Dr7 = dr[7];
- }
- CHECK (SetThreadContext (th->h, &th->context));
- th->context.ContextFlags = 0;
- }
- }
-
- if (resume_all)
- windows_continue (continue_status, -1, 0);
- else
- windows_continue (continue_status, ptid_get_tid (ptid), 0);
- }
- static BOOL WINAPI
- ctrl_c_handler (DWORD event_type)
- {
- const int attach_flag = current_inferior ()->attach_flag;
-
- if (event_type != CTRL_C_EVENT && event_type != CTRL_BREAK_EVENT)
- return FALSE;
-
- if (!new_console && !attach_flag)
- return TRUE;
- if (!DebugBreakProcess (current_process_handle))
- warning (_("Could not interrupt program. "
- "Press Ctrl-c in the program console."));
-
- return TRUE;
- }
- static int
- get_windows_debug_event (struct target_ops *ops,
- int pid, struct target_waitstatus *ourstatus)
- {
- BOOL debug_event;
- DWORD continue_status, event_code;
- thread_info *th;
- static thread_info dummy_thread_info;
- int retval = 0;
- last_sig = GDB_SIGNAL_0;
- if (!(debug_event = WaitForDebugEvent (¤t_event, 1000)))
- goto out;
- event_count++;
- continue_status = DBG_CONTINUE;
- event_code = current_event.dwDebugEventCode;
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
- th = NULL;
- have_saved_context = 0;
- switch (event_code)
- {
- case CREATE_THREAD_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "CREATE_THREAD_DEBUG_EVENT"));
- if (saw_create != 1)
- {
- struct inferior *inf;
- inf = find_inferior_pid (current_event.dwProcessId);
- if (!saw_create && inf->attach_flag)
- {
-
- retval = fake_create_process ();
- if (retval)
- saw_create++;
- }
- break;
- }
-
- retval = current_event.dwThreadId;
- th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
- current_event.dwThreadId),
- current_event.u.CreateThread.hThread,
- current_event.u.CreateThread.lpThreadLocalBase);
- break;
- case EXIT_THREAD_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "EXIT_THREAD_DEBUG_EVENT"));
- if (current_event.dwThreadId != main_thread_id)
- {
- windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
- current_event.dwThreadId),
- current_event.u.ExitThread.dwExitCode);
- th = &dummy_thread_info;
- }
- break;
- case CREATE_PROCESS_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "CREATE_PROCESS_DEBUG_EVENT"));
- CloseHandle (current_event.u.CreateProcessInfo.hFile);
- if (++saw_create != 1)
- break;
- current_process_handle = current_event.u.CreateProcessInfo.hProcess;
- if (main_thread_id)
- windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
- main_thread_id),
- 0);
- main_thread_id = current_event.dwThreadId;
-
- th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
- current_event.dwThreadId),
- current_event.u.CreateProcessInfo.hThread,
- current_event.u.CreateProcessInfo.lpThreadLocalBase);
- retval = current_event.dwThreadId;
- break;
- case EXIT_PROCESS_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "EXIT_PROCESS_DEBUG_EVENT"));
- if (!windows_initialization_done)
- {
- target_terminal_ours ();
- target_mourn_inferior ();
- error (_("During startup program exited with code 0x%x."),
- (unsigned int) current_event.u.ExitProcess.dwExitCode);
- }
- else if (saw_create == 1)
- {
- ourstatus->kind = TARGET_WAITKIND_EXITED;
- ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
- retval = main_thread_id;
- }
- break;
- case LOAD_DLL_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "LOAD_DLL_DEBUG_EVENT"));
- CloseHandle (current_event.u.LoadDll.hFile);
- if (saw_create != 1 || ! windows_initialization_done)
- break;
- catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
- ourstatus->kind = TARGET_WAITKIND_LOADED;
- ourstatus->value.integer = 0;
- retval = main_thread_id;
- break;
- case UNLOAD_DLL_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "UNLOAD_DLL_DEBUG_EVENT"));
- if (saw_create != 1 || ! windows_initialization_done)
- break;
- catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
- ourstatus->kind = TARGET_WAITKIND_LOADED;
- ourstatus->value.integer = 0;
- retval = main_thread_id;
- break;
- case EXCEPTION_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "EXCEPTION_DEBUG_EVENT"));
- if (saw_create != 1)
- break;
- switch (handle_exception (ourstatus))
- {
- case 0:
- continue_status = DBG_EXCEPTION_NOT_HANDLED;
- break;
- case 1:
- retval = current_event.dwThreadId;
- break;
- case -1:
- last_sig = 1;
- continue_status = -1;
- break;
- }
- break;
- case OUTPUT_DEBUG_STRING_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "OUTPUT_DEBUG_STRING_EVENT"));
- if (saw_create != 1)
- break;
- retval = handle_output_debug_string (ourstatus);
- break;
- default:
- if (saw_create != 1)
- break;
- printf_unfiltered ("gdb: kernel event for pid=%u tid=0x%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId);
- printf_unfiltered (" unknown event code %u\n",
- (unsigned) current_event.dwDebugEventCode);
- break;
- }
- if (!retval || saw_create != 1)
- {
- if (continue_status == -1)
- windows_resume (ops, minus_one_ptid, 0, 1);
- else
- CHECK (windows_continue (continue_status, -1, 0));
- }
- else
- {
- inferior_ptid = ptid_build (current_event.dwProcessId, 0,
- retval);
- current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
- }
- out:
- return retval;
- }
- static ptid_t
- windows_wait (struct target_ops *ops,
- ptid_t ptid, struct target_waitstatus *ourstatus, int options)
- {
- int pid = -1;
- target_terminal_ours ();
-
- while (1)
- {
- int retval;
-
- FIXME
- SetConsoleCtrlHandler (&ctrl_c_handler, TRUE);
- retval = get_windows_debug_event (ops, pid, ourstatus);
- SetConsoleCtrlHandler (&ctrl_c_handler, FALSE);
- if (retval)
- return ptid_build (current_event.dwProcessId, 0, retval);
- else
- {
- int detach = 0;
- if (deprecated_ui_loop_hook != NULL)
- detach = deprecated_ui_loop_hook (0);
- if (detach)
- windows_kill_inferior (ops);
- }
- }
- }
- static void
- windows_add_all_dlls (void)
- {
- struct so_list *so;
- HMODULE dummy_hmodule;
- DWORD cb_needed;
- HMODULE *hmodules;
- int i;
- if (EnumProcessModules (current_process_handle, &dummy_hmodule,
- sizeof (HMODULE), &cb_needed) == 0)
- return;
- if (cb_needed < 1)
- return;
- hmodules = (HMODULE *) alloca (cb_needed);
- if (EnumProcessModules (current_process_handle, hmodules,
- cb_needed, &cb_needed) == 0)
- return;
- for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++)
- {
- MODULEINFO mi;
- #ifdef __USEWIDE
- wchar_t dll_name[__PMAX];
- char name[__PMAX];
- #else
- char dll_name[__PMAX];
- char *name;
- #endif
- if (GetModuleInformation (current_process_handle, hmodules[i],
- &mi, sizeof (mi)) == 0)
- continue;
- if (GetModuleFileNameEx (current_process_handle, hmodules[i],
- dll_name, sizeof (dll_name)) == 0)
- continue;
- #ifdef __USEWIDE
- wcstombs (name, dll_name, __PMAX);
- #else
- name = dll_name;
- #endif
- solib_end->next = windows_make_so (name, mi.lpBaseOfDll);
- solib_end = solib_end->next;
- }
- }
- static void
- do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
- {
- extern int stop_after_trap;
- int i;
- struct inferior *inf;
- struct thread_info *tp;
- last_sig = GDB_SIGNAL_0;
- event_count = 0;
- exception_count = 0;
- open_process_used = 0;
- debug_registers_changed = 0;
- debug_registers_used = 0;
- for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
- dr[i] = 0;
- #ifdef __CYGWIN__
- cygwin_load_start = cygwin_load_end = 0;
- #endif
- current_event.dwProcessId = pid;
- memset (¤t_event, 0, sizeof (current_event));
- if (!target_is_pushed (ops))
- push_target (ops);
- disable_breakpoints_in_shlibs ();
- windows_clear_solib ();
- clear_proceed_status (0);
- init_wait_for_inferior ();
- inf = current_inferior ();
- inferior_appeared (inf, pid);
- inf->attach_flag = attaching;
-
- inferior_ptid = pid_to_ptid (pid);
- target_terminal_init ();
- target_terminal_inferior ();
- windows_initialization_done = 0;
- inf->control.stop_soon = STOP_QUIETLY;
- while (1)
- {
- stop_after_trap = 1;
- wait_for_inferior ();
- tp = inferior_thread ();
- if (tp->suspend.stop_signal != GDB_SIGNAL_TRAP)
- resume (0, tp->suspend.stop_signal);
- else
- break;
- }
-
- windows_add_all_dlls ();
- windows_initialization_done = 1;
- inf->control.stop_soon = NO_STOP_QUIETLY;
- stop_after_trap = 0;
- return;
- }
- static int
- set_process_privilege (const char *privilege, BOOL enable)
- {
- HANDLE token_hdl = NULL;
- LUID restore_priv;
- TOKEN_PRIVILEGES new_priv, orig_priv;
- int ret = -1;
- DWORD size;
- if (!OpenProcessToken (GetCurrentProcess (),
- TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
- &token_hdl))
- goto out;
- if (!LookupPrivilegeValueA (NULL, privilege, &restore_priv))
- goto out;
- new_priv.PrivilegeCount = 1;
- new_priv.Privileges[0].Luid = restore_priv;
- new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
- if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
- sizeof orig_priv, &orig_priv, &size))
- goto out;
- #if 0
- #endif
- ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
- out:
- if (token_hdl)
- CloseHandle (token_hdl);
- return ret;
- }
- static void
- windows_attach (struct target_ops *ops, const char *args, int from_tty)
- {
- BOOL ok;
- DWORD pid;
- pid = parse_pid_to_attach (args);
- if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
- {
- printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
- printf_unfiltered ("This can cause attach to "
- "fail on Windows NT/2K/XP\n");
- }
- windows_init_thread_list ();
- ok = DebugActiveProcess (pid);
- saw_create = 0;
- #ifdef __CYGWIN__
- if (!ok)
- {
-
- pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
- if (pid > 0)
- ok = DebugActiveProcess (pid);
- }
- #endif
- if (!ok)
- error (_("Can't attach to process."));
- DebugSetProcessKillOnExit (FALSE);
- if (from_tty)
- {
- char *exec_file = (char *) get_exec_file (0);
- if (exec_file)
- printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
- target_pid_to_str (pid_to_ptid (pid)));
- else
- printf_unfiltered ("Attaching to %s\n",
- target_pid_to_str (pid_to_ptid (pid)));
- gdb_flush (gdb_stdout);
- }
- do_initial_windows_stuff (ops, pid, 1);
- target_terminal_ours ();
- }
- static void
- windows_detach (struct target_ops *ops, const char *args, int from_tty)
- {
- int detached = 1;
- ptid_t ptid = {-1};
- windows_resume (ops, ptid, 0, GDB_SIGNAL_0);
- if (!DebugActiveProcessStop (current_event.dwProcessId))
- {
- error (_("Can't detach process %u (error %u)"),
- (unsigned) current_event.dwProcessId, (unsigned) GetLastError ());
- detached = 0;
- }
- DebugSetProcessKillOnExit (FALSE);
- if (detached && from_tty)
- {
- char *exec_file = get_exec_file (0);
- if (exec_file == 0)
- exec_file = "";
- printf_unfiltered ("Detaching from program: %s, Pid %u\n", exec_file,
- (unsigned) current_event.dwProcessId);
- gdb_flush (gdb_stdout);
- }
- x86_cleanup_dregs ();
- inferior_ptid = null_ptid;
- detach_inferior (current_event.dwProcessId);
- inf_child_maybe_unpush_target (ops);
- }
- static int
- windows_get_exec_module_filename (char *exe_name_ret, size_t exe_name_max_len)
- {
- DWORD len;
- HMODULE dh_buf;
- DWORD cbNeeded;
- cbNeeded = 0;
- if (!EnumProcessModules (current_process_handle, &dh_buf,
- sizeof (HMODULE), &cbNeeded) || !cbNeeded)
- return 0;
-
- #ifdef __CYGWIN__
- {
-
- cygwin_buf_t *pathbuf = alloca (exe_name_max_len * sizeof (cygwin_buf_t));
- len = GetModuleFileNameEx (current_process_handle,
- dh_buf, pathbuf, exe_name_max_len);
- if (len == 0)
- error (_("Error getting executable filename: %u."),
- (unsigned) GetLastError ());
- if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, exe_name_ret,
- exe_name_max_len) < 0)
- error (_("Error converting executable filename to POSIX: %d."), errno);
- }
- #else
- len = GetModuleFileNameEx (current_process_handle,
- dh_buf, exe_name_ret, exe_name_max_len);
- if (len == 0)
- error (_("Error getting executable filename: %u."),
- (unsigned) GetLastError ());
- #endif
- return 1;
- }
- static char *
- windows_pid_to_exec_file (struct target_ops *self, int pid)
- {
- static char path[__PMAX];
- #ifdef __CYGWIN__
-
- int nchars;
- char procexe[sizeof ("/proc/4294967295/exe")];
- xsnprintf (procexe, sizeof (procexe), "/proc/%u/exe", pid);
- nchars = readlink (procexe, path, sizeof(path));
- if (nchars > 0 && nchars < sizeof (path))
- {
- path[nchars] = '\0';
- return path;
- }
- #endif
-
- if (!windows_get_exec_module_filename (path, sizeof (path)))
- path[0] = '\0';
- return path;
- }
- static void
- windows_files_info (struct target_ops *ignore)
- {
- struct inferior *inf = current_inferior ();
- printf_unfiltered ("\tUsing the running image of %s %s.\n",
- inf->attach_flag ? "attached" : "child",
- target_pid_to_str (inferior_ptid));
- }
- static void
- windows_set_console_info (STARTUPINFO *si, DWORD *flags)
- {
- HANDLE hconsole = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
- if (hconsole != INVALID_HANDLE_VALUE)
- {
- CONSOLE_SCREEN_BUFFER_INFO sbinfo;
- COORD font_size;
- CONSOLE_FONT_INFO cfi;
- GetCurrentConsoleFont (hconsole, FALSE, &cfi);
- font_size = GetConsoleFontSize (hconsole, cfi.nFont);
- GetConsoleScreenBufferInfo(hconsole, &sbinfo);
- si->dwXSize = sbinfo.srWindow.Right - sbinfo.srWindow.Left + 1;
- si->dwYSize = sbinfo.srWindow.Bottom - sbinfo.srWindow.Top + 1;
- if (font_size.X)
- si->dwXSize *= font_size.X;
- else
- si->dwXSize *= 8;
- if (font_size.Y)
- si->dwYSize *= font_size.Y;
- else
- si->dwYSize *= 12;
- si->dwXCountChars = sbinfo.dwSize.X;
- si->dwYCountChars = sbinfo.dwSize.Y;
- si->dwFlags |= STARTF_USESIZE | STARTF_USECOUNTCHARS;
- }
- *flags |= CREATE_NEW_CONSOLE;
- }
- #ifndef __CYGWIN__
- static int
- envvar_cmp (const void *a, const void *b)
- {
- const char **p = (const char **) a;
- const char **q = (const char **) b;
- return strcasecmp (*p, *q);
- }
- #endif
- #ifdef __CYGWIN__
- static void
- clear_win32_environment (char **env)
- {
- int i;
- size_t len;
- wchar_t *copy = NULL, *equalpos;
- for (i = 0; env[i] && *env[i]; i++)
- {
- len = mbstowcs (NULL, env[i], 0) + 1;
- copy = (wchar_t *) xrealloc (copy, len * sizeof (wchar_t));
- mbstowcs (copy, env[i], len);
- equalpos = wcschr (copy, L'=');
- if (equalpos)
- *equalpos = L'\0';
- SetEnvironmentVariableW (copy, NULL);
- }
- xfree (copy);
- }
- #endif
- static void
- windows_create_inferior (struct target_ops *ops, char *exec_file,
- char *allargs, char **in_env, int from_tty)
- {
- STARTUPINFO si;
- #ifdef __CYGWIN__
- cygwin_buf_t real_path[__PMAX];
- cygwin_buf_t shell[__PMAX];
- const char *sh;
- cygwin_buf_t *toexec;
- cygwin_buf_t *cygallargs;
- cygwin_buf_t *args;
- char **old_env = NULL;
- PWCHAR w32_env;
- size_t len;
- int tty;
- int ostdin, ostdout, ostderr;
- #else
- char real_path[__PMAX];
- char shell[__PMAX];
- char *toexec;
- char *args;
- size_t args_len;
- HANDLE tty;
- char *w32env;
- char *temp;
- size_t envlen;
- int i;
- size_t envsize;
- char **env;
- #endif
- PROCESS_INFORMATION pi;
- BOOL ret;
- DWORD flags = 0;
- const char *inferior_io_terminal = get_inferior_io_terminal ();
- if (!exec_file)
- error (_("No executable specified, use `target exec'."));
- memset (&si, 0, sizeof (si));
- si.cb = sizeof (si);
- if (new_group)
- flags |= CREATE_NEW_PROCESS_GROUP;
- if (new_console)
- windows_set_console_info (&si, &flags);
- #ifdef __CYGWIN__
- if (!useshell)
- {
- flags |= DEBUG_ONLY_THIS_PROCESS;
- if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, exec_file, real_path,
- __PMAX * sizeof (cygwin_buf_t)) < 0)
- error (_("Error starting executable: %d"), errno);
- toexec = real_path;
- #ifdef __USEWIDE
- len = mbstowcs (NULL, allargs, 0) + 1;
- if (len == (size_t) -1)
- error (_("Error starting executable: %d"), errno);
- cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
- mbstowcs (cygallargs, allargs, len);
- #else
- cygallargs = allargs;
- #endif
- }
- else
- {
- sh = getenv ("SHELL");
- if (!sh)
- sh = "/bin/sh";
- if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, __PMAX) < 0)
- error (_("Error starting executable via shell: %d"), errno);
- #ifdef __USEWIDE
- len = sizeof (L" -c 'exec '") + mbstowcs (NULL, exec_file, 0)
- + mbstowcs (NULL, allargs, 0) + 2;
- cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
- swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs);
- #else
- len = (sizeof (" -c 'exec '") + strlen (exec_file)
- + strlen (allargs) + 2);
- cygallargs = (char *) alloca (len);
- xsnprintf (cygallargs, len, " -c 'exec %s %s'", exec_file, allargs);
- #endif
- toexec = shell;
- flags |= DEBUG_PROCESS;
- }
- #ifdef __USEWIDE
- args = (cygwin_buf_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
- * sizeof (wchar_t));
- wcscpy (args, toexec);
- wcscat (args, L" ");
- wcscat (args, cygallargs);
- #else
- args = (cygwin_buf_t *) alloca (strlen (toexec) + strlen (cygallargs) + 2);
- strcpy (args, toexec);
- strcat (args, " ");
- strcat (args, cygallargs);
- #endif
- #ifdef CW_CVT_ENV_TO_WINENV
-
- w32_env = (PWCHAR) cygwin_internal (CW_CVT_ENV_TO_WINENV, in_env);
- if (w32_env != (PWCHAR) -1)
- flags |= CREATE_UNICODE_ENVIRONMENT;
- else
-
- #endif
- {
-
- clear_win32_environment (environ);
-
- old_env = environ;
- environ = in_env;
- cygwin_internal (CW_SYNC_WINENV);
- w32_env = NULL;
- }
- if (!inferior_io_terminal)
- tty = ostdin = ostdout = ostderr = -1;
- else
- {
- tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
- if (tty < 0)
- {
- print_sys_errmsg (inferior_io_terminal, errno);
- ostdin = ostdout = ostderr = -1;
- }
- else
- {
- ostdin = dup (0);
- ostdout = dup (1);
- ostderr = dup (2);
- dup2 (tty, 0);
- dup2 (tty, 1);
- dup2 (tty, 2);
- }
- }
- windows_init_thread_list ();
- ret = CreateProcess (0,
- args,
- NULL,
- NULL,
- TRUE,
- flags,
- w32_env,
- NULL,
- &si,
- &pi);
- if (w32_env)
-
- free (w32_env);
- else
- {
-
- clear_win32_environment (in_env);
-
- environ = old_env;
- cygwin_internal (CW_SYNC_WINENV);
- }
- if (tty >= 0)
- {
- close (tty);
- dup2 (ostdin, 0);
- dup2 (ostdout, 1);
- dup2 (ostderr, 2);
- close (ostdin);
- close (ostdout);
- close (ostderr);
- }
- #else
- toexec = exec_file;
-
- args_len = strlen (toexec) + 2 + strlen (allargs) + 2;
- args = alloca (args_len);
- xsnprintf (args, args_len, "\"%s\" %s", toexec, allargs);
- flags |= DEBUG_ONLY_THIS_PROCESS;
- if (!inferior_io_terminal)
- tty = INVALID_HANDLE_VALUE;
- else
- {
- SECURITY_ATTRIBUTES sa;
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = 0;
- sa.bInheritHandle = TRUE;
- tty = CreateFileA (inferior_io_terminal, GENERIC_READ | GENERIC_WRITE,
- 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
- if (tty == INVALID_HANDLE_VALUE)
- warning (_("Warning: Failed to open TTY %s, error %#x."),
- inferior_io_terminal, (unsigned) GetLastError ());
- else
- {
- si.hStdInput = tty;
- si.hStdOutput = tty;
- si.hStdError = tty;
- si.dwFlags |= STARTF_USESTDHANDLES;
- }
- }
-
-
- for (envlen = 0, i = 0; in_env[i] && *in_env[i]; i++)
- envlen += strlen (in_env[i]) + 1;
- envsize = sizeof (in_env[0]) * (i + 1);
- env = (char **) alloca (envsize);
- memcpy (env, in_env, envsize);
-
- qsort (env, i, sizeof (char *), envvar_cmp);
- w32env = alloca (envlen + 1);
-
- for (temp = w32env, i = 0; env[i] && *env[i]; i++)
- {
- strcpy (temp, env[i]);
- temp += strlen (temp) + 1;
- }
-
- *temp = 0;
- windows_init_thread_list ();
- ret = CreateProcessA (0,
- args,
- NULL,
- NULL,
- TRUE,
- flags,
- w32env,
- NULL,
- &si,
- &pi);
- if (tty != INVALID_HANDLE_VALUE)
- CloseHandle (tty);
- #endif
- if (!ret)
- error (_("Error creating process %s, (error %u)."),
- exec_file, (unsigned) GetLastError ());
- CloseHandle (pi.hThread);
- CloseHandle (pi.hProcess);
- if (useshell && shell[0] != '\0')
- saw_create = -1;
- else
- saw_create = 0;
- do_initial_windows_stuff (ops, pi.dwProcessId, 0);
-
- }
- static void
- windows_mourn_inferior (struct target_ops *ops)
- {
- (void) windows_continue (DBG_CONTINUE, -1, 0);
- x86_cleanup_dregs();
- if (open_process_used)
- {
- CHECK (CloseHandle (current_process_handle));
- open_process_used = 0;
- }
- inf_child_mourn_inferior (ops);
- }
- static void
- windows_stop (struct target_ops *self, ptid_t ptid)
- {
- DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
- CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
- registers_changed ();
- }
- static enum target_xfer_status
- windows_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
- ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len)
- {
- SIZE_T done = 0;
- BOOL success;
- DWORD lasterror = 0;
- if (writebuf != NULL)
- {
- DEBUG_MEM (("gdb: write target memory, %s bytes at %s\n",
- pulongest (len), core_addr_to_string (memaddr)));
- success = WriteProcessMemory (current_process_handle,
- (LPVOID) (uintptr_t) memaddr, writebuf,
- len, &done);
- if (!success)
- lasterror = GetLastError ();
- FlushInstructionCache (current_process_handle,
- (LPCVOID) (uintptr_t) memaddr, len);
- }
- else
- {
- DEBUG_MEM (("gdb: read target memory, %s bytes at %s\n",
- pulongest (len), core_addr_to_string (memaddr)));
- success = ReadProcessMemory (current_process_handle,
- (LPCVOID) (uintptr_t) memaddr, readbuf,
- len, &done);
- if (!success)
- lasterror = GetLastError ();
- }
- *xfered_len = (ULONGEST) done;
- if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0)
- return TARGET_XFER_OK;
- else
- return success ? TARGET_XFER_OK : TARGET_XFER_E_IO;
- }
- static void
- windows_kill_inferior (struct target_ops *ops)
- {
- CHECK (TerminateProcess (current_process_handle, 0));
- for (;;)
- {
- if (!windows_continue (DBG_CONTINUE, -1, 1))
- break;
- if (!WaitForDebugEvent (¤t_event, INFINITE))
- break;
- if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
- break;
- }
- target_mourn_inferior ();
- }
- static void
- windows_close (struct target_ops *self)
- {
- DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n",
- ptid_get_pid (inferior_ptid)));
- }
- static char *
- windows_pid_to_str (struct target_ops *ops, ptid_t ptid)
- {
- static char buf[80];
- if (ptid_get_tid (ptid) != 0)
- {
- snprintf (buf, sizeof (buf), "Thread %d.0x%lx",
- ptid_get_pid (ptid), ptid_get_tid (ptid));
- return buf;
- }
- return normal_pid_to_str (ptid);
- }
- static enum target_xfer_status
- windows_xfer_shared_libraries (struct target_ops *ops,
- enum target_object object, const char *annex,
- gdb_byte *readbuf, const gdb_byte *writebuf,
- ULONGEST offset, ULONGEST len,
- ULONGEST *xfered_len)
- {
- struct obstack obstack;
- const char *buf;
- LONGEST len_avail;
- struct so_list *so;
- if (writebuf)
- return TARGET_XFER_E_IO;
- obstack_init (&obstack);
- obstack_grow_str (&obstack, "<library-list>\n");
- for (so = solib_start.next; so; so = so->next)
- windows_xfer_shared_library (so->so_name, (CORE_ADDR)
- (uintptr_t) so->lm_info->load_addr,
- target_gdbarch (), &obstack);
- obstack_grow_str0 (&obstack, "</library-list>\n");
- buf = obstack_finish (&obstack);
- len_avail = strlen (buf);
- if (offset >= len_avail)
- len= 0;
- else
- {
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, buf + offset, len);
- }
- obstack_free (&obstack, NULL);
- *xfered_len = (ULONGEST) len;
- return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
- }
- static enum target_xfer_status
- windows_xfer_partial (struct target_ops *ops, enum target_object object,
- const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
- ULONGEST *xfered_len)
- {
- switch (object)
- {
- case TARGET_OBJECT_MEMORY:
- return windows_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
- case TARGET_OBJECT_LIBRARIES:
- return windows_xfer_shared_libraries (ops, object, annex, readbuf,
- writebuf, offset, len, xfered_len);
- default:
- return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
- readbuf, writebuf, offset, len,
- xfered_len);
- }
- }
- static int
- windows_get_tib_address (struct target_ops *self,
- ptid_t ptid, CORE_ADDR *addr)
- {
- thread_info *th;
- th = thread_rec (ptid_get_tid (ptid), 0);
- if (th == NULL)
- return 0;
- if (addr != NULL)
- *addr = th->thread_local_base;
- return 1;
- }
- static ptid_t
- windows_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
- {
- return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
- }
- static struct target_ops *
- windows_target (void)
- {
- struct target_ops *t = inf_child_target ();
- t->to_close = windows_close;
- t->to_attach = windows_attach;
- t->to_attach_no_wait = 1;
- t->to_detach = windows_detach;
- t->to_resume = windows_resume;
- t->to_wait = windows_wait;
- t->to_fetch_registers = windows_fetch_inferior_registers;
- t->to_store_registers = windows_store_inferior_registers;
- t->to_xfer_partial = windows_xfer_partial;
- t->to_files_info = windows_files_info;
- t->to_kill = windows_kill_inferior;
- t->to_create_inferior = windows_create_inferior;
- t->to_mourn_inferior = windows_mourn_inferior;
- t->to_thread_alive = windows_thread_alive;
- t->to_pid_to_str = windows_pid_to_str;
- t->to_stop = windows_stop;
- t->to_pid_to_exec_file = windows_pid_to_exec_file;
- t->to_get_ada_task_ptid = windows_get_ada_task_ptid;
- t->to_get_tib_address = windows_get_tib_address;
- return t;
- }
- static void
- set_windows_aliases (char *argv0)
- {
- add_info_alias ("dll", "sharedlibrary", 1);
- }
- extern initialize_file_ftype _initialize_windows_nat;
- void
- _initialize_windows_nat (void)
- {
- struct target_ops *t;
- t = windows_target ();
- x86_use_watchpoints (t);
- x86_dr_low.set_control = cygwin_set_dr7;
- x86_dr_low.set_addr = cygwin_set_dr;
- x86_dr_low.get_addr = cygwin_get_dr;
- x86_dr_low.get_status = cygwin_get_dr6;
- x86_dr_low.get_control = cygwin_get_dr7;
-
- add_target (t);
- #ifdef __CYGWIN__
- cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
- #endif
- #ifdef __CYGWIN__
- add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
- Set use of shell to start subprocess."), _("\
- Show use of shell to start subprocess."), NULL,
- NULL,
- NULL, FIXME
- &setlist, &showlist);
- add_setshow_boolean_cmd ("cygwin-exceptions", class_support,
- &cygwin_exceptions, _("\
- Break when an exception is detected in the Cygwin DLL itself."), _("\
- Show whether gdb breaks on exceptions in the Cygwin DLL itself."), NULL,
- NULL,
- NULL, FIXME
- &setlist, &showlist);
- #endif
- add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\
- Set creation of new console when creating child process."), _("\
- Show creation of new console when creating child process."), NULL,
- NULL,
- NULL, FIXME
- &setlist, &showlist);
- add_setshow_boolean_cmd ("new-group", class_support, &new_group, _("\
- Set creation of new group when creating child process."), _("\
- Show creation of new group when creating child process."), NULL,
- NULL,
- NULL, FIXME
- &setlist, &showlist);
- add_setshow_boolean_cmd ("debugexec", class_support, &debug_exec, _("\
- Set whether to display execution in child process."), _("\
- Show whether to display execution in child process."), NULL,
- NULL,
- NULL, FIXME
- &setlist, &showlist);
- add_setshow_boolean_cmd ("debugevents", class_support, &debug_events, _("\
- Set whether to display kernel events in child process."), _("\
- Show whether to display kernel events in child process."), NULL,
- NULL,
- NULL, FIXME
- &setlist, &showlist);
- add_setshow_boolean_cmd ("debugmemory", class_support, &debug_memory, _("\
- Set whether to display memory accesses in child process."), _("\
- Show whether to display memory accesses in child process."), NULL,
- NULL,
- NULL, FIXME
- &setlist, &showlist);
- add_setshow_boolean_cmd ("debugexceptions", class_support,
- &debug_exceptions, _("\
- Set whether to display kernel exceptions in child process."), _("\
- Show whether to display kernel exceptions in child process."), NULL,
- NULL,
- NULL, FIXME
- &setlist, &showlist);
- init_w32_command_list ();
- add_cmd ("selector", class_info, display_selectors,
- _("Display selectors infos."),
- &info_w32_cmdlist);
- deprecated_init_ui_hook = set_windows_aliases;
- }
- static void
- cygwin_set_dr (int i, CORE_ADDR addr)
- {
- if (i < 0 || i > 3)
- internal_error (__FILE__, __LINE__,
- _("Invalid register %d in cygwin_set_dr.\n"), i);
- dr[i] = addr;
- debug_registers_changed = 1;
- debug_registers_used = 1;
- }
- static void
- cygwin_set_dr7 (unsigned long val)
- {
- dr[7] = (CORE_ADDR) val;
- debug_registers_changed = 1;
- debug_registers_used = 1;
- }
- static CORE_ADDR
- cygwin_get_dr (int i)
- {
- return dr[i];
- }
- static unsigned long
- cygwin_get_dr6 (void)
- {
- return (unsigned long) dr[6];
- }
- static unsigned long
- cygwin_get_dr7 (void)
- {
- return (unsigned long) dr[7];
- }
- static int
- windows_thread_alive (struct target_ops *ops, ptid_t ptid)
- {
- int tid;
- gdb_assert (ptid_get_tid (ptid) != 0);
- tid = ptid_get_tid (ptid);
- return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0
- ? FALSE : TRUE;
- }
- extern initialize_file_ftype _initialize_check_for_gdb_ini;
- void
- _initialize_check_for_gdb_ini (void)
- {
- char *homedir;
- if (inhibit_gdbinit)
- return;
- homedir = getenv ("HOME");
- if (homedir)
- {
- char *p;
- char *oldini = (char *) alloca (strlen (homedir) +
- sizeof ("/gdb.ini"));
- strcpy (oldini, homedir);
- p = strchr (oldini, '\0');
- if (p > oldini && !IS_DIR_SEPARATOR (p[-1]))
- *p++ = '/';
- strcpy (p, "gdb.ini");
- if (access (oldini, 0) == 0)
- {
- int len = strlen (oldini);
- char *newini = alloca (len + 1);
- xsnprintf (newini, len + 1, "%.*s.gdbinit",
- (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
- warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini);
- }
- }
- }
- static BOOL WINAPI
- bad_DebugActiveProcessStop (DWORD w)
- {
- return FALSE;
- }
- static BOOL WINAPI
- bad_DebugBreakProcess (HANDLE w)
- {
- return FALSE;
- }
- static BOOL WINAPI
- bad_DebugSetProcessKillOnExit (BOOL w)
- {
- return FALSE;
- }
- static BOOL WINAPI
- bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
- {
- return FALSE;
- }
- #ifdef __USEWIDE
- static DWORD WINAPI
- bad_GetModuleFileNameExW (HANDLE w, HMODULE x, LPWSTR y, DWORD z)
- {
- return 0;
- }
- #else
- static DWORD WINAPI
- bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
- {
- return 0;
- }
- #endif
- static BOOL WINAPI
- bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
- {
- return FALSE;
- }
- static BOOL WINAPI
- bad_OpenProcessToken (HANDLE w, DWORD x, PHANDLE y)
- {
- return FALSE;
- }
- static BOOL WINAPI
- bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
- {
- f->nFont = 0;
- return 1;
- }
- static COORD WINAPI
- bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
- {
- COORD size;
- size.X = 8;
- size.Y = 12;
- return size;
- }
- extern initialize_file_ftype _initialize_loadable;
- void
- _initialize_loadable (void)
- {
- HMODULE hm = NULL;
- hm = LoadLibrary ("kernel32.dll");
- if (hm)
- {
- DebugActiveProcessStop = (void *)
- GetProcAddress (hm, "DebugActiveProcessStop");
- DebugBreakProcess = (void *)
- GetProcAddress (hm, "DebugBreakProcess");
- DebugSetProcessKillOnExit = (void *)
- GetProcAddress (hm, "DebugSetProcessKillOnExit");
- GetConsoleFontSize = (void *)
- GetProcAddress (hm, "GetConsoleFontSize");
- GetCurrentConsoleFont = (void *)
- GetProcAddress (hm, "GetCurrentConsoleFont");
- }
-
- if (!DebugBreakProcess)
- DebugBreakProcess = bad_DebugBreakProcess;
- if (!DebugActiveProcessStop || !DebugSetProcessKillOnExit)
- {
- DebugActiveProcessStop = bad_DebugActiveProcessStop;
- DebugSetProcessKillOnExit = bad_DebugSetProcessKillOnExit;
- }
- if (!GetConsoleFontSize)
- GetConsoleFontSize = bad_GetConsoleFontSize;
- if (!GetCurrentConsoleFont)
- GetCurrentConsoleFont = bad_GetCurrentConsoleFont;
-
- hm = LoadLibrary ("psapi.dll");
- if (hm)
- {
- EnumProcessModules = (void *)
- GetProcAddress (hm, "EnumProcessModules");
- GetModuleInformation = (void *)
- GetProcAddress (hm, "GetModuleInformation");
- GetModuleFileNameEx = (void *)
- GetProcAddress (hm, GetModuleFileNameEx_name);
- }
- if (!EnumProcessModules || !GetModuleInformation || !GetModuleFileNameEx)
- {
-
- EnumProcessModules = bad_EnumProcessModules;
- GetModuleInformation = bad_GetModuleInformation;
- GetModuleFileNameEx = bad_GetModuleFileNameEx;
-
- warning(_("\
- cannot automatically find executable file or library to read symbols.\n\
- Use \"file\" or \"dll\" command to load executable/libraries directly."));
- }
- hm = LoadLibrary ("advapi32.dll");
- if (hm)
- {
- OpenProcessToken = (void *) GetProcAddress (hm, "OpenProcessToken");
- LookupPrivilegeValueA = (void *)
- GetProcAddress (hm, "LookupPrivilegeValueA");
- AdjustTokenPrivileges = (void *)
- GetProcAddress (hm, "AdjustTokenPrivileges");
-
- if (!OpenProcessToken || !LookupPrivilegeValueA
- || !AdjustTokenPrivileges)
- OpenProcessToken = bad_OpenProcessToken;
- }
- }