2011-09-27 Tristan Gingold <gingold@adacore.com>
authorTristan Gingold <gingold@adacore.com>
Tue, 27 Sep 2011 15:30:18 +0000 (15:30 +0000)
committerTristan Gingold <gingold@adacore.com>
Tue, 27 Sep 2011 15:30:18 +0000 (15:30 +0000)
* target.h (enum target_object): Add TARGET_OBJECT_DARWIN_DYLD_INFO.
* solib-darwin.c (DYLD_VERSION_MAX): Update number.
(darwin_solib_get_all_image_info_addr_at_init): New function.
(darwin_solib_read_all_image_info_addr): Likewise.
(darwin_solib_create_inferior_hook): Use the above two functions.
* darwin-nat.c (darwin_execvp): Renames retval to res.
(darwin_read_write_inferior): Update comment.
(darwin_read_dyld_info): New function.
(darwin_xfer_partial): Handle DYLD_INFO.

gdb/ChangeLog
gdb/darwin-nat.c
gdb/solib-darwin.c
gdb/target.h

index 5c59efcef03aab04e0d9071a6fa29e2c50cedbb3..59dfcde1b48c6df9de25aa2ef36c54a46176e158 100644 (file)
@@ -1,3 +1,15 @@
+2011-09-27  Tristan Gingold  <gingold@adacore.com>
+
+       * target.h (enum target_object): Add TARGET_OBJECT_DARWIN_DYLD_INFO.
+       * solib-darwin.c (DYLD_VERSION_MAX): Update number.
+       (darwin_solib_get_all_image_info_addr_at_init): New function.
+       (darwin_solib_read_all_image_info_addr): Likewise.
+       (darwin_solib_create_inferior_hook): Use the above two functions.
+       * darwin-nat.c (darwin_execvp): Renames retval to res.
+       (darwin_read_write_inferior): Update comment.
+       (darwin_read_dyld_info): New function.
+       (darwin_xfer_partial): Handle DYLD_INFO.
+
 2011-09-27  Stan Shebs  <stan@codesourcery.com>
 
        Add return address collection for tracepoints.
index 7c0ff5b8757cf1311dc00af000332b7d98bb6e52..94f49d6f335324ca8e7b4ebd273e852b0b8e565c 100644 (file)
@@ -1512,10 +1512,10 @@ darwin_execvp (const char *file, char * const argv[], char * const env[])
 {
   posix_spawnattr_t attr;
   short ps_flags = 0;
-  int retval;
+  int res;
 
-  retval = posix_spawnattr_init (&attr);
-  if (retval != 0)
+  res = posix_spawnattr_init (&attr);
+  if (res != 0)
     {
       fprintf_unfiltered
         (gdb_stderr, "Cannot initialize attribute for posix_spawn\n");
@@ -1531,11 +1531,10 @@ darwin_execvp (const char *file, char * const argv[], char * const env[])
 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
 #endif
   ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
-  retval = posix_spawnattr_setflags (&attr, ps_flags);
-  if (retval != 0)
+  res = posix_spawnattr_setflags (&attr, ps_flags);
+  if (res != 0)
     {
-      fprintf_unfiltered
-        (gdb_stderr, "Cannot set posix_spawn flags\n");
+      fprintf_unfiltered (gdb_stderr, "Cannot set posix_spawn flags\n");
       return;
     }
 
@@ -1695,7 +1694,7 @@ darwin_thread_alive (struct target_ops *ops, ptid_t ptid)
    copy it to RDADDR in gdb's address space.
    If WRADDR is not NULL, write gdb's LEN bytes from WRADDR and copy it
    to ADDR in inferior task's address space.
-   Return 0 on failure; number of bytes read / writen  otherwise.  */
+   Return 0 on failure; number of bytes read / writen otherwise.  */
 static int
 darwin_read_write_inferior (task_t task, CORE_ADDR addr,
                            char *rdaddr, const char *wraddr, int length)
@@ -1824,6 +1823,32 @@ out:
   return length;
 }
 
+/* Read LENGTH bytes at offset ADDR of task_dyld_info for TASK, and copy them
+   to RDADDR.
+   Return 0 on failure; number of bytes read / writen otherwise.  */
+
+static int
+darwin_read_dyld_info (task_t task, CORE_ADDR addr, char *rdaddr, int length)
+{
+  struct task_dyld_info task_dyld_info;
+  mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
+  int sz = TASK_DYLD_INFO_COUNT * sizeof (natural_t);
+  kern_return_t kret;
+
+  if (addr >= sz)
+    return 0;
+
+  kret = task_info (task, TASK_DYLD_INFO, (task_info_t) &task_dyld_info, &count);
+  MACH_CHECK_ERROR (kret);
+  if (kret != KERN_SUCCESS)
+    return -1;
+  /* Truncate.  */
+  if (addr + length > sz)
+    length = sz - addr;
+  memcpy (rdaddr, (char *)&task_dyld_info + addr, length);
+  return length;
+}
+
 \f
 /* Return 0 on failure, number of bytes handled otherwise.  TARGET
    is ignored.  */
@@ -1860,11 +1885,22 @@ darwin_xfer_partial (struct target_ops *ops,
      host_address_to_string (readbuf), host_address_to_string (writebuf),
      inf->pid);
 
-  if (object != TARGET_OBJECT_MEMORY)
-    return -1;
+  switch (object)
+    {
+    case TARGET_OBJECT_MEMORY:
+      return darwin_read_write_inferior (inf->private->task, offset,
+                                         readbuf, writebuf, len);
+    case TARGET_OBJECT_DARWIN_DYLD_INFO:
+      if (writebuf != NULL || readbuf == NULL)
+        {
+          /* Support only read.  */
+          return -1;
+        }
+      return darwin_read_dyld_info (inf->private->task, offset, readbuf, len);
+    default:
+      return -1;
+    }
 
-  return darwin_read_write_inferior (inf->private->task, offset,
-                                    readbuf, writebuf, len);
 }
 
 static void
