* win32-nat.c (solib_symbols_add): Use one variable for all section address
[deliverable/binutils-gdb.git] / gdb / windows-nat.c
index 2f7e8ccd7b1444c2e9c7416dfaec562f2ffda99b..897a541ba9d36ea840cd6e8c52101e4c8f62a02f 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-vector operations for controlling win32 child processes, for GDB.
 
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free
    Software Foundation, Inc.
 
    Contributed by Cygnus Solutions, A Red Hat Company.
@@ -123,7 +123,7 @@ static DEBUG_EVENT current_event;   /* The current debug event from
                                           WaitForDebugEvent */
 static HANDLE current_process_handle;  /* Currently executing process */
 static thread_info *current_thread;    /* Info on currently selected thread */
-static DWORD main_thread_id;   /* Thread ID of the main thread */
+static DWORD main_thread_id;           /* Thread ID of the main thread */
 
 /* Counts of things. */
 static int exception_count = 0;
@@ -139,9 +139,6 @@ static int debug_memory = 0;                /* show target memory accesses */
 static int debug_exceptions = 0;       /* show target exceptions */
 static int useshell = 0;               /* use shell for subprocesses */
 
-/* Path to shell */
-static char shell[MAX_PATH + 1];
-
 /* This vector maps GDB's idea of a register's number into an address
    in the win32 exception context vector.
 
@@ -385,7 +382,7 @@ static void
 do_child_store_inferior_registers (int r)
 {
   if (r >= 0)
-    read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
+    regcache_collect (r, ((char *) &current_thread->context) + mappings[r]);
   else
     {
       for (r = 0; r < NUM_REGS; r++)
@@ -475,7 +472,7 @@ psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
                                           dll_name_ret,
                                           MAX_PATH);
       if (len == 0)
-       error ("Error getting dll name: %u\n", GetLastError ());
+       error ("Error getting dll name: %u\n", (unsigned) GetLastError ());
 
       if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
        return 1;
@@ -504,6 +501,7 @@ struct so_stuff
 {
   struct so_stuff *next;
   DWORD load_addr;
+  DWORD end_addr;
   int loaded;
   struct objfile *objfile;
   char name[1];
@@ -580,24 +578,36 @@ register_loaded_dll (const char *name, DWORD load_addr)
   char *p;
   WIN32_FIND_DATA w32_fd;
   HANDLE h = FindFirstFile(name, &w32_fd);
+  MEMORY_BASIC_INFORMATION m;
   size_t len;
 
-  FindClose (h);
-  strcpy (buf, name);
-  if (GetCurrentDirectory (MAX_PATH + 1, cwd))
+  if (h == INVALID_HANDLE_VALUE)
+    strcpy (buf, name);
+  else
     {
-      p = strrchr (buf, '\\');
-      if (p)
-       p[1] = '\0';
-      SetCurrentDirectory (buf);
-      GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
-      SetCurrentDirectory (cwd);
+      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);
+       }
     }
 
   cygwin_conv_to_posix_path (buf, ppath);
   so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
   so->loaded = 0;
   so->load_addr = load_addr;
+  if (VirtualQueryEx (current_process_handle, (void *) load_addr, &m,
+                     sizeof (m)))
+    so->end_addr = (DWORD) m.AllocationBase + m.RegionSize;
+  else
+    so->end_addr = load_addr + 0x2000; /* completely arbitrary */
+
   so->next = NULL;
   so->objfile = NULL;
   strcpy (so->name, ppath);
@@ -625,21 +635,16 @@ get_image_name (HANDLE h, void *address, int unicode)
   if (address == NULL)
     return NULL;
 
-  ReadProcessMemory (h, address,  &address_ptr, sizeof (address_ptr), &done);
-
   /* See if we could read the address of a string, and that the
      address isn't null. */
-
-  if (done != sizeof (address_ptr) || !address_ptr)
+  if (!ReadProcessMemory (h, address,  &address_ptr, sizeof (address_ptr), &done)
+      || done != sizeof (address_ptr) || !address_ptr)
     return NULL;
 
   /* Find the length of the string */
