From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25232 invoked by alias); 7 Oct 2003 01:48:13 -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 25225 invoked from network); 7 Oct 2003 01:48:10 -0000 Received: from unknown (HELO gateway.sf.frob.com) (64.81.54.130) by sources.redhat.com with SMTP; 7 Oct 2003 01:48:10 -0000 Received: from magilla.sf.frob.com (magilla.sf.frob.com [198.49.250.228]) by gateway.sf.frob.com (Postfix) with ESMTP id 8E51A357B; Mon, 6 Oct 2003 18:48:09 -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 h971m8N2011751; Mon, 6 Oct 2003 18:48:08 -0700 Received: (from roland@localhost) by magilla.sf.frob.com (8.12.9/8.12.9/Submit) id h971m8Wd011747; Mon, 6 Oct 2003 18:48:08 -0700 Date: Tue, 07 Oct 2003 01:48:00 -0000 Message-Id: <200310070148.h971m8Wd011747@magilla.sf.frob.com> From: Roland McGrath To: gdb-patches@sources.redhat.com Subject: [PATCH] target_read_aux_vector X-Zippy-Says: Ha ha Ha ha Ha ha Ha Ha Ha Ha -- When will I EVER stop HAVING FUN?!! X-SW-Source: 2003-10/txt/msg00146.txt.bz2 This patch adds target_read_aux_vector to read the auxv information as a whole block (there is no code here that interprets its contents). It also makes ELF core file writing (gcore) use this to produce an NT_AUXV note. I have only tested the linux-proc.c code in actuality, but the procfs.c (Solaris) and corelow.c code is so simple it would be hard for it to be wrong. The function signature used here is a little goofy if you ask me. But I modelled it on target_make_corefile_notes, which is another recent addition and so I assume it is in the style that gdb folk prefer. I would be happy to change the signature if there is a different preference. I made the malloc'd-ness of the returned pointer part of the interface rather than having it call make_cleanup and magically know that's the right scope as the to_make_corefile_notes implementations do. The one way I've tested this is that "gcore" used on Linux 2.6 du jour produces an NT_AUXV note in the core file matching what a kernel-written dump has. The Solaris additions should make it do the same there as well. The core_ops implementation of target_read_aux_vector is not presently used at all, because you can't do gcore when examining a core file. (Incidentally, I think gdb should support that. Doing that and comparing what gdb wrote to the original core file is a good test of both core file reading and core file writing.) It would be used by the tdep code looking for AT_SYSINFO_EHDR, as we have been discussing here. I am not happy that the identical function is duplicated in procfs.c and linux-proc.c; but I did not see any place for common code that is usable for both flavors of /proc filesystem. The to_make_corefile_notes hooks in those two files are close to identical as well. Comments? Thanks, Roland 2003-10-06 Roland McGrath * target.h (struct target_ops): New field `to_read_aux_vector'. (target_read_aux_vector): New macro. * target.c (update_current_target): Do INHERIT for to_read_aux_vector. (dummy_read_aux_vector): New function. (init_dummy_target): Initialize dummy_target.to_read_aux_vector. * inftarg.c (inftarg_set_read_aux_vector): New function. * linux-proc.c (procfs_read_aux_vector): New function. (_initialize_linux_proc): Call inftarg_set_read_aux_vector. (linux_make_note_section): Add an NT_AUXV note. * procfs.c (procfs_read_aux_vector): New function. (init_procfs_ops): Initialize procfs_ops.to_read_aux_vector. (procfs_make_note_section): Add an NT_AUXV note. * sol-thread.c (sol_read_aux_vector): New function. (init_sol_thread_ops): Initialize sol_thread_ops.to_read_aux_vector. * corelow.c (core_read_aux_vector): New function. (init_core_ops): Initialize core_ops.to_read_aux_vector. 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 01:20:30 -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 char *dummy_read_aux_vector (int *ignore1) +{ + error ("No target."); + return NULL; +} + /* 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 01:20:30 -0000 @@ -322,6 +322,7 @@ struct target_ops int, int, int, void *), void *); + char *(*to_read_aux_vector) (int *); 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(LENP) \ + (current_target.to_read_aux_vector) (LENP) + +/* * 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 01:20:30 -0000 @@ -628,6 +628,13 @@ 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 (char *(*func) (int *)) +{ + 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 01:20:31 -0000 @@ -161,6 +161,46 @@ linux_find_memory_regions (int (*func) ( return 0; } +static char * +procfs_read_aux_vector (int *lenp) +{ + char pathname[MAXPATHLEN]; + int fd; + char *buf, *p; + int bufsz, n; + + sprintf (pathname, "/proc/%d/auxv", PIDGET (inferior_ptid)); + fd = open (pathname, O_RDONLY); + if (fd < 0) + return NULL; /* XXX Call error here? */ + + bufsz = 256; + buf = (char *) xmalloc (bufsz); + p = buf; + while (1) + { + n = read (fd, p, buf + bufsz - p); + if (n == 0) /* Hit EOF. */ + { + *lenp = p - buf; + break; + } + if (n < 0) /* Read error. */ + { + xfree (buf); + buf = NULL; + break; + } + bufsz *= 2; + n = p + n - buf; + buf = (char *) xrealloc (buf, bufsz); + p = buf + n; + } + + close (fd); + return buf; +} + /* Function: linux_do_thread_registers * * Records the thread's register state for the corefile note section. @@ -271,6 +311,8 @@ linux_make_note_section (bfd *obfd, int char psargs[80] = { '\0' }; char *note_data = NULL; ptid_t current_ptid = inferior_ptid; + char *auxv; + int auxv_len; if (get_exec_file (0)) { @@ -305,6 +347,14 @@ linux_make_note_section (bfd *obfd, int note_data = thread_args.note_data; } + auxv = target_read_aux_vector (&auxv_len); + if (auxv != NULL) + { + note_data = elfcore_write_note (obfd, note_data, note_size, + "CORE", NT_AUXV, auxv, auxv_len); + xfree (auxv); + } + make_cleanup (xfree, note_data); return note_data; } @@ -593,9 +643,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: procfs.c =================================================================== RCS file: /cvs/src/src/gdb/procfs.c,v retrieving revision 1.48 diff -b -p -u -r1.48 procfs.c --- procfs.c 21 Sep 2003 01:26:45 -0000 1.48 +++ procfs.c 7 Oct 2003 01:20:31 -0000 @@ -139,6 +139,7 @@ static int proc_find_memory_regions (int void *), void *); +static char *procfs_read_aux_vector (int *); static char * procfs_make_note_section (bfd *, int *); static int procfs_can_use_hw_breakpoint (int, int, int); @@ -190,6 +191,7 @@ init_procfs_ops (void) procfs_ops.to_stratum = process_stratum; procfs_ops.to_has_thread_control = tc_schedlock; procfs_ops.to_find_memory_regions = proc_find_memory_regions; + procfs_ops.to_read_aux_vector = procfs_read_aux_vector; procfs_ops.to_make_corefile_notes = procfs_make_note_section; procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint; procfs_ops.to_magic = OPS_MAGIC; @@ -5737,6 +5739,47 @@ proc_untrace_sysexit_cmd (char *args, in proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET); } +char * +procfs_read_aux_vector (int *lenp) +{ + char pathname[MAX_PROC_NAME_SIZE]; + int fd; + char *buf, *p; + int bufsz, n; + + sprintf (pathname, "/proc/%d/auxv", PIDGET (inferior_ptid)); + fd = open_with_retry (pathname, O_RDONLY); + if (fd < 0) + return NULL; /* XXX Call error here? */ + + bufsz = 256; + buf = (char *) xmalloc (bufsz); + p = buf; + while (1) + { + n = read (fd, p, buf + bufsz - p); + if (n == 0) /* Hit EOF. */ + { + *lenp = p - bufsz; + break; + } + if (n < 0) /* Read error. */ + { + xfree (buf); + buf = NULL; + break; + } + bufsz *= 2; + n = p + n - buf; + buf = (char *) xrealloc (buf, bufsz); + p = buf + n; + } + + close (fd); + return buf; +} + + void _initialize_procfs (void) @@ -5851,6 +5894,8 @@ procfs_make_note_section (bfd *obfd, int char *note_data = NULL; char *inf_args; struct procfs_corefile_thread_data thread_args; + char *auxv; + int auxv_len; if (get_exec_file (0)) { @@ -5897,6 +5942,14 @@ procfs_make_note_section (bfd *obfd, int else { note_data = thread_args.note_data; + } + + auxv = target_read_aux_vector (&auxv_len); + if (auxv != NULL) + { + note_data = elfcore_write_note (obfd, note_data, note_size, + "CORE", NT_AUXV, auxv, auxv_len); + xfree (auxv); } make_cleanup (xfree, note_data); 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 01:20:31 -0000 @@ -474,6 +548,30 @@ core_files_info (struct target_ops *t) print_section_info (t, core_bfd); } +static char * +core_read_aux_vector (int *lenp) +{ + sec_ptr section; + bfd_size_type size; + char *contents; + + section = bfd_get_section_by_name (core_bfd, ".auxv"); + if (section == NULL) + return NULL; + + size = bfd_section_size (core_bfd, section); + contents = (char *) xmalloc (size); + if (! bfd_get_section_contents (core_bfd, section, contents, + (file_ptr) 0, size)) + { + xfree (contents); + warning ("Couldn't read NT_AUXV note in core file."); + return NULL; + } + + return contents; +} + /* 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 +618,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; } Index: sol-thread.c =================================================================== RCS file: /cvs/src/src/gdb/sol-thread.c,v retrieving revision 1.38 diff -b -p -u -r1.38 sol-thread.c --- sol-thread.c 21 Sep 2003 01:26:45 -0000 1.38 +++ sol-thread.c 7 Oct 2003 01:28:38 -0000 @@ -1522,6 +1522,12 @@ sol_find_memory_regions (int (*func) (CO } static char * +sol_read_aux_vector (int *auxv_size) +{ + return procfs_ops.to_read_aux_vector (auxv_size); +} + +static char * sol_make_note_section (bfd *obfd, int *note_size) { return procfs_ops.to_make_corefile_notes (obfd, note_size); @@ -1575,6 +1581,7 @@ init_sol_thread_ops (void) sol_thread_ops.to_has_execution = 1; sol_thread_ops.to_has_thread_control = tc_none; sol_thread_ops.to_find_memory_regions = sol_find_memory_regions; + sol_thread_ops.to_read_aux_vector = sol_read_aux_vector; sol_thread_ops.to_make_corefile_notes = sol_make_note_section; sol_thread_ops.to_magic = OPS_MAGIC; }