* 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 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.
{
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");
#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;
}
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)
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. */
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
/* 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;
{
}
-/* 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 ();
return;
/* Create a bfd for the interpreter. */
- sym_addr = 0;
dyld_bfd = bfd_openr (interp_name, gnutarget);
if (dyld_bfd)
{
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 =
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 (¤t_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 ();
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, ... */
};