-  do
-    {
-      ReadProcessMemory (h, address_ptr + len * size, &b, size, &done);
-      len++;
-    }
-  while ((b[0] != 0 || b[size - 1] != 0) && done == size);
+  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);
@@ -705,6 +710,16 @@ handle_unload_dll (void *dummy)
   return 0;
 }
 
+char *
+solib_address (CORE_ADDR address)
+{
+  struct so_stuff *so;
+  for (so = &solib_start; so->next != NULL; so = so->next)
+    if (address >= so->load_addr && address <= so->end_addr)
+      return so->name;
+  return NULL;
+}
+
 /* Return name of last loaded DLL. */
 char *
 child_solib_loaded_library_pathname (int pid)
@@ -730,11 +745,66 @@ child_clear_solibs (void)
   max_dll_name_len = sizeof ("DLL Name") - 1;
 }
 
+/* Get the loaded address of all sections, given that .text was loaded
+   at text_load. Assumes that all sections are subject to the same
+   relocation offset. Returns NULL if problems occur or if the
+   sections were not relocated. */
+
+static struct section_addr_info *
+get_relocated_section_addrs (bfd *abfd, CORE_ADDR text_load)
+{
+  struct section_addr_info *result = NULL;
+  int section_count = bfd_count_sections (abfd);
+  asection *text_section = bfd_get_section_by_name (abfd, ".text");
+  CORE_ADDR text_vma;
+
+  if (!text_section)
+    {
+      /* Couldn't get the .text section. Weird. */
+    }
+
+  else if (text_load == (text_vma = bfd_get_section_vma (abfd, text_section)))
+    {
+      /* DLL wasn't relocated. */
+    }
+
+  else
+    {
+      /* Figure out all sections' loaded addresses. The offset here is
+        such that taking a bfd_get_section_vma() result and adding
+        offset will give the real load address of the section. */
+
+      CORE_ADDR offset = text_load - text_vma;
+
+      struct section_table *table_start = NULL;
+      struct section_table *table_end = NULL;
+      struct section_table *iter = NULL;
+
+      build_section_table (abfd, &table_start, &table_end);
+
+      for (iter = table_start; iter < table_end; ++iter)
+       {
+         /* Relocated addresses. */
+         iter->addr += offset;
+         iter->endaddr += offset;
+       }
+
+      result = build_section_addr_info_from_section_table (table_start,
+                                                          table_end);
+
+      xfree (table_start);
+    }
+
+  return result;
+}
+
 /* Add DLL symbol information. */
 static struct objfile *
 solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
 {
-  struct section_addr_info section_addrs;
+  struct section_addr_info *addrs = NULL;
+  static struct objfile *result = NULL;
+  bfd *abfd = NULL;
 
   /* The symbols in a dll are offset by 0x1000, which is the
      the offset from 0 of the first byte in an image - because
@@ -743,10 +813,44 @@ solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
   if (!name || !name[0])
     return NULL;
 
-  memset (&section_addrs, 0, sizeof (section_addrs));
-  section_addrs.other[0].name = ".text";
-  section_addrs.other[0].addr = load_addr;
-  return safe_symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
+  abfd = bfd_openr (name, "pei-i386");
+
+  if (!abfd)
+    {
+      /* pei failed - try pe */
+      abfd = bfd_openr (name, "pe-i386");
+    }
+
+  if (abfd)
+    {
+      if (bfd_check_format (abfd, bfd_object))
+       {
+         addrs = get_relocated_section_addrs (abfd, load_addr);
+       }
+
+      bfd_close (abfd);
+    }
+
+  if (addrs)
+    {
+      result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED);
+      free_section_addr_info (addrs);
+    }
+  else
+    {
+      /* Fallback on handling just the .text section. */
+      struct cleanup *my_cleanups;
+
+      addrs = alloc_section_addr_info (1);
+      my_cleanups = make_cleanup (xfree, addrs);
+      addrs->other[0].name = ".text";
+      addrs->other[0].addr = load_addr;
+
+      result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED);
+      do_cleanups (my_cleanups);
+    }
+
+  return result;
 }
 
 /* Load DLL symbol info. */
