2003-06-30 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / windows-nat.c
index accd6847321ebe8cf2d014ed0354190d2c94ca93..c2227cd29fe4d3902e3176f190691d3009fa39e5 100644 (file)
@@ -124,7 +124,6 @@ static DEBUG_EVENT current_event;   /* The current debug event from
 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 pid_t cygwin_pid;               /* pid of cygwin process */
 
 /* Counts of things. */
 static int exception_count = 0;
@@ -383,7 +382,7 @@ static void
 do_child_store_inferior_registers (int r)
 {
   if (r >= 0)
-    deprecated_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++)
@@ -603,8 +602,8 @@ register_loaded_dll (const char *name, DWORD load_addr)
   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)))
+  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 */
@@ -636,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);
@@ -751,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 *section_addrs_ptr = 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
@@ -764,10 +813,49 @@ 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, &section_addrs, 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))
+       {
+         section_addrs_ptr = get_relocated_section_addrs (abfd, load_addr);
+       }
+
+      bfd_close (abfd);
+    }
+
+  if (section_addrs_ptr)
+    {
+      result = safe_symbol_file_add (name, from_tty, section_addrs_ptr,
+                                    0, OBJF_SHARED);
+
+      free_section_addr_info (section_addrs_ptr);
+    }
+
+  else
+    {
+      /* Fallback on handling just the .text section. */
+      struct section_addr_info *section_addrs;
+      struct cleanup *my_cleanups;
+
+      section_addrs = alloc_section_addr_info (1);
+      my_cleanups = make_cleanup (xfree, section_addrs);
+      section_addrs->other[0].name = ".text";
+      section_addrs->other[0].addr = load_addr;
+
+      result = safe_symbol_file_add (name, from_tty, &section_addrs,
+                                    0, OBJF_SHARED);
+      do_cleanups (my_cleanups);
+    }
+
+  return result;
 }
 
 /* Load DLL symbol info. */
@@ -850,58 +938,58 @@ display_selector (HANDLE thread, DWORD sel)
       int base, limit;
       printf_filtered ("0x%03lx: ", sel);
       if (!info.HighWord.Bits.Pres)
-        {
-          puts_filtered ("Segment not present\n");
-          return 0;
-        }
+       {
+         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;
+       limit = (limit << 12) | 0xfff;
       printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
       if (info.HighWord.Bits.Default_Big)
-        puts_filtered(" 32-bit ");
+       puts_filtered(" 32-bit ");
       else
-        puts_filtered(" 16-bit ");
+       puts_filtered(" 16-bit ");
       switch ((info.HighWord.Bits.Type & 0xf) >> 1)
        {
        case 0:
-          puts_filtered ("Data (Read-Only, Exp-up");
-          break;
+         puts_filtered ("Data (Read-Only, Exp-up");
+         break;
        case 1:
-          puts_filtered ("Data (Read/Write, Exp-up");
-          break;
+         puts_filtered ("Data (Read/Write, Exp-up");
+         break;
        case 2:
-          puts_filtered ("Unused segment (");
-          break;
+         puts_filtered ("Unused segment (");
+         break;
        case 3:
-          puts_filtered ("Data (Read/Write, Exp-down");
-          break;
+         puts_filtered ("Data (Read/Write, Exp-down");
+         break;
        case 4:
-          puts_filtered ("Code (Exec-Only, N.Conf");
-          break;
+         puts_filtered ("Code (Exec-Only, N.Conf");
+         break;
        case 5:
-          puts_filtered ("Code (Exec/Read, N.Conf");
+         puts_filtered ("Code (Exec/Read, N.Conf");
          break;
        case 6:
-          puts_filtered ("Code (Exec-Only, Conf");
+         puts_filtered ("Code (Exec-Only, Conf");
          break;
        case 7:
-          puts_filtered ("Code (Exec/Read, Conf");
+         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.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");
+       puts_filtered ("Page granular.\n");
       else
        puts_filtered ("Byte granular.\n");
       return 1;
@@ -926,22 +1014,22 @@ display_selectors (char * args, int from_tty)
 
       puts_filtered ("Selector $cs\n");
       display_selector (current_thread->h,
-        current_thread->context.SegCs);
+       current_thread->context.SegCs);
       puts_filtered ("Selector $ds\n");
       display_selector (current_thread->h,
-        current_thread->context.SegDs);
+       current_thread->context.SegDs);
       puts_filtered ("Selector $es\n");
       display_selector (current_thread->h,
-        current_thread->context.SegEs);
+       current_thread->context.SegEs);
       puts_filtered ("Selector $ss\n");
       display_selector (current_thread->h,
-        current_thread->context.SegSs);
+       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);
+       current_thread->context.SegGs);
     }
   else
     {
@@ -1411,12 +1499,12 @@ set_process_privilege (const char *privilege, BOOL enable)
        AdjustTokenPrivileges = GetProcAddress (advapi32,
                                                "AdjustTokenPrivileges");
       if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
-        {
+       {
          advapi32 = NULL;
          goto out;
        }
     }
-  
+
   if (!OpenProcessToken (GetCurrentProcess (),
                         TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
                         &token_hdl))
@@ -1430,7 +1518,7 @@ set_process_privilege (const char *privilege, BOOL enable)
   new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
 
   if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
-                              sizeof orig_priv, &orig_priv, &size))
+                             sizeof orig_priv, &orig_priv, &size))
     goto out;
 #if 0
   /* Disabled, otherwise every `attach' in an unprivileged user session
@@ -1467,12 +1555,22 @@ child_attach (char *args, int from_tty)
       printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
     }
 
-  pid = strtoul (args, 0, 0);
+  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 ())
     {
@@ -1763,21 +1861,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;
 }
@@ -1864,16 +1964,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;
        }
@@ -2006,11 +2106,11 @@ _initialize_win32_nat (void)
   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);
+                 "Print information specific to Win32 debugging.",
+                 &info_w32_cmdlist, "info w32 ", 0, &infolist);
 
   add_cmd ("selector", class_info, display_selectors,
-           "Display selectors infos.",
+          "Display selectors infos.",
           &info_w32_cmdlist);
 
   add_target (&child_ops);
This page took 0.037146 seconds and 4 git commands to generate.