index 24301d90618b9e05255446e3da61e7c866e5a9c9..d592809cbf862d58eaa76e9f126d21a65ed2755d 100644 (file)
@@ -68,7 +68,7 @@ struct gdb_dyld_all_image_infos
 
 /* Current all_image_infos version.  */
 #define DYLD_VERSION_MIN 1
-#define DYLD_VERSION_MAX 7
+#define DYLD_VERSION_MAX 12
 
 /* Address of structure dyld_all_image_infos in inferior.  */
 static CORE_ADDR dyld_all_image_addr;
@@ -293,22 +293,19 @@ darwin_special_symbol_handling (void)
 {
 }
 
-/* Shared library startup support.  See documentation in solib-svr4.c.  */
+/* Extract dyld_all_image_addr when the process was just created, assuming the
+   current PC is at the entry of the dynamic linker.  */
 
 static void
-darwin_solib_create_inferior_hook (int from_tty)
+darwin_solib_get_all_image_info_addr_at_init (void)
 {
-  struct minimal_symbol *msymbol;
-  char **bkpt_namep;
-  asection *interp_sect;
   gdb_byte *interp_name;
-  CORE_ADDR sym_addr;
   CORE_ADDR load_addr = 0;
-  int load_addr_found = 0;
-  int loader_found_in_list = 0;
-  struct so_list *so;
   bfd *dyld_bfd = NULL;
-  struct inferior *inf = current_inferior ();
+
+  /* This method doesn't work with an attached process.  */
+  if (current_inferior ()->attach_flag)
+    return;
 
   /* Find the program interpreter.  */
   interp_name = find_program_interpreter ();
@@ -316,7 +313,6 @@ darwin_solib_create_inferior_hook (int from_tty)
     return;
 
   /* Create a bfd for the interpreter.  */
-  sym_addr = 0;
   dyld_bfd = bfd_openr (interp_name, gnutarget);
   if (dyld_bfd)
     {
@@ -335,21 +331,11 @@ darwin_solib_create_inferior_hook (int from_tty)
   if (!dyld_bfd)
     return;
 
-  if (!inf->attach_flag)
-    {
-      /* We find the dynamic linker's base address by examining
-        the current pc (which should point at the entry point for the
-        dynamic linker) and subtracting the offset of the entry point.  */
-      load_addr = (regcache_read_pc (get_current_regcache ())
-                  - bfd_get_start_address (dyld_bfd));
-    }
-  else
-    {
-      /* FIXME: todo.
-        Get address of __DATA.__dyld in exec_bfd, read address at offset 0.
-      */
-      return;
-    }
+  /* We find the dynamic linker's base address by examining
+     the current pc (which should point at the entry point for the
+     dynamic linker) and subtracting the offset of the entry point.  */
+  load_addr = (regcache_read_pc (get_current_regcache ())
+               - bfd_get_start_address (dyld_bfd));
 
   /* Now try to set a breakpoint in the dynamic linker.  */
   dyld_all_image_addr =
@@ -361,6 +347,40 @@ darwin_solib_create_inferior_hook (int from_tty)
     return;
 
   dyld_all_image_addr += load_addr;
+}
+
+/* Extract dyld_all_image_addr reading it from 
+   TARGET_OBJECT_DARWIN_DYLD_INFO.  */
+
+static void
+darwin_solib_read_all_image_info_addr (void)
+{
+  gdb_byte buf[8 + 8 + 4];
+  LONGEST len;
+  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+
+  len = target_read (&current_target, TARGET_OBJECT_DARWIN_DYLD_INFO, NULL,
+                     buf, 0, sizeof (buf));
+  if (len != sizeof (buf))
+    return;
+
+  dyld_all_image_addr = extract_unsigned_integer (buf, 8, byte_order);
+}
+
+/* Shared library startup support.  See documentation in solib-svr4.c.  */
+
+static void
+darwin_solib_create_inferior_hook (int from_tty)
+{
+  dyld_all_image_addr = 0;
+
+  darwin_solib_read_all_image_info_addr ();
+
+  if (dyld_all_image_addr == 0)
+    darwin_solib_get_all_image_info_addr_at_init ();
+
+  if (dyld_all_image_addr == 0)
+    return;
 
   darwin_load_image_infos ();
 
index e2646571e3f4a3ca812fc408a090e95169ae34ac..173e60bd549949321d10e135d5727d86c3f3bcca 100644 (file)
@@ -276,6 +276,8 @@ enum target_object
   TARGET_OBJECT_TRACEFRAME_INFO,
   /* Load maps for FDPIC systems.  */
   TARGET_OBJECT_FDPIC,
+  /* Darwin dynamic linker info data.  */
+  TARGET_OBJECT_DARWIN_DYLD_INFO
   /* Possible future objects: TARGET_OBJECT_FILE, ...  */
 };