@@ -820,6 +924,126 @@ handle_output_debug_string (struct target_waitstatus *ourstatus)
   return gotasig;
 }
 
+static int
+display_selector (HANDLE thread, DWORD sel)
+{
+  LDT_ENTRY info;
+  if (GetThreadSelectorEntry (thread, sel, &info))
+    {
+      int base, limit;
+      printf_filtered ("0x%03lx: ", 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
+    {
+      printf_filtered ("Invalid selector 0x%lx.\n",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);
+    }
+}
+
+static struct cmd_list_element *info_w32_cmdlist = NULL;
+
+static void
+info_w32_command (char *args, int from_tty)
+{
+  help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
+}
+
+
 #define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
   printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
   (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
@@ -1075,6 +1299,7 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
       ourstatus->kind = TARGET_WAITKIND_LOADED;
       ourstatus->value.integer = 0;
       retval = main_thread_id;
+      re_enable_breakpoints_in_shlibs ();
       break;
 
     case UNLOAD_DLL_DEBUG_EVENT:
@@ -1182,6 +1407,7 @@ do_initial_child_stuff (DWORD pid)
   memset (&current_event, 0, sizeof (current_event));
   push_target (&child_ops);
   child_init_thread_list ();
+  disable_breakpoints_in_shlibs (1);
   child_clear_solibs ();
   clear_proceed_status ();
   init_wait_for_inferior ();
@@ -1211,7 +1437,7 @@ static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
 static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
 
 static int
-has_detach_ability ()
+has_detach_ability (void)
 {
   static HMODULE kernel32 = NULL;
 
@@ -1231,6 +1457,83 @@ has_detach_ability ()
   return 0;
 }
 
+/* Try to set or remove a user privilege to the current process.  Return -1
+   if that fails, the previous setting of that privilege otherwise.
+
+   This code is copied from the Cygwin source code and rearranged to allow
+   dynamically loading of the needed symbols from advapi32 which is only
+   available on NT/2K/XP. */
+static int
+set_process_privilege (const char *privilege, BOOL enable)
+{
+  static HMODULE advapi32 = NULL;
+  static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
+  static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
+  static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
+                                             DWORD, PTOKEN_PRIVILEGES, PDWORD);
+
+  HANDLE token_hdl = NULL;
+  LUID restore_priv;
+  TOKEN_PRIVILEGES new_priv, orig_priv;
+  int ret = -1;
+  DWORD size;
+
+  if (GetVersion () >= 0x80000000)  /* No security availbale on 9x/Me */
+    return 0;
+
+  if (!advapi32)
+    {
+      if (!(advapi32 = LoadLibrary ("advapi32.dll")))
+       goto out;
+      if (!OpenProcessToken)
+       OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken");
+      if (!LookupPrivilegeValue)
+       LookupPrivilegeValue = GetProcAddress (advapi32,
+                                              "LookupPrivilegeValueA");
+      if (!AdjustTokenPrivileges)
+       AdjustTokenPrivileges = GetProcAddress (advapi32,
+                                               "AdjustTokenPrivileges");
+      if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
+       {
+         advapi32 = NULL;
+         goto out;
+       }
+    }
+
+  if (!OpenProcessToken (GetCurrentProcess (),
+                        TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
+                        &token_hdl))
+    goto out;
+
+  if (!LookupPrivilegeValue (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
+  /* Disabled, otherwise every `attach' in an unprivileged user session
+     would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
+     child_attach(). */
+  /* AdjustTokenPrivileges returns TRUE even if the privilege could not
+     be enabled. GetLastError () returns an correct error code, though. */
+  if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
+    goto out;
+#endif
+
+  ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
+
+out:
+  if (token_hdl)
+    CloseHandle (token_hdl);
+
+  return ret;
+}
+
 /* Attach to process PID, then initialize for debugging it.  */
 static void
 child_attach (char *args, int from_tty)
@@ -1241,11 +1544,28 @@ child_attach (char *args, int from_tty)
   if (!args)
     error_no_arg ("process-id to attach");
 
-  pid = strtoul (args, 0, 0);
+  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");
+    }
+
+  pid = strtoul (args, 0, 0);          /* Windows pid */
+
   ok = DebugActiveProcess (pid);
+  saw_create = 0;
 
   if (!ok)
-    error ("Can't attach to process.");
+    {
+      /* Try fall back to Cygwin pid */
+      pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
+
+      if (pid > 0)
+       ok = DebugActiveProcess (pid);
+
+      if (!ok)
+       error ("Can't attach to process.");
+    }
 
   if (has_detach_ability ())
     {
@@ -1336,6 +1656,10 @@ child_create_inferior (char *exec_file, char *allargs, char **env)
   char *args;
   char real_path[MAXPATHLEN];
   char *toexec;
+  char shell[MAX_PATH + 1]; /* Path to shell */
+  const char *sh;
+  int tty;
+  int ostdin, ostdout, ostderr;
 
   if (!exec_file)
     error ("No executable specified, use `target exec'.\n");
@@ -1343,15 +1667,7 @@ child_create_inferior (char *exec_file, char *allargs, char **env)
   memset (&si, 0, sizeof (si));
   si.cb = sizeof (si);
 
-  flags = 0;
-
-  if (new_group)
-    flags |= CREATE_NEW_PROCESS_GROUP;
-
-  if (new_console)
-    flags |= CREATE_NEW_CONSOLE;
-
-  if (!useshell || !shell[0])
+  if (!useshell)
     {
       flags = DEBUG_ONLY_THIS_PROCESS;
       cygwin_conv_to_win32_path (exec_file, real_path);
@@ -1359,13 +1675,25 @@ child_create_inferior (char *exec_file, char *allargs, char **env)
     }
   else
     {
-      char *newallargs = alloca (sizeof (" -c 'exec  '") + strlen (exec_file) + strlen (allargs) + 2);
+      char *newallargs;
+      sh = getenv ("SHELL");
+      if (!sh)
+       sh = "/bin/sh";
+      cygwin_conv_to_win32_path (sh, shell);
+      newallargs = alloca (sizeof (" -c 'exec  '") + strlen (exec_file)
+                          + strlen (allargs) + 2);
       sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
       allargs = newallargs;
       toexec = shell;
       flags = DEBUG_PROCESS;
     }
 
+  if (new_group)
+    flags |= CREATE_NEW_PROCESS_GROUP;
+
+  if (new_console)
+    flags |= CREATE_NEW_CONSOLE;
+
   args = alloca (strlen (toexec) + strlen (allargs) + 2);
   strcpy (args, toexec);
   strcat (args, " ");
@@ -1373,7 +1701,7 @@ child_create_inferior (char *exec_file, char *allargs, char **env)
 
   /* Prepare the environment vars for CreateProcess.  */
   {
-    /* This code use to assume all env vars were file names and would
+    /* This code used to assume all env vars were file names and would
        translate them all to win32 style.  That obviously doesn't work in the
        general case.  The current rule is that we only translate PATH.
        We need to handle PATH because we're about to call CreateProcess and
@@ -1444,6 +1772,27 @@ child_create_inferior (char *exec_file, char *allargs, char **env)
     *temp = 0;
   }
 
+  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);
+       }
+    }
+
   ret = CreateProcess (0,
                       args,    /* command line */
                       NULL,    /* Security */
@@ -1454,8 +1803,19 @@ child_create_inferior (char *exec_file, char *allargs, char **env)
                       NULL,    /* current directory */
                       &si,
                       &pi);
+  if (tty >= 0)
+    {
+      close (tty);
+      dup2 (ostdin, 0);
+      dup2 (ostdout, 1);
+      dup2 (ostderr, 2);
+      close (ostdin);
+      close (ostdout);
+      close (ostderr);
+    }
+
   if (!ret)
-    error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
+    error ("Error creating process %s, (error %d)\n", exec_file, (unsigned) GetLastError ());
 
   CloseHandle (pi.hThread);
   CloseHandle (pi.hProcess);
@@ -1496,21 +1856,23 @@ child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
                   int write, struct mem_attrib *mem,
                   struct target_ops *target)
 {
-  DWORD done;
+  DWORD done = 0;
   if (write)
     {
       DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
                  len, (DWORD) memaddr));
-      WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
-                         len, &done);
+      if (!WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
+                              len, &done))
+       done = 0;
       FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
     }
   else
     {
       DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
                  len, (DWORD) memaddr));
