Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] add-symbol-file-from-memory command
@ 2003-05-20  7:01 Roland McGrath
  0 siblings, 0 replies; 40+ messages in thread
From: Roland McGrath @ 2003-05-20  7:01 UTC (permalink / raw)
  To: gdb-patches

This patch relies on the BFD patch I posted earlier adding the function
bfd_elf_bfd_from_remote_memory.  This adds a user command
add-symbol-file-from-memory, which is like add-symbol-file but takes just
the address of an ELF header in inferior memory (and no other args) instead
of a file name.  

This command may not really be worth having, but it serves to exercise the
underlying function symbol_file_add_from_memory.  That function does the
work of reading symbols and unwind info from the Linux vsyscall DSO.
So please examine that new code.

This makes symfile.c call bfd_elf_bfd_from_remote_memory, which is
implemented in bfd/elf.c and so won't exist if there is no ELF target
backend configured into libbfd.  I couldn't see any obvious place in gdb
that is conditionalized at compile-time on ELF; unless I'm missing
something elfread.c is always built in regardless of the presence of ELF
targets.  Should I not be using this function in this file?


Thanks,
Roland


2003-05-19  Roland McGrath  <roland@redhat.com>

	* symfile.c (symbol_file_add_with_addrs_or_offsets): Take ABFD as
	a new argument.  Call symfile_bfd_open only if passed a null pointer.
	(symbol_file_add, reread_separate_symbols): Update callers.
	(build_addr_info): New function, helper for ...
	(symbol_file_add_from_memory): New function.
	(add_symbol_file_from_memory_command): New function using that.
	(_initialize_symfile): Register it for add-symbol-file-from-memory.
	* symfile.h (symbol_file_add_from_memory): Declare it.

Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.93.6.1
diff -B -p -u -r1.93.6.1 symfile.c
--- symfile.c	18 May 2003 09:44:22 -0000	1.93.6.1
+++ symfile.c	20 May 2003 00:13:39 -0000
@@ -834,6 +834,10 @@ new_symfile_objfile (struct objfile *obj
    NAME is the file name (which will be tilde-expanded and made
    absolute herein) (but we don't free or modify NAME itself).
 
+   If ABFD is not null, it's already open and should be used instead of
+   opening the file by name.  This BFD will be closed on error, and
+   is always consumed by this function.
+
    FROM_TTY says how verbose to be.
 
    MAINLINE specifies whether this is the main symbol file, or whether
@@ -846,7 +850,7 @@ new_symfile_objfile (struct objfile *obj
    Upon success, returns a pointer to the objfile that was added.
    Upon failure, jumps back to command level (never returns). */
 static struct objfile *
-symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
+symbol_file_add_with_addrs_or_offsets (char *name, bfd *abfd, int from_tty,
                                        struct section_addr_info *addrs,
                                        struct section_offsets *offsets,
                                        int num_offsets,
@@ -855,16 +859,19 @@ symbol_file_add_with_addrs_or_offsets (c
   struct objfile *objfile;
   struct partial_symtab *psymtab;
   char *debugfile;
-  bfd *abfd;
   struct section_addr_info orig_addrs;
-  
+  struct cleanup *old_chain;
+
   if (addrs)
     orig_addrs = *addrs;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
 
-  abfd = symfile_bfd_open (name);
+  if (abfd == NULL)
+    abfd = symfile_bfd_open (name);
+
+  old_chain = make_cleanup_bfd_close (abfd);
 
   if ((have_full_symbols () || have_partial_symbols ())
       && mainline
@@ -873,6 +880,7 @@ symbol_file_add_with_addrs_or_offsets (c
     error ("Not confirmed.");
 
   objfile = allocate_objfile (abfd, flags);
+  discard_cleanups (old_chain);
 
   /* If the objfile uses a mapped symbol file, and we have a psymtab for
      it, then skip reading any symbols at this time. */
@@ -998,7 +1006,8 @@ struct objfile *
 symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
 		 int mainline, int flags)
 {
-  return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0, 
+  return symbol_file_add_with_addrs_or_offsets (name, NULL, from_tty,
+						addrs, 0, 0,
                                                 mainline, flags);
 }
 
@@ -1848,6 +1857,102 @@ add_shared_symbol_files_command (char *a
 #endif
 }
 \f
+/* Helper function passed to bfd_map_over_sections.  */
+static void
+build_addr_info (bfd *abfd, asection *sectp, void *info)
+{
+  struct section_addr_info *const sai = info;
+  unsigned int i = 0;
+
+  if ((bfd_get_section_flags (abfd, sectp) & (SEC_ALLOC|SEC_LOAD)) == 0)
+    return;
+
+  while (sai->other[i++].name != NULL)
+    if (i == MAX_SECTIONS)
+      return;
+
+  sai->other[i].addr = bfd_get_section_vma (abfd, sectp);
+  sai->other[i].name = (char *) bfd_get_section_name (abfd, sectp);
+  sai->other[i].sectindex = sectp->index;
+}
+
+/* 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.  */
+struct objfile *
+symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr, int from_tty)
+{
+  struct objfile *objf;
+  bfd *nbfd;
+  bfd_vma loadbase;
+  struct section_addr_info sai;
+  unsigned int i;
+
+  if (from_tty)
+    {
+      if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
+	error ("add-symbol-file-from-memory not supported for this target");
+    }
+  else
+    gdb_assert (bfd_get_flavour (templ) == bfd_target_elf_flavour);
+
+  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
+					 target_read_memory);
+  if (nbfd == NULL)
+    {
+      if (from_tty)
+	error ("Failed to read a valid object file image from memory.");
+      return NULL;
+    }
+
+  if (!bfd_check_format (nbfd, bfd_object))
+    {
+      /* FIXME: should be checking for errors from bfd_close (for one thing,
+         on error it does not free all the storage associated with the
+         bfd).  */
+      bfd_close (nbfd);
+      if (from_tty)
+	error ("Got object file from memory but can't read symbols: %s.",
+	       bfd_errmsg (bfd_get_error ()));
+      return NULL;
+    }
+
+  memset (&sai, 0, sizeof sai);
+  bfd_map_over_sections (nbfd, build_addr_info, &sai);
+  for (i = 0; i < MAX_SECTIONS && sai.other[i].name != NULL; ++i)
+    sai.other[i].addr += loadbase;
+
+  objf = symbol_file_add_with_addrs_or_offsets ("<in-memory>", nbfd, from_tty,
+						&sai, NULL, 0, 0, 0);
+
+  reinit_frame_cache ();	/* ??? */
+
+  return objf;
+}
+
+static void
+add_symbol_file_from_memory_command (char *args, int from_tty)
+{
+  CORE_ADDR addr;
+  bfd *templ;
+
+  if (args == NULL)
+    error ("add-symbol-file-from-memory requires an expression argument");
+
+  addr = parse_and_eval_address (args);
+
+  /* We need some representative bfd to know the target we are looking at.  */
+  if (symfile_objfile != NULL)
+    templ = symfile_objfile->obfd;
+  else
+    templ = exec_bfd;
+  if (templ == NULL)
+    error ("\
+Must use symbol-file or exec-file before add-symbol-file-from-memory.");
+
+  (void) symbol_file_add_from_memory (templ, addr, from_tty);
+}
+\f
 /* Re-read symbols if a symbol-file has changed.  */
 void
 reread_symbols (void)
Index: symfile.h
===================================================================
RCS file: /cvs/src/src/gdb/symfile.h,v
retrieving revision 1.20.2.1
diff -B -p -u -r1.20.2.1 symfile.h
--- symfile.h	18 May 2003 09:44:23 -0000	1.20.2.1
+++ symfile.h	20 May 2003 00:13:39 -0000
@@ -297,6 +297,12 @@ extern CORE_ADDR symbol_overlayed_addres
 
 /* Load symbols from a file. */
 extern void symbol_file_add_main (char *args, int from_tty);
+
+/* 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.  */
+extern struct objfile *symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr,
+						    int from_tty);
 
 /* Clear GDB symbol tables. */
 extern void symbol_file_clear (int from_tty);


^ permalink raw reply	[flat|nested] 40+ messages in thread
* [PATCH] add-symbol-file-from-memory command
@ 2003-10-03  4:27 Roland McGrath
  2003-10-03 21:41 ` Jim Blandy
  0 siblings, 1 reply; 40+ messages in thread
From: Roland McGrath @ 2003-10-03  4:27 UTC (permalink / raw)
  To: gdb-patches


I posted this originally back in May, and got no response whatsoever.  I've
updated the patch to work with current mainline gdb and tested it again.  I
hope there will be some response this time.  This new user command is not
important, but this code needs review as it will form part of the support
for backtraces from system calls to work on Linux 2.6 kernels.

This adds a user command add-symbol-file-from-memory, which is like
add-symbol-file but takes just the address of an ELF header in inferior
memory (and no other args) instead of a file name.

This command may not really be worth having, but it serves to exercise the
underlying function symbol_file_add_from_memory.  That function does the
work of reading symbols and unwind info from the Linux vsyscall DSO.
So please examine that new code.

This makes symfile.c call bfd_elf_bfd_from_remote_memory, which is
implemented in bfd/elf.c and so won't exist if there is no ELF target
backend configured into libbfd.  I couldn't see any obvious place in gdb
that is conditionalized at compile-time on ELF; unless I'm missing
something elfread.c is always built in regardless of the presence of ELF
targets.  Should I not be using this function in this file?


2003-10-02  Roland McGrath  <roland@redhat.com>

	* symfile.c (symbol_file_add_with_addrs_or_offsets): Take ABFD as
	a new argument.  Call symfile_bfd_open only if passed a null pointer.
	(symbol_file_add, reread_separate_symbols): Update callers.
	(build_addr_info): New function, helper for ...
	(symbol_file_add_from_memory): New function.
	(add_symbol_file_from_memory_command): New function using that.
	(_initialize_symfile): Register it for add-symbol-file-from-memory.
	* symfile.h (symbol_file_add_from_memory): Declare it.


Thanks,
Roland


Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.109
diff -p -u -r1.109 symfile.c
--- symfile.c	21 Sep 2003 01:26:45 -0000	1.109
+++ symfile.c	3 Oct 2003 03:21:22 -0000
@@ -813,6 +813,10 @@ new_symfile_objfile (struct objfile *obj
    NAME is the file name (which will be tilde-expanded and made
    absolute herein) (but we don't free or modify NAME itself).
 
+   If ABFD is not null, it's already open and should be used instead of
+   opening the file by name.  This BFD will be closed on error, and
+   is always consumed by this function.
+
    FROM_TTY says how verbose to be.
 
    MAINLINE specifies whether this is the main symbol file, or whether
@@ -825,7 +829,7 @@ new_symfile_objfile (struct objfile *obj
    Upon success, returns a pointer to the objfile that was added.
    Upon failure, jumps back to command level (never returns). */
 static struct objfile *
-symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
+symbol_file_add_with_addrs_or_offsets (char *name, bfd *abfd, int from_tty,
                                        struct section_addr_info *addrs,
                                        struct section_offsets *offsets,
                                        int num_offsets,
@@ -834,14 +838,16 @@ symbol_file_add_with_addrs_or_offsets (c
   struct objfile *objfile;
   struct partial_symtab *psymtab;
   char *debugfile;
-  bfd *abfd;
   struct section_addr_info *orig_addrs;
   struct cleanup *my_cleanups;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
 
-  abfd = symfile_bfd_open (name);
+  if (abfd == NULL)
+    abfd = symfile_bfd_open (name);
+
+  my_cleanups = make_cleanup_bfd_close (abfd);
 
   if ((have_full_symbols () || have_partial_symbols ())
       && mainline
@@ -850,6 +856,7 @@ symbol_file_add_with_addrs_or_offsets (c
     error ("Not confirmed.");
 
   objfile = allocate_objfile (abfd, flags);
+  discard_cleanups (my_cleanups);
 
   orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd));
   my_cleanups = make_cleanup (xfree, orig_addrs);
@@ -987,7 +994,8 @@ struct objfile *
 symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
 		 int mainline, int flags)
 {
-  return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0, 
+  return symbol_file_add_with_addrs_or_offsets (name, NULL, from_tty,
+						addrs, 0, 0,
                                                 mainline, flags);
 }
 
@@ -1845,6 +1853,103 @@ add_shared_symbol_files_command (char *a
 #endif
 }
 \f
+/* Helper function passed to bfd_map_over_sections.  */
+static void
+build_addr_info (bfd *abfd, asection *sectp, void *info)
+{
+  struct section_addr_info *const sai = info;
+  unsigned int i = 0;
+
+  if ((bfd_get_section_flags (abfd, sectp) & (SEC_ALLOC|SEC_LOAD)) == 0)
+    return;
+
+  while (sai->other[i++].name != NULL)
+    if (i == sai->num_sections)
+      return;
+
+  sai->other[i].addr = bfd_get_section_vma (abfd, sectp);
+  sai->other[i].name = (char *) bfd_get_section_name (abfd, sectp);
+  sai->other[i].sectindex = sectp->index;
+}
+
+/* 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.  */
+struct objfile *
+symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr, int from_tty)
+{
+  struct objfile *objf;
+  bfd *nbfd;
+  bfd_vma loadbase;
+  struct section_addr_info *sai;
+  unsigned int i;
+
+  if (from_tty)
+    {
+      if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
+	error ("add-symbol-file-from-memory not supported for this target");
+    }
+  else
+    gdb_assert (bfd_get_flavour (templ) == bfd_target_elf_flavour);
+
+  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
+					 target_read_memory);
+  if (nbfd == NULL)
+    {
+      if (from_tty)
+	error ("Failed to read a valid object file image from memory.");
+      return NULL;
+    }
+
+  if (!bfd_check_format (nbfd, bfd_object))
+    {
+      /* FIXME: should be checking for errors from bfd_close (for one thing,
+         on error it does not free all the storage associated with the
+         bfd).  */
+      bfd_close (nbfd);
+      if (from_tty)
+	error ("Got object file from memory but can't read symbols: %s.",
+	       bfd_errmsg (bfd_get_error ()));
+      return NULL;
+    }
+
+  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
+  make_cleanup (xfree, sai);
+  bfd_map_over_sections (nbfd, build_addr_info, sai);
+  for (i = 0; i < sai->num_sections && sai->other[i].name != NULL; ++i)
+    sai->other[i].addr += loadbase;
+
+  objf = symbol_file_add_with_addrs_or_offsets ("<in-memory>", nbfd, from_tty,
+						sai, NULL, 0, 0, 0);
+
+  reinit_frame_cache ();	/* ??? */
+
+  return objf;
+}
+
+static void
+add_symbol_file_from_memory_command (char *args, int from_tty)
+{
+  CORE_ADDR addr;
+  bfd *templ;
+
+  if (args == NULL)
+    error ("add-symbol-file-from-memory requires an expression argument");
+
+  addr = parse_and_eval_address (args);
+
+  /* We need some representative bfd to know the target we are looking at.  */
+  if (symfile_objfile != NULL)
+    templ = symfile_objfile->obfd;
+  else
+    templ = exec_bfd;
+  if (templ == NULL)
+    error ("\
+Must use symbol-file or exec-file before add-symbol-file-from-memory.");
+
+  (void) symbol_file_add_from_memory (templ, addr, from_tty);
+}
+\f
 /* Re-read symbols if a symbol-file has changed.  */
 void
 reread_symbols (void)
@@ -2104,7 +2209,7 @@ reread_separate_symbols (struct objfile 
          Preserve the flags from objfile that make sense.  */
       objfile->separate_debug_objfile
         = (symbol_file_add_with_addrs_or_offsets
-           (debug_file,
+           (debug_file, NULL,
             info_verbose, /* from_tty: Don't override the default. */
             0, /* No addr table.  */
             objfile->section_offsets, objfile->num_sections,
@@ -2137,7 +2242,7 @@ add_filename_language (char *ext, enum l
@@ -3605,6 +3710,13 @@ with the text.  SECT is a section name t
 	       &cmdlist);
   set_cmd_completer (c, filename_completer);
 
+  c = add_cmd ("add-symbol-file-from-memory", class_files,
+	       add_symbol_file_from_memory_command,
+	       "Usage: add-symbol-file-from-memory ADDR\n\
+Load the symbols out of memory from a dynamically loaded object file.\n\
+ADDR is the starting address of the file's shared object file header.",
+	       &cmdlist);
+
   c = add_cmd ("add-shared-symbol-files", class_files,
 	       add_shared_symbol_files_command,
    "Load the symbols from shared objects in the dynamic linker's link map.",
Index: symfile.h
===================================================================
RCS file: /cvs/src/src/gdb/symfile.h,v
retrieving revision 1.25
diff -p -u -r1.25 symfile.h
--- symfile.h	11 Sep 2003 19:49:19 -0000	1.25
+++ symfile.h	3 Oct 2003 03:21:22 -0000
@@ -306,6 +306,12 @@ extern CORE_ADDR symbol_overlayed_addres
 /* Load symbols from a file.  */
 extern void symbol_file_add_main (char *args, int from_tty);
 
+/* 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.  */
+extern struct objfile *symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr,
+						    int from_tty);
+
 /* Clear GDB symbol tables.  */
 extern void symbol_file_clear (int from_tty);
 


^ permalink raw reply	[flat|nested] 40+ messages in thread
* [PATCH] add-symbol-file-from-memory command
@ 2004-02-02  3:38 Roland McGrath
  2004-02-02  4:06 ` Daniel Jacobowitz
  2004-02-02  6:19 ` Eli Zaretskii
  0 siblings, 2 replies; 40+ messages in thread
From: Roland McGrath @ 2004-02-02  3:38 UTC (permalink / raw)
  To: gdb-patches

This patch hasn't changed since the last time I posted it.  But I'm hoping
that it will be approved this time.  This support (the underlying function,
not the user command) is the last nontrivial piece required for backtraces
from system calls to work right with vanilla Linux 2.6 kernels.  The only
objections previously were not apropos, and noone said anything about the
content of the code itself.  If there is valid cause not to put this in
now, I hope I can see it stated clearly.

The last time around, some said bfd_elf_bfd_from_remote_memory function was
"in flux" or "a work in progress".  That function is fine as it is in BFD
and has sat there without change for a long time.  If anyone intends to
change its calling convention, updating gdb to suit will be at most three
minutes work.  Since the current BFD code was approved for commit as it is,
I can't see how speculations about possible future changes there warrant
holding up this gdb change now.

I've made fresh diffs here, after testing this code with today's mainline
gdb.  It still works just fine.  


Thanks,
Roland


2003-10-02  Roland McGrath  <roland@redhat.com>

	* symfile.c (symbol_file_add_with_addrs_or_offsets): Take ABFD as
	a new argument.  Call symfile_bfd_open only if passed a null pointer.
	(symbol_file_add, reread_separate_symbols): Update callers.
	(build_addr_info): New function, helper for ...
	(symbol_file_add_from_memory): New function.
	(add_symbol_file_from_memory_command): New function using that.
	(_initialize_symfile): Register it for add-symbol-file-from-memory.
	* symfile.h (symbol_file_add_from_memory): Declare it.

Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.117
diff -b -p -u -r1.117 symfile.c
--- symfile.c	23 Jan 2004 17:56:46 -0000	1.117
+++ symfile.c	2 Feb 2004 03:23:23 -0000
@@ -799,6 +799,10 @@ new_symfile_objfile (struct objfile *obj
    NAME is the file name (which will be tilde-expanded and made
    absolute herein) (but we don't free or modify NAME itself).
 
+   If ABFD is not null, it's already open and should be used instead of
+   opening the file by name.  This BFD will be closed on error, and
+   is always consumed by this function.
+
    FROM_TTY says how verbose to be.
 
    MAINLINE specifies whether this is the main symbol file, or whether
@@ -811,7 +815,7 @@ new_symfile_objfile (struct objfile *obj
    Upon success, returns a pointer to the objfile that was added.
    Upon failure, jumps back to command level (never returns). */
 static struct objfile *
-symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
+symbol_file_add_with_addrs_or_offsets (char *name, bfd *abfd, int from_tty,
                                        struct section_addr_info *addrs,
                                        struct section_offsets *offsets,
                                        int num_offsets,
@@ -820,15 +824,17 @@ symbol_file_add_with_addrs_or_offsets (c
   struct objfile *objfile;
   struct partial_symtab *psymtab;
   char *debugfile;
-  bfd *abfd;
   struct section_addr_info *orig_addrs;
   struct cleanup *my_cleanups;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
 
+  if (abfd == NULL)
   abfd = symfile_bfd_open (name);
 
+  my_cleanups = make_cleanup_bfd_close (abfd);
+
   if ((have_full_symbols () || have_partial_symbols ())
       && mainline
       && from_tty
@@ -836,6 +842,7 @@ symbol_file_add_with_addrs_or_offsets (c
     error ("Not confirmed.");
 
   objfile = allocate_objfile (abfd, flags);
+  discard_cleanups (my_cleanups);
 
   orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd));
   my_cleanups = make_cleanup (xfree, orig_addrs);
@@ -952,7 +959,8 @@ struct objfile *
 symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
 		 int mainline, int flags)
 {
-  return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0, 
+  return symbol_file_add_with_addrs_or_offsets (name, NULL, from_tty,
+						addrs, 0, 0,
                                                 mainline, flags);
 }
 
@@ -1802,6 +1810,106 @@ add_shared_symbol_files_command (char *a
 #endif
 }
 \f
+/* Helper function passed to bfd_map_over_sections.  */
+static void
+build_addr_info (bfd *abfd, asection *sectp, void *info)
+{
+  struct section_addr_info *const sai = info;
+  unsigned int i = 0;
+
+  if ((bfd_get_section_flags (abfd, sectp) & (SEC_ALLOC|SEC_LOAD)) == 0)
+    return;
+
+  while (sai->other[i++].name != NULL)
+    if (i == sai->num_sections)
+      return;
+
+  sai->other[i].addr = bfd_get_section_vma (abfd, sectp);
+  sai->other[i].name = (char *) bfd_get_section_name (abfd, sectp);
+  sai->other[i].sectindex = sectp->index;
+}
+
+/* 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.  */
+struct objfile *
+symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr, int from_tty)
+{
+  struct objfile *objf;
+  bfd *nbfd;
+  bfd_vma loadbase;
+  struct section_addr_info *sai;
+  unsigned int i;
+
+  if (from_tty)
+    {
+      if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
+	error ("add-symbol-file-from-memory not supported for this target");
+    }
+  else
+    gdb_assert (bfd_get_flavour (templ) == bfd_target_elf_flavour);
+
+  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
+					 target_read_memory);
+  if (nbfd == NULL)
+    {
+      if (from_tty)
+	error ("Failed to read a valid object file image from memory.");
+      return NULL;
+    }
+
+  nbfd->filename = xstrdup ("shared object read from target memory");
+
+  if (!bfd_check_format (nbfd, bfd_object))
+    {
+      /* FIXME: should be checking for errors from bfd_close (for one thing,
+         on error it does not free all the storage associated with the
+         bfd).  */
+      bfd_close (nbfd);
+      if (from_tty)
+	error ("Got object file from memory but can't read symbols: %s.",
+	       bfd_errmsg (bfd_get_error ()));
+      return NULL;
+    }
+
+  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
+  make_cleanup (xfree, sai);
+  bfd_map_over_sections (nbfd, build_addr_info, sai);
+  for (i = 0; i < sai->num_sections && sai->other[i].name != NULL; ++i)
+    sai->other[i].addr += loadbase;
+
+  objf = symbol_file_add_with_addrs_or_offsets ((char *) nbfd->filename, nbfd,
+						from_tty, sai, NULL, 0, 0,
+						OBJF_SHARED);
+
+  reinit_frame_cache ();	/* ??? */
+
+  return objf;
+}
+
+static void
+add_symbol_file_from_memory_command (char *args, int from_tty)
+{
+  CORE_ADDR addr;
+  bfd *templ;
+
+  if (args == NULL)
+    error ("add-symbol-file-from-memory requires an expression argument");
+
+  addr = parse_and_eval_address (args);
+
+  /* We need some representative bfd to know the target we are looking at.  */
+  if (symfile_objfile != NULL)
+    templ = symfile_objfile->obfd;
+  else
+    templ = exec_bfd;
+  if (templ == NULL)
+    error ("\
+Must use symbol-file or exec-file before add-symbol-file-from-memory.");
+
+  (void) symbol_file_add_from_memory (templ, addr, from_tty);
+}
+\f
 /* Re-read symbols if a symbol-file has changed.  */
 void
 reread_symbols (void)
@@ -2063,7 +2171,7 @@ reread_separate_symbols (struct objfile 
          Preserve the flags from objfile that make sense.  */
       objfile->separate_debug_objfile
         = (symbol_file_add_with_addrs_or_offsets
-           (debug_file,
+           (debug_file, NULL,
             info_verbose, /* from_tty: Don't override the default. */
             0, /* No addr table.  */
             objfile->section_offsets, objfile->num_sections,
@@ -3566,6 +3674,13 @@ with the text.  SECT is a section name t
 	       &cmdlist);
   set_cmd_completer (c, filename_completer);
 
+  c = add_cmd ("add-symbol-file-from-memory", class_files,
+	       add_symbol_file_from_memory_command,
+	       "Usage: add-symbol-file-from-memory ADDR\n\
+Load the symbols out of memory from a dynamically loaded object file.\n\
+ADDR is the starting address of the file's shared object file header.",
+	       &cmdlist);
+
   c = add_cmd ("add-shared-symbol-files", class_files,
 	       add_shared_symbol_files_command,
    "Load the symbols from shared objects in the dynamic linker's link map.",
Index: symfile.h
===================================================================
RCS file: /cvs/src/src/gdb/symfile.h,v
retrieving revision 1.25
diff -b -p -u -r1.25 symfile.h
--- symfile.h	11 Sep 2003 19:49:19 -0000	1.25
+++ symfile.h	2 Feb 2004 03:23:23 -0000
@@ -306,6 +306,12 @@ extern CORE_ADDR symbol_overlayed_addres
 /* Load symbols from a file.  */
 extern void symbol_file_add_main (char *args, int from_tty);
 
+/* 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.  */
+extern struct objfile *symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr,
+						    int from_tty);
+
 /* Clear GDB symbol tables.  */
 extern void symbol_file_clear (int from_tty);
 


^ permalink raw reply	[flat|nested] 40+ messages in thread
* [PATCH] add-symbol-file-from-memory command
@ 2004-02-12  0:34 Roland McGrath
  2004-02-13 15:54 ` Andrew Cagney
  0 siblings, 1 reply; 40+ messages in thread
From: Roland McGrath @ 2004-02-12  0:34 UTC (permalink / raw)
  To: gdb-patches

I've cleaned up some nits that Daniel pointed out.  This is the current
version of my add-symbol-file-from-memory patch.  I've tested it and it
works with today's mainline gdb.  Are there any remaining problems people
see with this code?  Can it go in?


Thanks,
Roland


2004-02-11  Roland McGrath  <roland@redhat.com>

	* symfile.c (symbol_file_add_with_addrs_or_offsets): Take ABFD as
	a new argument.  Call symfile_bfd_open only if passed a null pointer.
	(symbol_file_add, reread_separate_symbols): Update callers.
	(build_addr_info): New function, helper for ...
	(symbol_file_add_from_memory): New function.
	(add_symbol_file_from_memory_command): New function using that.
	(_initialize_symfile): Register it for add-symbol-file-from-memory.
	* symfile.h (symbol_file_add_from_memory): Declare it.

Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.121
diff -p -u -r1.121 symfile.c
--- symfile.c	9 Feb 2004 23:50:55 -0000	1.121
+++ symfile.c	11 Feb 2004 21:02:31 -0000
@@ -799,6 +799,10 @@ new_symfile_objfile (struct objfile *obj
    NAME is the file name (which will be tilde-expanded and made
    absolute herein) (but we don't free or modify NAME itself).
 
+   If ABFD is not null, it's already open and should be used instead of
+   opening the file by name.  This BFD will be closed on error, and
+   is always consumed by this function.
+
    FROM_TTY says how verbose to be.
 
    MAINLINE specifies whether this is the main symbol file, or whether
@@ -811,7 +815,7 @@ new_symfile_objfile (struct objfile *obj
    Upon success, returns a pointer to the objfile that was added.
    Upon failure, jumps back to command level (never returns). */
 static struct objfile *
-symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
+symbol_file_add_with_addrs_or_offsets (char *name, bfd *abfd, int from_tty,
                                        struct section_addr_info *addrs,
                                        struct section_offsets *offsets,
                                        int num_offsets,
@@ -820,14 +824,16 @@ symbol_file_add_with_addrs_or_offsets (c
   struct objfile *objfile;
   struct partial_symtab *psymtab;
   char *debugfile;
-  bfd *abfd;
   struct section_addr_info *orig_addrs;
   struct cleanup *my_cleanups;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
 
-  abfd = symfile_bfd_open (name);
+  if (abfd == NULL)
+    abfd = symfile_bfd_open (name);
+
+  my_cleanups = make_cleanup_bfd_close (abfd);
 
   if ((have_full_symbols () || have_partial_symbols ())
       && mainline
@@ -836,6 +842,7 @@ symbol_file_add_with_addrs_or_offsets (c
     error ("Not confirmed.");
 
   objfile = allocate_objfile (abfd, flags);
+  discard_cleanups (my_cleanups);
 
   orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd));
   my_cleanups = make_cleanup (xfree, orig_addrs);
@@ -952,7 +959,8 @@ struct objfile *
 symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
 		 int mainline, int flags)
 {
-  return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0, 
+  return symbol_file_add_with_addrs_or_offsets (name, NULL, from_tty,
+						addrs, 0, 0,
                                                 mainline, flags);
 }
 
@@ -1802,6 +1810,88 @@ add_shared_symbol_files_command (char *a
 #endif
 }
 \f
+/* 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.  */
+struct objfile *
+symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr, int from_tty)
+{
+  struct objfile *objf;
+  bfd *nbfd;
+  asection *sec;
+  bfd_vma loadbase;
+  struct section_addr_info *sai;
+  unsigned int i;
+
+  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
+    error ("add-symbol-file-from-memory not supported for this target");
+
+  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
+					 target_read_memory);
+  if (nbfd == NULL)
+    {
+      error ("Failed to read a valid object file image from memory.");
+      return NULL;
+    }
+
+  nbfd->filename = xstrdup ("shared object read from target memory");
+
+  if (!bfd_check_format (nbfd, bfd_object))
+    {
+      /* FIXME: should be checking for errors from bfd_close (for one thing,
+         on error it does not free all the storage associated with the
+         bfd).  */
+      bfd_close (nbfd);
+      error ("Got object file from memory but can't read symbols: %s.",
+	     bfd_errmsg (bfd_get_error ()));
+      return NULL;
+    }
+
+  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
+  make_cleanup (xfree, sai);
+  i = 0;
+  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
+    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
+      {
+	sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
+	sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
+	sai->other[i].sectindex = sec->index;
+	++i;
+      }
+
+  objf = symbol_file_add_with_addrs_or_offsets ((char *) nbfd->filename, nbfd,
+						from_tty, sai, NULL, 0, 0,
+						OBJF_SHARED);
+
+  /* This might change our ideas about frames already looked at.  */
+  reinit_frame_cache ();
+
+  return objf;
+}
+
+static void
+add_symbol_file_from_memory_command (char *args, int from_tty)
+{
+  CORE_ADDR addr;
+  bfd *templ;
+
+  if (args == NULL)
+    error ("add-symbol-file-from-memory requires an expression argument");
+
+  addr = parse_and_eval_address (args);
+
+  /* We need some representative bfd to know the target we are looking at.  */
+  if (symfile_objfile != NULL)
+    templ = symfile_objfile->obfd;
+  else
+    templ = exec_bfd;
+  if (templ == NULL)
+    error ("\
+Must use symbol-file or exec-file before add-symbol-file-from-memory.");
+
+  (void) symbol_file_add_from_memory (templ, addr, from_tty);
+}
+\f
 /* Re-read symbols if a symbol-file has changed.  */
 void
 reread_symbols (void)
@@ -3561,6 +3651,13 @@ with the text.  SECT is a section name t
 	       &cmdlist);
   set_cmd_completer (c, filename_completer);
 
+  c = add_cmd ("add-symbol-file-from-memory", class_files,
+	       add_symbol_file_from_memory_command,
+	       "\
+Load the symbols out of memory from a dynamically loaded object file.\n\
+Give an expression for the address of the file's shared object file header.",
+	       &cmdlist);
+
   c = add_cmd ("add-shared-symbol-files", class_files,
 	       add_shared_symbol_files_command,
    "Load the symbols from shared objects in the dynamic linker's link map.",
Index: symfile.h
===================================================================
RCS file: /cvs/src/src/gdb/symfile.h,v
retrieving revision 1.26
diff -p -u -r1.26 symfile.h
--- symfile.h	7 Feb 2004 23:13:47 -0000	1.26
+++ symfile.h	11 Feb 2004 21:02:31 -0000
@@ -306,6 +306,12 @@ extern CORE_ADDR symbol_overlayed_addres
 /* Load symbols from a file.  */
 extern void symbol_file_add_main (char *args, int from_tty);
 
+/* 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.  */
+extern struct objfile *symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr,
+						    int from_tty);
+
 /* Clear GDB symbol tables.  */
 extern void symbol_file_clear (int from_tty);
 


^ permalink raw reply	[flat|nested] 40+ messages in thread
* [PATCH] add-symbol-file-from-memory command
@ 2004-04-08 20:47 Roland McGrath
  2004-04-08 22:13 ` Jim Blandy
  0 siblings, 1 reply; 40+ messages in thread
From: Roland McGrath @ 2004-04-08 20:47 UTC (permalink / raw)
  To: gdb-patches

I updated my tree and made a new diff for add-symbol-file-from-memory,
though there were no conflicts to resolve so it's not materially different
from the last version of this patch I posted.  It still works with today's
gdb.  Several people have looked at this code before.  It just needs
authoritative approval to go in.  If anyone has any reservations, I haven't
heard them articulated.  As I've mentioned before, the new command itself
is not the motivation for the new function.  It's the final piece of
necessary infrastructure for vsyscall DSO support for Linux targets.
(After this, the only thing needed is the glue to check for AT_SYSINFO at
the right time.)


Thanks,
Roland



Index: gdb/symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.124
diff -p -u -r1.124 symfile.c
--- gdb/symfile.c	28 Feb 2004 18:04:37 -0000	1.124
+++ gdb/symfile.c	8 Apr 2004 20:31:27 -0000
@@ -764,6 +764,10 @@ new_symfile_objfile (struct objfile *obj
    NAME is the file name (which will be tilde-expanded and made
    absolute herein) (but we don't free or modify NAME itself).
 
+   If ABFD is not null, it's already open and should be used instead of
+   opening the file by name.  This BFD will be closed on error, and
+   is always consumed by this function.
+
    FROM_TTY says how verbose to be.
 
    MAINLINE specifies whether this is the main symbol file, or whether
@@ -776,7 +780,7 @@ new_symfile_objfile (struct objfile *obj
    Upon success, returns a pointer to the objfile that was added.
    Upon failure, jumps back to command level (never returns). */
 static struct objfile *
-symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
+symbol_file_add_with_addrs_or_offsets (char *name, bfd *abfd, int from_tty,
                                        struct section_addr_info *addrs,
                                        struct section_offsets *offsets,
                                        int num_offsets,
@@ -785,14 +789,16 @@ symbol_file_add_with_addrs_or_offsets (c
   struct objfile *objfile;
   struct partial_symtab *psymtab;
   char *debugfile;
-  bfd *abfd;
   struct section_addr_info *orig_addrs;
   struct cleanup *my_cleanups;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
 
-  abfd = symfile_bfd_open (name);
+  if (abfd == NULL)
+    abfd = symfile_bfd_open (name);
+
+  my_cleanups = make_cleanup_bfd_close (abfd);
 
   if ((have_full_symbols () || have_partial_symbols ())
       && mainline
@@ -801,6 +807,7 @@ symbol_file_add_with_addrs_or_offsets (c
     error ("Not confirmed.");
 
   objfile = allocate_objfile (abfd, flags);
+  discard_cleanups (my_cleanups);
 
   orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd));
   my_cleanups = make_cleanup (xfree, orig_addrs);
@@ -917,7 +924,8 @@ struct objfile *
 symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
 		 int mainline, int flags)
 {
-  return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0, 
+  return symbol_file_add_with_addrs_or_offsets (name, NULL, from_tty,
+						addrs, 0, 0,
                                                 mainline, flags);
 }
 
@@ -1767,6 +1775,88 @@ add_shared_symbol_files_command (char *a
 #endif
 }
 \f
+/* 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.  */
+struct objfile *
+symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr, int from_tty)
+{
+  struct objfile *objf;
+  bfd *nbfd;
+  asection *sec;
+  bfd_vma loadbase;
+  struct section_addr_info *sai;
+  unsigned int i;
+
+  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
+    error ("add-symbol-file-from-memory not supported for this target");
+
+  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
+					 target_read_memory);
+  if (nbfd == NULL)
+    {
+      error ("Failed to read a valid object file image from memory.");
+      return NULL;
+    }
+
+  nbfd->filename = xstrdup ("shared object read from target memory");
+
+  if (!bfd_check_format (nbfd, bfd_object))
+    {
+      /* FIXME: should be checking for errors from bfd_close (for one thing,
+         on error it does not free all the storage associated with the
+         bfd).  */
+      bfd_close (nbfd);
+      error ("Got object file from memory but can't read symbols: %s.",
+	     bfd_errmsg (bfd_get_error ()));
+      return NULL;
+    }
+
+  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
+  make_cleanup (xfree, sai);
+  i = 0;
+  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
+    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
+      {
+	sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
+	sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
+	sai->other[i].sectindex = sec->index;
+	++i;
+      }
+
+  objf = symbol_file_add_with_addrs_or_offsets ((char *) nbfd->filename, nbfd,
+						from_tty, sai, NULL, 0, 0,
+						OBJF_SHARED);
+
+  /* This might change our ideas about frames already looked at.  */
+  reinit_frame_cache ();
+
+  return objf;
+}
+
+static void
+add_symbol_file_from_memory_command (char *args, int from_tty)
+{
+  CORE_ADDR addr;
+  bfd *templ;
+
+  if (args == NULL)
+    error ("add-symbol-file-from-memory requires an expression argument");
+
+  addr = parse_and_eval_address (args);
+
+  /* We need some representative bfd to know the target we are looking at.  */
+  if (symfile_objfile != NULL)
+    templ = symfile_objfile->obfd;
+  else
+    templ = exec_bfd;
+  if (templ == NULL)
+    error ("\
+Must use symbol-file or exec-file before add-symbol-file-from-memory.");
+
+  (void) symbol_file_add_from_memory (templ, addr, from_tty);
+}
+\f
 /* Re-read symbols if a symbol-file has changed.  */
 void
 reread_symbols (void)
@@ -2023,7 +2113,7 @@ reread_separate_symbols (struct objfile 
          Preserve the flags from objfile that make sense.  */
       objfile->separate_debug_objfile
         = (symbol_file_add_with_addrs_or_offsets
-           (debug_file,
+           (debug_file, NULL,
             info_verbose, /* from_tty: Don't override the default. */
             0, /* No addr table.  */
             objfile->section_offsets, objfile->num_sections,
@@ -3526,6 +3616,13 @@ with the text.  SECT is a section name t
 	       &cmdlist);
   set_cmd_completer (c, filename_completer);
 
+  c = add_cmd ("add-symbol-file-from-memory", class_files,
+	       add_symbol_file_from_memory_command,
+	       "\
+Load the symbols out of memory from a dynamically loaded object file.\n\
+Give an expression for the address of the file's shared object file header.",
+	       &cmdlist);
+
   c = add_cmd ("add-shared-symbol-files", class_files,
 	       add_shared_symbol_files_command,
    "Load the symbols from shared objects in the dynamic linker's link map.",
Index: gdb/symfile.h
===================================================================
RCS file: /cvs/src/src/gdb/symfile.h,v
retrieving revision 1.28
diff -p -u -r1.28 symfile.h
--- gdb/symfile.h	2 Apr 2004 19:23:05 -0000	1.28
+++ gdb/symfile.h	8 Apr 2004 20:31:27 -0000
@@ -302,6 +302,12 @@ extern CORE_ADDR symbol_overlayed_addres
 /* Load symbols from a file.  */
 extern void symbol_file_add_main (char *args, int from_tty);
 
+/* 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.  */
+extern struct objfile *symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr,
+						    int from_tty);
+
 /* Clear GDB symbol tables.  */
 extern void symbol_file_clear (int from_tty);
 


^ permalink raw reply	[flat|nested] 40+ messages in thread
* [PATCH] add-symbol-file-from-memory command
@ 2004-04-08 22:38 Roland McGrath
  2004-04-15 18:11 ` Jim Blandy
  0 siblings, 1 reply; 40+ messages in thread
From: Roland McGrath @ 2004-04-08 22:38 UTC (permalink / raw)
  To: gdb-patches

This is a version of the patch with the internal function's calling
convention changed as Jim suggested.  


Thanks,
Roland


ChangeLog:
2004-04-08  Roland McGrath  <roland@redhat.com>

	* symfile.c (symbol_file_add_with_addrs_or_offsets): Take ABFD as
	argument instead of NAME.
	(symbol_file_add, reread_separate_symbols): Call symfile_bfd_open
	in call to symbol_file_add_with_addrs_or_offsets.
	(build_addr_info): New function, helper for ...
	(symbol_file_add_from_memory): New function.
	(add_symbol_file_from_memory_command): New function using that.
	(_initialize_symfile): Register it for add-symbol-file-from-memory.
	(pre_add_symbol_hook): Add const to argument type.
	* symfile.h (symbol_file_add_from_memory): Declare it.

gdbtk/ChangeLog:
2004-04-08  Roland McGrath  <roland@redhat.com>

	* generic/gdbtk-hooks.c (gdbtk_pre_add_symbol): Add const to arg type.
	(pre_add_symbol): Likewise in extern decl.

Index: gdb/symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.124
diff -b -p -u -r1.124 symfile.c
--- gdb/symfile.c	28 Feb 2004 18:04:37 -0000	1.124
+++ gdb/symfile.c	8 Apr 2004 22:35:02 -0000
@@ -79,7 +79,7 @@ void (*show_load_progress) (const char *
 			    unsigned long section_size, 
 			    unsigned long total_sent, 
 			    unsigned long total_size);
-void (*pre_add_symbol_hook) (char *);
+void (*pre_add_symbol_hook) (const char *);
 void (*post_add_symbol_hook) (void);
 void (*target_new_objfile_hook) (struct objfile *);
 
@@ -761,8 +761,8 @@ new_symfile_objfile (struct objfile *obj
 /* Process a symbol file, as either the main file or as a dynamically
    loaded file.
 
-   NAME is the file name (which will be tilde-expanded and made
-   absolute herein) (but we don't free or modify NAME itself).
+   ABFD is a BFD already open on the file, as from symfile_bfd_open.
+   This BFD will be closed on error, and is always consumed by this function.
 
    FROM_TTY says how verbose to be.
 
@@ -776,7 +776,7 @@ new_symfile_objfile (struct objfile *obj
    Upon success, returns a pointer to the objfile that was added.
    Upon failure, jumps back to command level (never returns). */
 static struct objfile *
-symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
+symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
                                        struct section_addr_info *addrs,
                                        struct section_offsets *offsets,
                                        int num_offsets,
@@ -785,14 +785,14 @@ symbol_file_add_with_addrs_or_offsets (c
   struct objfile *objfile;
   struct partial_symtab *psymtab;
   char *debugfile;
-  bfd *abfd;
   struct section_addr_info *orig_addrs;
   struct cleanup *my_cleanups;
+  const char *name = bfd_get_filename (abfd);
 
-  /* Open a bfd for the file, and give user a chance to burp if we'd be
-     interactively wiping out any existing symbols.  */
+  my_cleanups = make_cleanup_bfd_close (abfd);
 
-  abfd = symfile_bfd_open (name);
+  /* Give user a chance to burp if we'd be
+     interactively wiping out any existing symbols.  */
 
   if ((have_full_symbols () || have_partial_symbols ())
       && mainline
@@ -801,6 +801,7 @@ symbol_file_add_with_addrs_or_offsets (c
     error ("Not confirmed.");
 
   objfile = allocate_objfile (abfd, flags);
+  discard_cleanups (my_cleanups);
 
   orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd));
   my_cleanups = make_cleanup (xfree, orig_addrs);
@@ -917,7 +918,8 @@ struct objfile *
 symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
 		 int mainline, int flags)
 {
-  return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0, 
+  return symbol_file_add_with_addrs_or_offsets (symfile_bfd_open (name),
+						from_tty, addrs, 0, 0,
                                                 mainline, flags);
 }
 
@@ -1767,6 +1769,87 @@ add_shared_symbol_files_command (char *a
 #endif
 }
 \f
+/* 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.  */
+struct objfile *
+symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr, int from_tty)
+{
+  struct objfile *objf;
+  bfd *nbfd;
+  asection *sec;
+  bfd_vma loadbase;
+  struct section_addr_info *sai;
+  unsigned int i;
+
+  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
+    error ("add-symbol-file-from-memory not supported for this target");
+
+  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
+					 target_read_memory);
+  if (nbfd == NULL)
+    {
+      error ("Failed to read a valid object file image from memory.");
+      return NULL;
+    }
+
+  nbfd->filename = xstrdup ("shared object read from target memory");
+
+  if (!bfd_check_format (nbfd, bfd_object))
+    {
+      /* FIXME: should be checking for errors from bfd_close (for one thing,
+         on error it does not free all the storage associated with the
+         bfd).  */
+      bfd_close (nbfd);
+      error ("Got object file from memory but can't read symbols: %s.",
+	     bfd_errmsg (bfd_get_error ()));
+      return NULL;
+    }
+
+  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
+  make_cleanup (xfree, sai);
+  i = 0;
+  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
+    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
+      {
+	sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
+	sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
+	sai->other[i].sectindex = sec->index;
+	++i;
+      }
+
+  objf = symbol_file_add_with_addrs_or_offsets (nbfd, from_tty,
+						sai, NULL, 0, 0, OBJF_SHARED);
+
+  /* This might change our ideas about frames already looked at.  */
+  reinit_frame_cache ();
+
+  return objf;
+}
+
+static void
+add_symbol_file_from_memory_command (char *args, int from_tty)
+{
+  CORE_ADDR addr;
+  bfd *templ;
+
+  if (args == NULL)
+    error ("add-symbol-file-from-memory requires an expression argument");
+
+  addr = parse_and_eval_address (args);
+
+  /* We need some representative bfd to know the target we are looking at.  */
+  if (symfile_objfile != NULL)
+    templ = symfile_objfile->obfd;
+  else
+    templ = exec_bfd;
+  if (templ == NULL)
+    error ("\
+Must use symbol-file or exec-file before add-symbol-file-from-memory.");
+
+  (void) symbol_file_add_from_memory (templ, addr, from_tty);
+}
+\f
 /* Re-read symbols if a symbol-file has changed.  */
 void
 reread_symbols (void)
@@ -2023,7 +2106,7 @@ reread_separate_symbols (struct objfile 
          Preserve the flags from objfile that make sense.  */
       objfile->separate_debug_objfile
         = (symbol_file_add_with_addrs_or_offsets
-           (debug_file,
+           (symfile_bfd_open (debug_file),
             info_verbose, /* from_tty: Don't override the default. */
             0, /* No addr table.  */
             objfile->section_offsets, objfile->num_sections,
@@ -3526,6 +3609,13 @@ with the text.  SECT is a section name t
 	       &cmdlist);
   set_cmd_completer (c, filename_completer);
 
+  c = add_cmd ("add-symbol-file-from-memory", class_files,
+	       add_symbol_file_from_memory_command,
+	       "\
+Load the symbols out of memory from a dynamically loaded object file.\n\
+Give an expression for the address of the file's shared object file header.",
+	       &cmdlist);
+
   c = add_cmd ("add-shared-symbol-files", class_files,
 	       add_shared_symbol_files_command,
    "Load the symbols from shared objects in the dynamic linker's link map.",
Index: gdb/symfile.h
===================================================================
RCS file: /cvs/src/src/gdb/symfile.h,v
retrieving revision 1.28
diff -b -p -u -r1.28 symfile.h
--- gdb/symfile.h	2 Apr 2004 19:23:05 -0000	1.28
+++ gdb/symfile.h	8 Apr 2004 22:35:02 -0000
@@ -302,6 +302,12 @@ extern CORE_ADDR symbol_overlayed_addres
 /* Load symbols from a file.  */
 extern void symbol_file_add_main (char *args, int from_tty);
 
+/* 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.  */
+extern struct objfile *symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr,
+						    int from_tty);
+
 /* Clear GDB symbol tables.  */
 extern void symbol_file_clear (int from_tty);

Index: gdb/gdbtk/generic/gdbtk-hooks.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/generic/gdbtk-hooks.c,v
retrieving revision 1.31
diff -b -p -u -r1.31 gdbtk-hooks.c
--- gdb/gdbtk/generic/gdbtk-hooks.c	12 Feb 2003 16:02:03 -0000	1.31
+++ gdb/gdbtk/generic/gdbtk-hooks.c	8 Apr 2004 22:35:11 -0000
@@ -73,7 +73,7 @@ extern void gdbtk_create_tracepoint (int
 extern void gdbtk_delete_tracepoint (int);
 extern void gdbtk_modify_tracepoint (int);
 
-extern void (*pre_add_symbol_hook) (char *);
+extern void (*pre_add_symbol_hook) (const char *);
 extern void (*post_add_symbol_hook) (void);
 extern void (*selected_frame_level_changed_hook) (int);
 extern int (*ui_loop_hook) (int);
@@ -599,7 +599,7 @@ gdbtk_load_hash (const char *section, un
 /* This hook is called whenever we are ready to load a symbol file so that
    the UI can notify the user... */
 static void
-gdbtk_pre_add_symbol (char *name)
+gdbtk_pre_add_symbol (const char *name)
 {
   gdbtk_two_elem_cmd ("gdbtk_tcl_pre_add_symbol", name);
 }


^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2004-04-15 21:42 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-20  7:01 [PATCH] add-symbol-file-from-memory command Roland McGrath
2003-10-03  4:27 Roland McGrath
2003-10-03 21:41 ` Jim Blandy
2003-10-03 21:45   ` Daniel Jacobowitz
2003-10-03 22:08   ` Roland McGrath
2003-10-03 22:19   ` Elena Zannoni
2003-10-03 23:00     ` Roland McGrath
2003-10-04 12:57       ` Elena Zannoni
2003-10-04 20:14         ` Roland McGrath
2003-10-07  1:42           ` Andrew Cagney
2003-10-03 22:34   ` Andrew Cagney
2003-10-03 23:02     ` Roland McGrath
2003-10-04 14:39       ` Andrew Cagney
2003-10-06 15:30   ` Jim Blandy
2003-10-06 15:43     ` Daniel Jacobowitz
2003-10-06 19:57       ` Roland McGrath
2003-10-07 23:32       ` Michael Snyder
2004-02-02  3:38 Roland McGrath
2004-02-02  4:06 ` Daniel Jacobowitz
2004-02-02  4:47   ` Roland McGrath
2004-02-02 15:02     ` Daniel Jacobowitz
2004-02-02 23:31       ` Roland McGrath
2004-02-02 23:34         ` Daniel Jacobowitz
2004-02-02  6:19 ` Eli Zaretskii
2004-02-02  7:35   ` Roland McGrath
2004-02-02 17:29     ` Eli Zaretskii
2004-02-12  0:34 Roland McGrath
2004-02-13 15:54 ` Andrew Cagney
2004-02-13 19:13   ` Roland McGrath
2004-04-08 20:47 Roland McGrath
2004-04-08 22:13 ` Jim Blandy
2004-04-08 22:28   ` Roland McGrath
2004-04-08 22:32     ` Daniel Jacobowitz
2004-04-08 22:35   ` Andrew Cagney
2004-04-08 22:42     ` Roland McGrath
2004-04-15 18:52       ` Andrew Cagney
2004-04-08 22:38 Roland McGrath
2004-04-15 18:11 ` Jim Blandy
2004-04-15 18:49   ` Andrew Cagney
2004-04-15 21:42   ` Roland McGrath

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox