From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8368 invoked by alias); 27 Sep 2011 13:41:47 -0000 Received: (qmail 8344 invoked by uid 22791); 27 Sep 2011 13:41:44 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00,TW_CP X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 27 Sep 2011 13:41:29 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 4159ACB02A9 for ; Tue, 27 Sep 2011 15:41:29 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CX8DsInTaAdv for ; Tue, 27 Sep 2011 15:41:18 +0200 (CEST) Received: from ulanbator.act-europe.fr (ulanbator.act-europe.fr [10.10.1.67]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id EB505CB0251 for ; Tue, 27 Sep 2011 15:41:18 +0200 (CEST) From: Tristan Gingold Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Subject: [RFA] Darwin: handle shared libraries in attached processes Date: Tue, 27 Sep 2011 15:07:00 -0000 Message-Id: To: "gdb-patches@sourceware.org ml" Mime-Version: 1.0 (Apple Message framework v1244.3) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-09/txt/msg00458.txt.bz2 Hi, this patch adds support for shared libraries in attached processes. This w= as not supported until now. The basic issue is to know the address at which the dynamic loader is loade= d. This is done using a method similar to linux: an address is read from t= he target object space TARGET_OBJECT_DARWIN_DYLD_INFO (not unlike TARGET_OB= JECT_AUXV). Most of the code is within my area maintenance, except the new macro in tar= get.h Manually tested on x86_64-apple-darwin11 Ok for trunk ? Tristan. 2011-09-27 Tristan Gingold * 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. diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c index 7c0ff5b..94f49d6 100644 --- a/gdb/darwin-nat.c +++ b/gdb/darwin-nat.c @@ -1512,10 +1512,10 @@ darwin_execvp (const char *file, char * const argv[= ], char * const env[]) { posix_spawnattr_t attr; short ps_flags =3D 0; - int retval; + int res; =20 - retval =3D posix_spawnattr_init (&attr); - if (retval !=3D 0) + res =3D posix_spawnattr_init (&attr); + if (res !=3D 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 |=3D _POSIX_SPAWN_DISABLE_ASLR; - retval =3D posix_spawnattr_setflags (&attr, ps_flags); - if (retval !=3D 0) + res =3D posix_spawnattr_setflags (&attr, ps_flags); + if (res !=3D 0) { - fprintf_unfiltered - (gdb_stderr, "Cannot set posix_spawn flags\n"); + fprintf_unfiltered (gdb_stderr, "Cannot set posix_spawn flags\n"); return; } =20 @@ -1695,7 +1694,7 @@ darwin_thread_alive (struct target_ops *ops, ptid_t p= tid) 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; } =20 +/* Read LENGTH bytes at offset ADDR of task_dyld_info for TASK, and copy t= hem + 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 leng= th) +{ + struct task_dyld_info task_dyld_info; + mach_msg_type_number_t count =3D TASK_DYLD_INFO_COUNT; + int sz =3D TASK_DYLD_INFO_COUNT * sizeof (natural_t); + kern_return_t kret; + + if (addr >=3D sz) + return 0; + + kret =3D task_info (task, TASK_DYLD_INFO, (task_info_t) &task_dyld_info,= &count); + MACH_CHECK_ERROR (kret); + if (kret !=3D KERN_SUCCESS) + return -1; + /* Truncate. */ + if (addr + length > sz) + length =3D sz - addr; + memcpy (rdaddr, (char *)&task_dyld_info + addr, length); + return length; +} + =20 /* 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); =20 - if (object !=3D 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 !=3D NULL || readbuf =3D=3D NULL) + { + /* Support only read. */ + return -1; + } + return darwin_read_dyld_info (inf->private->task, offset, readbuf, l= en); + default: + return -1; + } =20 - return darwin_read_write_inferior (inf->private->task, offset, - readbuf, writebuf, len); } =20 static void diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c index 24301d9..d592809 100644 --- a/gdb/solib-darwin.c +++ b/gdb/solib-darwin.c @@ -68,7 +68,7 @@ struct gdb_dyld_all_image_infos =20 /* Current all_image_infos version. */ #define DYLD_VERSION_MIN 1 -#define DYLD_VERSION_MAX 7 +#define DYLD_VERSION_MAX 12 =20 /* 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) { } =20 -/* 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. */ =20 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 =3D 0; - int load_addr_found =3D 0; - int loader_found_in_list =3D 0; - struct so_list *so; bfd *dyld_bfd =3D NULL; - struct inferior *inf =3D current_inferior (); + + /* This method doesn't work with an attached process. */ + if (current_inferior ()->attach_flag) + return; =20 /* Find the program interpreter. */ interp_name =3D find_program_interpreter (); @@ -316,7 +313,6 @@ darwin_solib_create_inferior_hook (int from_tty) return; =20 /* Create a bfd for the interpreter. */ - sym_addr =3D 0; dyld_bfd =3D bfd_openr (interp_name, gnutarget); if (dyld_bfd) { @@ -335,21 +331,11 @@ darwin_solib_create_inferior_hook (int from_tty) if (!dyld_bfd) return; =20 - 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 =3D (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 =3D (regcache_read_pc (get_current_regcache ()) + - bfd_get_start_address (dyld_bfd)); =20 /* Now try to set a breakpoint in the dynamic linker. */ dyld_all_image_addr =3D @@ -361,6 +347,40 @@ darwin_solib_create_inferior_hook (int from_tty) return; =20 dyld_all_image_addr +=3D load_addr; +} + +/* Extract dyld_all_image_addr reading it from=20 + 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 =3D gdbarch_byte_order (target_gdbarch); + + len =3D target_read (¤t_target, TARGET_OBJECT_DARWIN_DYLD_INFO, NU= LL, + buf, 0, sizeof (buf)); + if (len !=3D sizeof (buf)) + return; + + dyld_all_image_addr =3D 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 =3D 0; + + darwin_solib_read_all_image_info_addr (); + + if (dyld_all_image_addr =3D=3D 0) + darwin_solib_get_all_image_info_addr_at_init (); + + if (dyld_all_image_addr =3D=3D 0) + return; =20 darwin_load_image_infos (); =20 diff --git a/gdb/target.h b/gdb/target.h index e264657..173e60b 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -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, ... */ }; =20