Add an optional offset option to the "symbol-file" command

Message ID 2053384.P3bKoiIbRW@ralph.baldwin.cx
State New, archived
Headers

Commit Message

John Baldwin May 25, 2018, 9:44 p.m. UTC
  On Friday, May 25, 2018 10:14:35 AM Simon Marchi wrote:
> On 2018-05-25 01:23, Petr Tesarik wrote:
> > Yes, technically, add-symbol-file can be used for the same purpose, but
> > it is very inconvenient. Most notably, it requires listing all ELF
> > sections explicitly, and the Linux kernel has a lot of them (typically
> > a few dozen).
> > 
> > So, my current solution is:
> > 
> >  1. exec-file vmlinux
> >  2. info target
> >  3. # parse the output, adding an offset to each section's start
> >  4. add-symbol-file vmlinux $textaddr -s ... # a very long list
> >  5. exec-file  # to make sure that only target memory is used
> > 
> > Although I have already written a Python script to initialise the
> > session, it's ugly, especially when it comes to parsing the output of
> > "info target".
> 
> Thanks for confirming.
> 
> > Regarding consistency, add-symbol-file does not currently have any
> > conflicting "-o" option, so I can add one for the same purpose.
> > 
> > Shall I do that?
> 
> I think it would be a good idea.  It would improve the usability of 
> add-symbol-file and keep both commands more or less in sync, so it 
> sounds like a win-win to me.
> 
> I assume the second positional argument of add-symbol-file (which gives 
> the start address of .text) would become optional?  You just need to 
> think carefully about what should happen when mixing the different 
> arguments.  The .text positional argument and -o would probably be 
> mutually exclusive?  -o applies to all sections, but you could use -s to 
> override the address of a particular section?

Please do this.  I have an old branch with an 'add_symbol_file_rel' that
tried to do this (but the syntax was a bit clumsy).  My use case was debugging
an EFI appliation via the GDB stub in qemu.  I've included the patch below
in case it is useful.

commit d4ae4cb5271baacc2754e0ee89415c66a5296133
Author: John Baldwin <jhb@FreeBSD.org>
Date:   Fri Mar 6 15:09:01 2015 -0500

    Add a variant of 'add-symbol-file' that accepts a single base address
    of the image and relocates all sections in the file by adding the
    base address.
  

Patch

diff --git a/gdb/symfile.c b/gdb/symfile.c
index c2a71eca59..6f86fd4345 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -89,6 +89,8 @@  static void symbol_file_add_main_1 (const char *args, int from_tty, int flags);
 
 static void add_symbol_file_command (char *, int);
 
+static void add_symbol_file_rel_command (char *, int);
+
 static const struct sym_fns *find_sym_fns (bfd *);
 
 static void decrement_reading_symtab (void *);
@@ -2406,6 +2408,74 @@  add_symbol_file_command (char *args, int from_tty)
 }
 
 
+static void
+add_symbol_file_rel_command (char *args, int from_tty)
+{
+  struct gdbarch *gdbarch = get_current_arch ();
+  int flags = OBJF_USERLOADED | OBJF_SHARED;
+  CORE_ADDR base_addr;
+  char *arg;
+  int argcnt = 0;
+  int i;
+  char **argv;
+  struct objfile *objf;
+  bfd *bfd;
+
+  struct section_addr_info *section_addrs;
+  struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
+
+  dont_repeat ();
+
+  if (args == NULL)
+    error (_("add-symbol-file-rel takes a file name and an address"));
+
+  argv = gdb_buildargv (args);
+  make_cleanup_freeargv (argv);
+
+  if (argv[0] == NULL || argv[1] == NULL)
+    error (_("add-symbol-file-rel takes a file name and an address"));
+
+  /* The first argument is the file name.  */
+  bfd = symfile_bfd_open (argv[0]);
+  make_cleanup_bfd_unref (bfd);
+
+  /* The second argument is the base address. */
+  base_addr = parse_and_eval_address (argv[1]);
+
+  /* Handle optional arguments. */
+  for (arg = argv[2], argcnt = 2; arg != NULL; arg = argv[++argcnt])
+    {
+      if (strcmp (arg, "-readnow") == 0)
+	flags |= OBJF_READNOW;
+      else
+	error (_("USAGE: add-symbol-file-rel <filename> <baseaddress>"
+		 " [-readnow]"));
+    }
+
+  section_addrs = build_section_addr_info_from_bfd (bfd);
+  make_cleanup_free_section_addr_info (section_addrs);
+  for (i = 0; i < section_addrs->num_sections; i++)
+    {
+      section_addrs->other[i].addr += base_addr;
+      printf_unfiltered ("\t%s_addr = %s\n", section_addrs->other[i].name,
+			 paddress (gdbarch, section_addrs->other[i].addr));
+    }
+  
+  if (from_tty && (!query ("%s", "")))
+    error (_("Not confirmed."));
+
+  objf = symbol_file_add_from_bfd (bfd, argv[0], from_tty ? SYMFILE_VERBOSE : 0,
+				   section_addrs, flags, NULL);
+
+  add_target_sections_of_objfile (objf);
+
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+  reinit_frame_cache ();
+  do_cleanups (my_cleanups);
+}
+
+
 /* This function removes a symbol file that was added via add-symbol-file.  */
 
 static void
@@ -3998,6 +4068,15 @@  with the text.  SECT is a section name to be loaded at SECT_ADDR."),
 	       &cmdlist);
   set_cmd_completer (c, filename_completer);
 
+  c = add_cmd ("add-symbol-file-rel", class_files, add_symbol_file_rel_command,
+	       _("\
+Load symbols from FILE, assuming FILE has been dynamically loaded.\n\
+Usage: add-symbol-file-rel FILE ADDR\n\
+ADDR is the base address of the file.  The base address is added to the\n\
+address of each loaded section."),
+	       &cmdlist);
+  set_cmd_completer (c, filename_completer);
+  
   c = add_cmd ("remove-symbol-file", class_files,
 	       remove_symbol_file_command, _("\
 Remove a symbol file added via the add-symbol-file command.\n\