Re: [rfa] Attach vsyscall support for GNU/Linux

Daniel Jacobowitz
2004-11-07T21:35:42Z

On Tue, Nov 02, 2004 at 09:28:27AM -0500, Andrew Cagney wrote:
> Can you translate the above into code? At present it's i386 so what
> would I care?

I've checked in this patch after testing on i386-pc-linux-gnu.
Vsyscall support now works on HEAD.

It's been a while since you wrote this, and we're much closer to the
planned release of 6.3. I can move both patches to the branch or hold
them for 6.3.1/6.4; let me know what you'd prefer.

--
Daniel Jacobowitz

2004-11-07 Andrew Cagney <cagney@redhat.com>
Daniel Jacobowitz <dan@debian.org>
Roland McGrath <roland@redhat.com>

* Makefile.in (symfile-mem.o): Update dependencies.
* i386-linux-tdep.c (i386_linux_dwarf_signal_frame_p): New.
(i386_linux_init_abi): Call dwarf2_frame_set_signal_frame_p.
* inf-ptrace.c (inf_ptrace_attach): Call
observer_notify_inferior_created.
* inftarg.c (child_attach): Likewise.
* symfile-mem.c: Include "observer.h", "auxv.h", and "elf/common.h".
(symbol_file_add_from_memory): Take NAME argument. Use it for
the new BFD's filename.
(add_symbol_file_from_memory_command): Update call to
symbol_file_add_from_memory.
(struct symbol_file_add_from_memory_args, add_vsyscall_page)
(symbol_file_add_from_memory_wrapper): New.
(_initialize_symfile_mem): Register add_vsyscall_page as an
inferior_created observer.

Index: gdb/Makefile.in
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/Makefile.in,v
retrieving revision 1.655
diff -u -p -r1.655 Makefile.in
--- gdb/Makefile.in 6 Nov 2004 17:18:10 -0000 1.655
+++ gdb/Makefile.in 7 Nov 2004 17:46:17 -0000
@@ -2619,7 +2619,8 @@ symfile.o: symfile.c $(defs_h) $(bfdlink
$(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \
$(gdb_string_h) $(gdb_stat_h)
symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \
- $(objfiles_h) $(gdbcmd_h) $(target_h) $(value_h) $(symfile_h)
+ $(objfiles_h) $(gdbcmd_h) $(target_h) $(value_h) $(symfile_h) \
+ $(observer_h) $(auxv_h) $(elf_common_h)
symmisc.o: symmisc.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(bfd_h) \
$(symfile_h) $(objfiles_h) $(breakpoint_h) $(command_h) \
$(gdb_obstack_h) $(language_h) $(bcache_h) $(block_h) $(gdb_regex_h) \
Index: gdb/i386-linux-tdep.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/i386-linux-tdep.c,v
retrieving revision 1.41
diff -u -p -r1.41 i386-linux-tdep.c
--- gdb/i386-linux-tdep.c 6 Aug 2004 20:58:28 -0000 1.41
+++ gdb/i386-linux-tdep.c 5 Nov 2004 20:24:29 -0000
@@ -244,6 +244,27 @@ i386_linux_sigtramp_p (struct frame_info
|| strcmp ("__restore_rt", name) == 0);
}

+/* Return one if the unwound PC from NEXT_FRAME is in a signal trampoline
+ which may have DWARF-2 CFI. */
+
+static int
+i386_linux_dwarf_signal_frame_p (struct gdbarch *gdbarch,
+ struct frame_info *next_frame)
+{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+ char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+
+ /* If a vsyscall DSO is in use, the signal trampolines may have these
+ names. */
+ if (name && (strcmp (name, "__kernel_sigreturn") == 0
+ || strcmp (name, "__kernel_rt_sigreturn") == 0))
+ return 1;
+
+ return 0;
+}
+
/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */
#define I386_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 20

@@ -414,6 +435,8 @@ i386_linux_init_abi (struct gdbarch_info

/* GNU/Linux uses the dynamic linker included in the GNU C Library. */
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
+
+ dwarf2_frame_set_signal_frame_p (gdbarch, i386_linux_dwarf_signal_frame_p);
}

/* Provide a prototype to silence -Wmissing-prototypes. */
Index: gdb/inf-ptrace.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/inf-ptrace.c,v
retrieving revision 1.11
diff -u -p -r1.11 inf-ptrace.c
--- gdb/inf-ptrace.c 15 Oct 2004 13:29:33 -0000 1.11
+++ gdb/inf-ptrace.c 5 Nov 2004 20:10:05 -0000
@@ -220,6 +220,10 @@ inf_ptrace_attach (char *args, int from_

inferior_ptid = pid_to_ptid (pid);
push_target (ptrace_ops_hack);
+
+ /* Do this first, before anything has had a chance to query the
+ inferior's symbol table or similar. */
+ observer_notify_inferior_created (&current_target, from_tty);
}

static void
Index: gdb/inftarg.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/inftarg.c,v
retrieving revision 1.34
diff -u -p -r1.34 inftarg.c
--- gdb/inftarg.c 8 Oct 2004 20:29:47 -0000 1.34
+++ gdb/inftarg.c 5 Nov 2004 20:10:05 -0000
@@ -211,6 +211,10 @@ child_attach (char *args, int from_tty)

inferior_ptid = pid_to_ptid (pid);
push_target (&deprecated_child_ops);
+
+ /* Do this first, before anything has had a chance to query the
+ inferior's symbol table or similar. */
+ observer_notify_inferior_created (&current_target, from_tty);
}

