X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fwindows-nat.c;h=5eb8f6710a9069477894a6083cdd276a8a5f49b9;hb=0cb79d6955c226a3639ae92f771509754ed3276d;hp=86f92423bbdb4110e5cddcb89b3295bddb1215e1;hpb=581e13c1888512fde1bd3ff9e46f1a3ec4c337d7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 86f92423bb..5eb8f6710a 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -1,7 +1,6 @@ /* Target-vector operations for controlling windows child processes, for GDB. - Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1995-2012 Free Software Foundation, Inc. Contributed by Cygnus Solutions, A Red Hat Company. @@ -40,14 +39,17 @@ #include #include #ifdef __CYGWIN__ +#include #include #include #endif #include #include "buildsym.h" +#include "filenames.h" #include "symfile.h" #include "objfiles.h" +#include "gdb_bfd.h" #include "gdb_obstack.h" #include "gdb_string.h" #include "gdbthread.h" @@ -111,7 +113,6 @@ static struct target_ops windows_ops; /* The starting and ending address of the cygwin1.dll text segment. */ static CORE_ADDR cygwin_load_start; static CORE_ADDR cygwin_load_end; -# if CYGWIN_VERSION_DLL_MAKE_COMBINED(CYGWIN_VERSION_API_MAJOR,CYGWIN_VERSION_API_MINOR) >= 181 # define __USEWIDE typedef wchar_t cygwin_buf_t; static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, @@ -120,21 +121,6 @@ static struct target_ops windows_ops; # define CreateProcess CreateProcessW # define GetModuleFileNameEx_name "GetModuleFileNameExW" # define bad_GetModuleFileNameEx bad_GetModuleFileNameExW -# else -# define CCP_POSIX_TO_WIN_W 1 -# define CCP_WIN_W_TO_POSIX 3 -# define cygwin_conv_path(op, from, to, size) \ - (op == CCP_WIN_W_TO_POSIX) ? \ - cygwin_conv_to_full_posix_path (from, to) : \ - cygwin_conv_to_win32_path (from, to) - typedef char cygwin_buf_t; - static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD); -# define STARTUPINFO STARTUPINFOA -# define CreateProcess CreateProcessA -# define GetModuleFileNameEx_name "GetModuleFileNameExA" -# define bad_GetModuleFileNameEx bad_GetModuleFileNameExA -# define CW_SET_DOS_FILE_WARNING -1 /* no-op this for older Cygwin */ -# endif #endif static int have_saved_context; /* True if we've saved context from a @@ -187,9 +173,11 @@ 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 target_signal last_sig = TARGET_SIGNAL_0; +static enum gdb_signal last_sig = GDB_SIGNAL_0; /* Set if a signal was received from the debugged process. */ /* Thread information structure used to track information that is @@ -256,24 +244,28 @@ static int useshell = 0; /* use shell for subprocesses */ static const int *mappings; +/* The function to use in order to determine whether a register is + a segment register or not. */ +static segment_register_p_ftype *segment_register_p; + /* This vector maps the target's idea of an exception (extracted from the DEBUG_EVENT structure) to GDB's idea. */ struct xlate_exception { int them; - enum target_signal us; + enum gdb_signal us; }; static const struct xlate_exception xlate[] = { - {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV}, - {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV}, - {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP}, - {DBG_CONTROL_C, TARGET_SIGNAL_INT}, - {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP}, - {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE}, + {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}}; /* Set the MAPPINGS static global to OFFSETS. @@ -285,6 +277,14 @@ windows_set_context_register_offsets (const int *offsets) mappings = offsets; } +/* See windows-nat.h. */ + +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) { @@ -469,6 +469,14 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r) l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); regcache_raw_supply (regcache, r, (char *) &l); } + else if (segment_register_p (r)) + { + /* GDB treats segment registers as 32bit registers, but they are + in fact only 16 bits long. Make sure we do not read extra + bits from our source buffer. */ + l = *((long *) context_offset) & 0xffff; + regcache_raw_supply (regcache, r, (char *) &l); + } else if (r >= 0) regcache_raw_supply (regcache, r, context_offset); else @@ -516,7 +524,7 @@ windows_store_inferior_registers (struct target_ops *ops, do_windows_store_inferior_registers (regcache, r); } -/* Get the name of a given module at at given base address. If base_address +/* Get the name of a given module at given base address. If base_address is zero return the first loaded module (which is always the name of the executable). */ static int @@ -745,7 +753,7 @@ windows_make_so (const char *name, LPVOID load_addr) asection *text = NULL; CORE_ADDR text_vma; - abfd = bfd_openr (so->so_name, "pei-i386"); + abfd = gdb_bfd_open (so->so_name, "pei-i386", -1); if (!abfd) return so; @@ -755,18 +763,18 @@ windows_make_so (const char *name, LPVOID load_addr) if (!text) { - bfd_close (abfd); + gdb_bfd_unref (abfd); return so; } - /* The symbols in a dll are offset by 0x1000, which is the the + /* The symbols in a dll are offset by 0x1000, which is the offset from 0 of the first byte in an image - because of the file header and the section alignment. */ cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *) load_addr + 0x1000); cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text); - bfd_close (abfd); + gdb_bfd_unref (abfd); } #endif @@ -904,7 +912,7 @@ windows_clear_solib (void) } /* Load DLL symbol info. */ -void +static void dll_symbol_command (char *args, int from_tty) { int n; @@ -959,7 +967,7 @@ handle_output_debug_string (struct target_waitstatus *ourstatus) to treat this like a real signal. */ char *p; int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0); - int gotasig = target_signal_from_host (sig); + int gotasig = gdb_signal_from_host (sig); ourstatus->value.sig = gotasig; if (gotasig) { @@ -1120,7 +1128,7 @@ handle_exception (struct target_waitstatus *ourstatus) { case EXCEPTION_ACCESS_VIOLATION: DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION"); - ourstatus->value.sig = TARGET_SIGNAL_SEGV; + ourstatus->value.sig = GDB_SIGNAL_SEGV; #ifdef __CYGWIN__ { /* See if the access violation happened within the cygwin DLL @@ -1131,7 +1139,7 @@ handle_exception (struct target_waitstatus *ourstatus) cygwin later in the process and will be sent as a cygwin-specific-signal. So, ignore SEGVs if they show up within the text segment of the DLL itself. */ - char *fn; + const char *fn; CORE_ADDR addr = (CORE_ADDR) (uintptr_t) current_event.u.Exception.ExceptionRecord.ExceptionAddress; @@ -1146,75 +1154,75 @@ handle_exception (struct target_waitstatus *ourstatus) break; case STATUS_STACK_OVERFLOW: DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW"); - ourstatus->value.sig = TARGET_SIGNAL_SEGV; + ourstatus->value.sig = GDB_SIGNAL_SEGV; break; case STATUS_FLOAT_DENORMAL_OPERAND: DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case STATUS_FLOAT_INEXACT_RESULT: DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case STATUS_FLOAT_INVALID_OPERATION: DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case STATUS_FLOAT_OVERFLOW: DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case STATUS_FLOAT_STACK_CHECK: DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case STATUS_FLOAT_UNDERFLOW: DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case STATUS_FLOAT_DIVIDE_BY_ZERO: DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case STATUS_INTEGER_DIVIDE_BY_ZERO: DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case STATUS_INTEGER_OVERFLOW: DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW"); - ourstatus->value.sig = TARGET_SIGNAL_FPE; + ourstatus->value.sig = GDB_SIGNAL_FPE; break; case EXCEPTION_BREAKPOINT: DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT"); - ourstatus->value.sig = TARGET_SIGNAL_TRAP; + ourstatus->value.sig = GDB_SIGNAL_TRAP; break; case DBG_CONTROL_C: DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C"); - ourstatus->value.sig = TARGET_SIGNAL_INT; + ourstatus->value.sig = GDB_SIGNAL_INT; break; case DBG_CONTROL_BREAK: DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK"); - ourstatus->value.sig = TARGET_SIGNAL_INT; + ourstatus->value.sig = GDB_SIGNAL_INT; break; case EXCEPTION_SINGLE_STEP: DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP"); - ourstatus->value.sig = TARGET_SIGNAL_TRAP; + ourstatus->value.sig = GDB_SIGNAL_TRAP; break; case EXCEPTION_ILLEGAL_INSTRUCTION: DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION"); - ourstatus->value.sig = TARGET_SIGNAL_ILL; + ourstatus->value.sig = GDB_SIGNAL_ILL; break; case EXCEPTION_PRIV_INSTRUCTION: DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION"); - ourstatus->value.sig = TARGET_SIGNAL_ILL; + ourstatus->value.sig = GDB_SIGNAL_ILL; break; case EXCEPTION_NONCONTINUABLE_EXCEPTION: DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION"); - ourstatus->value.sig = TARGET_SIGNAL_ILL; + ourstatus->value.sig = GDB_SIGNAL_ILL; break; default: /* Treat unhandled first chance exceptions specially. */ @@ -1224,7 +1232,7 @@ handle_exception (struct target_waitstatus *ourstatus) current_event.u.Exception.ExceptionRecord.ExceptionCode, host_address_to_string ( current_event.u.Exception.ExceptionRecord.ExceptionAddress)); - ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; + ourstatus->value.sig = GDB_SIGNAL_UNKNOWN; break; } exception_count++; @@ -1289,7 +1297,7 @@ fake_create_process (void) open_process_used = 1; else { - error (_("OpenProcess call failed, GetLastError = %lud\n"), + error (_("OpenProcess call failed, GetLastError = %lud"), GetLastError ()); /* We can not debug anything in that case. */ } @@ -1304,7 +1312,7 @@ fake_create_process (void) static void windows_resume (struct target_ops *ops, - ptid_t ptid, int step, enum target_signal sig) + ptid_t ptid, int step, enum gdb_signal sig) { thread_info *th; DWORD continue_status = DBG_CONTINUE; @@ -1317,7 +1325,7 @@ windows_resume (struct target_ops *ops, if (resume_all) ptid = inferior_ptid; - if (sig != TARGET_SIGNAL_0) + if (sig != GDB_SIGNAL_0) { if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT) { @@ -1351,7 +1359,7 @@ windows_resume (struct target_ops *ops, last_sig)); } - last_sig = TARGET_SIGNAL_0; + 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)); @@ -1399,7 +1407,7 @@ windows_resume (struct target_ops *ops, handler is in charge of interrupting the inferior using DebugBreakProcess. Note that this function is not available prior to Windows XP. In this case we emit a warning. */ -BOOL WINAPI +static BOOL WINAPI ctrl_c_handler (DWORD event_type) { const int attach_flag = current_inferior ()->attach_flag; @@ -1433,7 +1441,7 @@ get_windows_debug_event (struct target_ops *ops, static thread_info dummy_thread_info; int retval = 0; - last_sig = TARGET_SIGNAL_0; + last_sig = GDB_SIGNAL_0; if (!(debug_event = WaitForDebugEvent (¤t_event, 1000))) goto out; @@ -1693,7 +1701,7 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) struct inferior *inf; struct thread_info *tp; - last_sig = TARGET_SIGNAL_0; + last_sig = GDB_SIGNAL_0; event_count = 0; exception_count = 0; open_process_used = 0; @@ -1730,9 +1738,9 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) while (1) { stop_after_trap = 1; - wait_for_inferior (0); + wait_for_inferior (); tp = inferior_thread (); - if (tp->suspend.stop_signal != TARGET_SIGNAL_TRAP) + if (tp->suspend.stop_signal != GDB_SIGNAL_TRAP) resume (0, tp->suspend.stop_signal); else break; @@ -1853,7 +1861,7 @@ windows_detach (struct target_ops *ops, char *args, int from_tty) int detached = 1; ptid_t ptid = {-1}; - windows_resume (ops, ptid, 0, TARGET_SIGNAL_0); + windows_resume (ops, ptid, 0, GDB_SIGNAL_0); if (!DebugActiveProcessStop (current_event.dwProcessId)) { @@ -1967,6 +1975,40 @@ windows_set_console_info (STARTUPINFO *si, DWORD *flags) *flags |= CREATE_NEW_CONSOLE; } +#ifndef __CYGWIN__ +/* Function called by qsort to sort environment strings. */ + +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 + /* Start an inferior windows child process and sets inferior_ptid to its pid. EXEC_FILE is the file to run. ALLARGS is a string containing the arguments to the program. @@ -1984,6 +2026,8 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, 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; @@ -1992,7 +2036,14 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, char shell[__PMAX]; /* Path to shell */ 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; @@ -2064,8 +2115,23 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, strcat (args, cygallargs); #endif - /* Prepare the environment vars for CreateProcess. */ - cygwin_internal (CW_SYNC_WINENV); +#ifdef CW_CVT_ENV_TO_WINENV + /* First try to create a direct Win32 copy of the POSIX environment. */ + w32_env = (PWCHAR) cygwin_internal (CW_CVT_ENV_TO_WINENV, in_env); + if (w32_env != (PWCHAR) -1) + flags |= CREATE_UNICODE_ENVIRONMENT; + else + /* If that fails, fall back to old method tweaking GDB's environment. */ +#endif + { + /* Reset all Win32 environment variables to avoid leftover on next run. */ + clear_win32_environment (environ); + /* Prepare the environment vars for CreateProcess. */ + old_env = environ; + environ = in_env; + cygwin_internal (CW_SYNC_WINENV); + w32_env = NULL; + } if (!inferior_io_terminal) tty = ostdin = ostdout = ostderr = -1; @@ -2095,10 +2161,22 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, NULL, /* thread */ TRUE, /* inherit handles */ flags, /* start flags */ - NULL, /* environment */ + w32_env, /* environment */ NULL, /* current directory */ &si, &pi); + if (w32_env) + /* Just free the Win32 environment, if it could be created. */ + free (w32_env); + else + { + /* Reset all environment variables to avoid leftover on next run. */ + clear_win32_environment (in_env); + /* Restore normal GDB environment variables. */ + environ = old_env; + cygwin_internal (CW_SYNC_WINENV); + } + if (tty >= 0) { close (tty); @@ -2111,10 +2189,13 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, } #else toexec = exec_file; - args = alloca (strlen (toexec) + strlen (allargs) + 2); - strcpy (args, toexec); - strcat (args, " "); - strcat (args, allargs); + /* Build the command line, a space-separated list of tokens where + the first token is the name of the module to be executed. + To avoid ambiguities introduced by spaces in the module name, + we quote it. */ + args_len = strlen (toexec) + 2 /* quotes */ + strlen (allargs) + 2; + args = alloca (args_len); + xsnprintf (args, args_len, "\"%s\" %s", toexec, allargs); flags |= DEBUG_ONLY_THIS_PROCESS; @@ -2140,6 +2221,31 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, } } + /* CreateProcess takes the environment list as a null terminated set of + strings (i.e. two nulls terminate the list). */ + + /* Get total size for env strings. */ + 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); + /* Windows programs expect the environment block to be sorted. */ + qsort (env, i, sizeof (char *), envvar_cmp); + + w32env = alloca (envlen + 1); + + /* Copy env strings into new buffer. */ + for (temp = w32env, i = 0; env[i] && *env[i]; i++) + { + strcpy (temp, env[i]); + temp += strlen (temp) + 1; + } + + /* Final nil string to terminate new env. */ + *temp = 0; + windows_init_thread_list (); ret = CreateProcessA (0, args, /* command line */ @@ -2147,7 +2253,7 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, NULL, /* thread */ TRUE, /* inherit handles */ flags, /* start flags */ - NULL, /* environment */ + w32env, /* environment */ NULL, /* current directory */ &si, &pi); @@ -2414,8 +2520,9 @@ init_windows_ops (void) i386_dr_low.set_control = cygwin_set_dr7; i386_dr_low.set_addr = cygwin_set_dr; - i386_dr_low.reset_addr = NULL; + i386_dr_low.get_addr = cygwin_get_dr; i386_dr_low.get_status = cygwin_get_dr6; + i386_dr_low.get_control = cygwin_get_dr7; /* i386_dr_low.debug_register_length field is set by calling i386_set_debug_register_length function @@ -2430,6 +2537,9 @@ set_windows_aliases (char *argv0) add_info_alias ("dll", "sharedlibrary", 1); } +/* -Wmissing-prototypes */ +extern initialize_file_ftype _initialize_windows_nat; + void _initialize_windows_nat (void) { @@ -2547,6 +2657,14 @@ cygwin_set_dr7 (unsigned long val) debug_registers_used = 1; } +/* Get the value of debug register I from the inferior. */ + +static CORE_ADDR +cygwin_get_dr (int i) +{ + return dr[i]; +} + /* Get the value of the DR6 debug status register from the inferior. Here we just return the value stored in dr[6] by the last call to thread_rec for current_event.dwThreadId id. */ @@ -2556,6 +2674,16 @@ cygwin_get_dr6 (void) return (unsigned long) dr[6]; } +/* Get the value of the DR7 debug status register from the inferior. + Here we just return the value stored in dr[7] by the last call to + thread_rec for current_event.dwThreadId id. */ + +static unsigned long +cygwin_get_dr7 (void) +{ + return (unsigned long) dr[7]; +} + /* Determine if the thread referenced by "ptid" is alive by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0 it means that the thread has died. Otherwise it is assumed to be alive. */ @@ -2571,6 +2699,9 @@ windows_thread_alive (struct target_ops *ops, ptid_t ptid) ? FALSE : TRUE; } +/* -Wmissing-prototypes */ +extern initialize_file_ftype _initialize_check_for_gdb_ini; + void _initialize_check_for_gdb_ini (void) { @@ -2586,7 +2717,7 @@ _initialize_check_for_gdb_ini (void) sizeof ("/gdb.ini")); strcpy (oldini, homedir); p = strchr (oldini, '\0'); - if (p > oldini && p[-1] != '/') + if (p > oldini && !IS_DIR_SEPARATOR (p[-1])) *p++ = '/'; strcpy (p, "gdb.ini"); if (access (oldini, 0) == 0) @@ -2664,8 +2795,12 @@ bad_GetConsoleFontSize (HANDLE w, DWORD nFont) return size; } +/* -Wmissing-prototypes */ +extern initialize_file_ftype _initialize_loadable; + /* Load any functions which may not be available in ancient versions of Windows. */ + void _initialize_loadable (void) {