-      ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
-                        &done);
+      if (!ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our,
+                             len, &done))
+       done = 0;
     }
   return done;
 }
@@ -1597,16 +1959,16 @@ child_resume (ptid_t ptid, int step, enum target_signal sig)
 
       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 = dr[6];
-          FIXME: should we set dr6 also ?? */
-         th->context.Dr7 = dr[7];
-       }
+         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 = dr[6];
+              FIXME: should we set dr6 also ?? */
+             th->context.Dr7 = dr[7];
+           }
          CHECK (SetThreadContext (th->h, &th->context));
          th->context.ContextFlags = 0;
        }
@@ -1662,54 +2024,34 @@ init_child_ops (void)
   child_ops.to_terminal_inferior = terminal_inferior;
   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
   child_ops.to_terminal_ours = terminal_ours;
+  child_ops.to_terminal_save_ours = terminal_save_ours;
   child_ops.to_terminal_info = child_terminal_info;
   child_ops.to_kill = child_kill_inferior;
-  child_ops.to_load = 0;
-  child_ops.to_lookup_symbol = 0;
   child_ops.to_create_inferior = child_create_inferior;
   child_ops.to_mourn_inferior = child_mourn_inferior;
   child_ops.to_can_run = child_can_run;
-  child_ops.to_notice_signals = 0;
   child_ops.to_thread_alive = win32_child_thread_alive;
   child_ops.to_pid_to_str = cygwin_pid_to_str;
   child_ops.to_stop = child_stop;
   child_ops.to_stratum = process_stratum;