#if !defined(CHILD_POST_ATTACH)
Index: gdb/symfile-mem.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/symfile-mem.c,v
retrieving revision 1.3
diff -u -p -r1.3 symfile-mem.c
--- gdb/symfile-mem.c 17 Jul 2004 14:24:07 -0000 1.3
+++ gdb/symfile-mem.c 7 Nov 2004 17:43:57 -0000
@@ -52,13 +52,19 @@
#include "target.h"
#include "value.h"
#include "symfile.h"
+#include "observer.h"
+#include "auxv.h"
+#include "elf/common.h"

/* Read inferior memory at ADDR to find the header of a loaded object file
and read its in-core symbols out of inferior memory. TEMPL is a bfd
- representing the target's format. */
+ representing the target's format. NAME is the name to use for this
+ symbol file in messages; it can be NULL or a malloc-allocated string
+ which will be attached to the BFD. */
static struct objfile *
-symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, int from_tty)
+symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
+ int from_tty)
{
struct objfile *objf;
struct bfd *nbfd;
@@ -75,7 +81,10 @@ symbol_file_add_from_memory (struct bfd
if (nbfd == NULL)
error ("Failed to read a valid object file image from memory.");

- nbfd->filename = xstrdup ("shared object read from target memory");
+ if (name == NULL)
+ nbfd->filename = xstrdup ("shared object read from target memory");
+ else
+ nbfd->filename = name;

if (!bfd_check_format (nbfd, bfd_object))
{
@@ -129,7 +138,73 @@ add_symbol_file_from_memory_command (cha
error ("\
Must use symbol-file or exec-file before add-symbol-file-from-memory.");

- symbol_file_add_from_memory (templ, addr, from_tty);
+ symbol_file_add_from_memory (templ, addr, NULL, from_tty);
+}
+
+/* Arguments for symbol_file_add_from_memory_wrapper. */
+
+struct symbol_file_add_from_memory_args
+{
+ struct bfd *bfd;
+ CORE_ADDR sysinfo_ehdr;
+ char *name;
+ int from_tty;
+};
+
+/* Wrapper function for symbol_file_add_from_memory, for
+ catch_exceptions. */
+
+static int
+symbol_file_add_from_memory_wrapper (struct ui_out *uiout, void *data)
+{
+ struct symbol_file_add_from_memory_args *args = data;
+
+ symbol_file_add_from_memory (args->bfd, args->sysinfo_ehdr, args->name,
+ args->from_tty);
+ return 0;
+}
+
+/* Try to add the symbols for the vsyscall page, if there is one. This function
+ is called via the inferior_created observer. */
+
+static void
+add_vsyscall_page (struct target_ops *target, int from_tty)
+{
+ CORE_ADDR sysinfo_ehdr;
+
+ if (target_auxv_search (target, AT_SYSINFO_EHDR, &sysinfo_ehdr) > 0
+ && sysinfo_ehdr != (CORE_ADDR) 0)
+ {
+ struct bfd *bfd;
+ struct symbol_file_add_from_memory_args args;
+
+ if (core_bfd != NULL)
+ bfd = core_bfd;
+ else if (exec_bfd != NULL)
+ bfd = exec_bfd;
+ else
+ /* FIXME: cagney/2004-05-06: Should not require an existing
+ BFD when trying to create a run-time BFD of the VSYSCALL
+ page in the inferior. Unfortunately that's the current
+ interface so for the moment bail. Introducing a
+ ``bfd_runtime'' (a BFD created using the loaded image) file
+ format should fix this. */
+ {
+ warning ("could not load vsyscall page because no executable was specified");
+ warning ("try using the \"file\" command first");
+ return;
+ }
+ args.bfd = bfd;
+ args.sysinfo_ehdr = sysinfo_ehdr;
+ xasprintf (&args.name, "system-supplied DSO at 0x%s",
+ paddr_nz (sysinfo_ehdr));
+ /* Pass zero for FROM_TTY, because the action of loading the
+ vsyscall DSO was not triggered by the user, even if the user
+ typed "run" at the TTY. */
+ args.from_tty = 0;
+ catch_exceptions (uiout, symbol_file_add_from_memory_wrapper,
+ &args, NULL, RETURN_MASK_ALL);
+ }
}

\f
@@ -143,4 +218,7 @@ Load the symbols out of memory from a dy
Give an expression for the address of the file's shared object file header.",
&cmdlist);

+ /* Want to know of each new inferior so that its vsyscall info can
+ be extracted. */
+ observer_attach_inferior_created (add_vsyscall_page);
}