From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20603 invoked by alias); 7 Oct 2003 03:33:47 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 20596 invoked from network); 7 Oct 2003 03:33:46 -0000 Received: from unknown (HELO gateway.sf.frob.com) (64.81.54.130) by sources.redhat.com with SMTP; 7 Oct 2003 03:33:46 -0000 Received: from magilla.sf.frob.com (magilla.sf.frob.com [198.49.250.228]) by gateway.sf.frob.com (Postfix) with ESMTP id CD4D6357B; Mon, 6 Oct 2003 20:33:44 -0700 (PDT) Received: from magilla.sf.frob.com (localhost.localdomain [127.0.0.1]) by magilla.sf.frob.com (8.12.9/8.12.9) with ESMTP id h973XiN2017568; Mon, 6 Oct 2003 20:33:44 -0700 Received: (from roland@localhost) by magilla.sf.frob.com (8.12.9/8.12.9/Submit) id h973XiBG017564; Mon, 6 Oct 2003 20:33:44 -0700 Date: Tue, 07 Oct 2003 03:33:00 -0000 Message-Id: <200310070333.h973XiBG017564@magilla.sf.frob.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit From: Roland McGrath To: Elena Zannoni Cc: gdb-patches@sources.redhat.com Subject: Re: unwind support for Linux 2.6 vsyscall DSO X-Zippy-Says: .. I feel.. JUGULAR.. X-SW-Source: 2003-10/txt/msg00157.txt.bz2 Here is an alternate version of my patch, omitting the Solaris parts. This uses an iterator interface as you requested. I didn't add a utility function but duplicated the code that might be in one. This also works (writes a good NT_AUXV note), but the core file writing additions are now rather clunky, and that code has to be duplicated for Solaris (or factored out). I prefer the first version. Thanks, Roland Index: target.c =================================================================== RCS file: /cvs/src/src/gdb/target.c,v retrieving revision 1.55 diff -b -p -u -r1.55 target.c --- target.c 2 Oct 2003 20:28:30 -0000 1.55 +++ target.c 7 Oct 2003 03:29:27 -0000 @@ -624,6 +624,7 @@ update_current_target (void) INHERIT (to_async, t); INHERIT (to_async_mask_value, t); INHERIT (to_find_memory_regions, t); + INHERIT (to_read_aux_vector, t); INHERIT (to_make_corefile_notes, t); INHERIT (to_get_thread_local_address, t); INHERIT (to_magic, t); @@ -1500,6 +1501,13 @@ static int dummy_find_memory_regions (in return 0; } +/* Error-catcher for target_read_aux_vector */ +static int dummy_read_aux_vector (int (*ignore1) (), void *ignore2) +{ + error ("No target."); + return 0; +} + /* Error-catcher for target_make_corefile_notes */ static char * dummy_make_corefile_notes (bfd *ignore1, int *ignore2) { @@ -1521,6 +1529,7 @@ init_dummy_target (void) dummy_target.to_pid_to_str = normal_pid_to_str; dummy_target.to_stratum = dummy_stratum; dummy_target.to_find_memory_regions = dummy_find_memory_regions; + dummy_target.to_read_aux_vector = dummy_read_aux_vector; dummy_target.to_make_corefile_notes = dummy_make_corefile_notes; dummy_target.to_magic = OPS_MAGIC; } Index: target.h =================================================================== RCS file: /cvs/src/src/gdb/target.h,v retrieving revision 1.41 diff -b -p -u -r1.41 target.h --- target.h 17 Jun 2003 20:28:13 -0000 1.41 +++ target.h 7 Oct 2003 03:29:27 -0000 @@ -322,6 +322,7 @@ struct target_ops int, int, int, void *), void *); + int (*to_read_aux_vector) (int (*) (const void *, void *), void *); char * (*to_make_corefile_notes) (bfd *, int *); /* Return the thread-local address at OFFSET in the @@ -939,6 +940,14 @@ extern void (*target_new_objfile_hook) ( (current_target.to_find_memory_regions) (FUNC, DATA) /* + * Function to read target startup auxilliary vector (ELF-specific). + * Returns a malloc'd buffer of ELF auxv data, and sets *LENP to its size. + */ + +#define target_read_aux_vector(FUNC, DATA) \ + (current_target.to_read_aux_vector) (FUNC, DATA) + +/* * Compose corefile .note section. */ Index: inftarg.c =================================================================== RCS file: /cvs/src/src/gdb/inftarg.c,v retrieving revision 1.18 diff -b -p -u -r1.18 inftarg.c --- inftarg.c 21 Sep 2003 01:26:45 -0000 1.18 +++ inftarg.c 7 Oct 2003 03:29:27 -0000 @@ -628,6 +628,14 @@ inftarg_set_find_memory_regions (int (*f child_ops.to_find_memory_regions = func; } +/* Take over the 'read_aux_vector' vector from inftarg.c. */ +void +inftarg_set_read_aux_vector (int (*func) (int (*) (const void *, void *), + void *)) +{ + child_ops.to_read_aux_vector = func; +} + /* Take over the 'make_corefile_notes' vector from inftarg.c. */ extern void inftarg_set_make_corefile_notes (char * (*func) (bfd *, int *)) Index: linux-proc.c =================================================================== RCS file: /cvs/src/src/gdb/linux-proc.c,v retrieving revision 1.20 diff -b -p -u -r1.20 linux-proc.c --- linux-proc.c 1 Oct 2003 20:36:56 -0000 1.20 +++ linux-proc.c 7 Oct 2003 03:29:27 -0000 @@ -161,6 +161,72 @@ linux_find_memory_regions (int (*func) ( return 0; } +static int +procfs_read_aux_vector (int (*func) (const Elf_Internal_Auxv *, void *), + void *data) +{ + char pathname[MAXPATHLEN]; + union + { + Elf32_External_Auxv av32[20]; + Elf64_External_Auxv av64[10]; + } buf; + int fd, n, ret; + + sprintf (pathname, "/proc/%d/auxv", PIDGET (inferior_ptid)); + fd = open (pathname, O_RDONLY); + if (fd < 0) + return 0; /* XXX Call error here? */ + + ret = 0; + while (1) + { + n = read (fd, &buf, sizeof buf); + if (n <= 0) /* Hit EOF or read error. */ + return 0; + + switch (bfd_arch_bits_per_address (exec_bfd)) + { + default: + break; + + case 32: + { + const Elf32_External_Auxv *av; + for (av = buf.av32; (char *) av < (char *) &buf + n; ++av) + { + Elf_Internal_Auxv elt; + elt.a_type = bfd_get_32 (exec_bfd, av->a_type); + elt.a_val = bfd_get_32 (exec_bfd, av->a_val); + ret = (*func) (&elt, data); + if (ret != 0) + break; + } + continue; + } + case 64: + { + const Elf64_External_Auxv *av; + for (av = buf.av64; (char *) av < (char *) &buf + n; ++av) + { + Elf_Internal_Auxv elt; + elt.a_type = bfd_get_64 (exec_bfd, av->a_type); + elt.a_val = bfd_get_64 (exec_bfd, av->a_val); + ret = (*func) (&elt, data); + if (ret != 0) + break; + } + continue; + } + } + + break; + } + + close (fd); + return ret; +} + /* Function: linux_do_thread_registers * * Records the thread's register state for the corefile note section. @@ -255,6 +321,46 @@ linux_do_registers (bfd *obfd, ptid_t pt return note_data; } +static int +linux_auxv_count (const void *av, void *data) +{ + ++*(int *) data; + return 0; +} + +static int +linux_auxv_reconstruct (const void *internal, void *data) +{ + const Elf_Internal_Auxv *av = internal; + bfd_byte **ptr = data; + + switch (bfd_arch_bits_per_address (exec_bfd)) + { + default: + break; + + case 32: + { + bfd_put_32 (exec_bfd, av->a_type, *ptr); + *ptr += 4; + bfd_put_32 (exec_bfd, av->a_val, *ptr); + *ptr += 4; + break; + } + + case 64: + { + bfd_put_64 (exec_bfd, av->a_type, *ptr); + *ptr += 8; + bfd_put_64 (exec_bfd, av->a_val, *ptr); + *ptr += 8; + break; + } + } + + return 0; +} + /* Function: linux_make_note_section * * Fills the "to_make_corefile_note" target vector. @@ -271,6 +377,7 @@ linux_make_note_section (bfd *obfd, int char psargs[80] = { '\0' }; char *note_data = NULL; ptid_t current_ptid = inferior_ptid; + int auxv_len; if (get_exec_file (0)) { @@ -305,6 +412,19 @@ linux_make_note_section (bfd *obfd, int note_data = thread_args.note_data; } + auxv_len = 0; + target_read_aux_vector (linux_auxv_count, &auxv_len); + if (auxv_len != 0) + { + bfd_byte *auxv, *auxvptr; + auxv = alloca (auxv_len * 2 + * (bfd_arch_bits_per_address (exec_bfd) / 8)); + auxvptr = auxv; + target_read_aux_vector (linux_auxv_reconstruct, &auxvptr); + note_data = elfcore_write_note (obfd, note_data, note_size, + "CORE", NT_AUXV, auxv, auxvptr - auxv); + } + make_cleanup (xfree, note_data); return note_data; } @@ -593,9 +713,11 @@ _initialize_linux_proc (void) { extern void inftarg_set_find_memory_regions (); extern void inftarg_set_make_corefile_notes (); + extern void inftarg_set_read_aux_vector (); inftarg_set_find_memory_regions (linux_find_memory_regions); inftarg_set_make_corefile_notes (linux_make_note_section); + inftarg_set_read_aux_vector (procfs_read_aux_vector); add_info ("proc", linux_info_proc_cmd, "Show /proc process information about any running process.\n\ Index: corelow.c =================================================================== RCS file: /cvs/src/src/gdb/corelow.c,v retrieving revision 1.30 diff -b -p -u -r1.30 corelow.c --- corelow.c 21 Sep 2003 01:26:44 -0000 1.30 +++ corelow.c 7 Oct 2003 03:29:27 -0000 @@ -474,6 +550,69 @@ core_files_info (struct target_ops *t) print_section_info (t, core_bfd); } +static int +core_read_aux_vector (int (*func) (const void *, void *), void *data) +{ + sec_ptr section; + bfd_size_type size; + char *contents; + int ret; + + section = bfd_get_section_by_name (core_bfd, ".auxv"); + if (section == NULL) + return 0; + + size = bfd_section_size (core_bfd, section); + contents = (char *) alloca (size); + if (! bfd_get_section_contents (core_bfd, section, contents, + (file_ptr) 0, size)) + { + warning ("Couldn't read NT_AUXV note in core file."); + return 0; + } + + switch (bfd_arch_bits_per_address (core_bfd)) + { + default: + return 0; + + case 32: + { + Elf32_External_Auxv *av; + for (av = (Elf32_External_Auxv *) contents; + (char *) av < contents + size; + ++av) + { + Elf_Internal_Auxv elt; + elt.a_type = bfd_get_32 (core_bfd, av->a_type); + elt.a_val = bfd_get_32 (core_bfd, av->a_val); + ret = (*func) (&elt, data); + if (ret != 0) + return ret; + } + break; + } + case 64: + { + Elf64_External_Auxv *av; + for (av = (Elf64_External_Auxv *) contents; + (char *) av < contents + size; + ++av) + { + Elf_Internal_Auxv elt; + elt.a_type = bfd_get_64 (core_bfd, av->a_type); + elt.a_val = bfd_get_64 (core_bfd, av->a_val); + ret = (*func) (&elt, data); + if (ret != 0) + return ret; + } + break; + } + } + + return 0; +} + /* If mourn is being called in all the right places, this could be say `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ @@ -520,6 +659,7 @@ init_core_ops (void) core_ops.to_has_memory = 1; core_ops.to_has_stack = 1; core_ops.to_has_registers = 1; + core_ops.to_read_aux_vector = core_read_aux_vector; core_ops.to_magic = OPS_MAGIC; }