-  child_ops.DONT_USE = 0;
   child_ops.to_has_all_memory = 1;
   child_ops.to_has_memory = 1;
   child_ops.to_has_stack = 1;
   child_ops.to_has_registers = 1;
   child_ops.to_has_execution = 1;
-  child_ops.to_sections = 0;
-  child_ops.to_sections_end = 0;
   child_ops.to_magic = OPS_MAGIC;
 }
 
 void
-_initialize_inftarg (void)
+_initialize_win32_nat (void)
 {
   struct cmd_list_element *c;
-  const char *sh;
 
   init_child_ops ();
 
   c = add_com ("dll-symbols", class_files, dll_symbol_command,
               "Load dll library symbols from FILE.");
-  c->completer = filename_completer;
-
-  sh = getenv ("SHELL");
-  if (!sh)
-    sh = "/bin/sh";
-  if (access (sh, X_OK) != 0)
-    {
-      shell[0] = '\0';
-      useshell = 0;
-    }
-  else
-    {
-      cygwin_conv_to_win32_path (sh, shell);
-      useshell = 1;
-    }
+  set_cmd_completer (c, filename_completer);
 
   add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
 
@@ -1758,6 +2100,14 @@ _initialize_inftarg (void)
   add_info ("dll", info_dll_command, "Status of loaded DLLs.");
   add_info_alias ("sharedlibrary", "dll", 1);
 
+  add_prefix_cmd ("w32", class_info, info_w32_command,
+                 "Print information specific to Win32 debugging.",
+                 &info_w32_cmdlist, "info w32 ", 0, &infolist);
+
+  add_cmd ("selector", class_info, display_selectors,
+          "Display selectors infos.",
+          &info_w32_cmdlist);
+
   add_target (&child_ops);
 }
 
@@ -1860,8 +2210,7 @@ typedef struct
 {
   struct target_ops *target;
   bfd_vma addr;
-}
-map_code_section_args;
+} map_code_section_args;
 
 static void
 map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
This page took 0.033978 seconds and 4 git commands to generate.