This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] add-symbol-file-from-memory command


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
 }
 
+/* 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);
+}
+
 /* 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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]