Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess <andrew.burgess@embecosm.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 2/3] gdb: 'maint info sections' - handle the no executable case
Date: Fri,  5 Feb 2021 21:29:10 +0000	[thread overview]
Message-ID: <e49d1445ad73db5bd9ccd4270c7c1d6e7c96b405.1612560410.git.andrew.burgess@embecosm.com> (raw)
In-Reply-To: <cover.1612560410.git.andrew.burgess@embecosm.com>

The 'maint info sections' command is split into two blocks or work,
first if there's an executable then the sections from the executable,
and optionally all other loaded object files are printed.  Then all
the sections from any core file are printed.

I ran into a situation where (for various reasons) I wasn't using a
main executable.  Instead I connected to a remote target and used
add-symbol-file.  This allowed me to debug an image that was already
loaded on the remote system.

Unfortunately, when I tried to use 'maint info sections' I saw
nothing.  The reason is that the loop over all object files is hidden
behind a check that we have a main executable.

This commit removes this check and merges together some duplicate
code.  I also (I think) made the output of this command cleaner.

Here is the original output of 'maint info sections':

  Exec file:
      `/tmp/hello.x', file type elf64-x86-64.
   [0]      0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
   [1]      0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
   ...

And my modified output:

  Exec file: `/home/andrew/tmp/hello.x', file type elf64-x86-64.
   [0]      0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
   [1]      0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
   ...

The forced newline after 'Exec file: ' has been removed.  This is now
a wrap point (in case the filename is very long).

Here is the original output of 'maint info sections ALLOBJ':

  Exec file:
      `/tmp/hello.x', file type elf64-x86-64.
    Object file: /tmp/hello.x
   [0]      0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
   [1]      0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
   ...
    Object file: /lib64/ld-linux-x86-64.so.2
   [0]      0x7ffff7fd12a8->0x7ffff7fd12c8 at 0x000002a8: .note.gnu.property ALLOC LOAD READONLY DATA HAS_CONTENTS
   [1]      0x7ffff7fd12c8->0x7ffff7fd12ec at 0x000002c8: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
   ...

And my modified output:

  Exec file: `/tmp/hello.x', file type elf64-x86-64.
   [0]      0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
   [1]      0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
   ...
  Object file: `/lib64/ld-linux-x86-64.so.2', file type elf64-x86-64.
   [0]      0x7ffff7fd12a8->0x7ffff7fd12c8 at 0x000002a8: .note.gnu.property ALLOC LOAD READONLY DATA HAS_CONTENTS
   [1]      0x7ffff7fd12c8->0x7ffff7fd12ec at 0x000002c8: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
   ...

The executable now only gets a single header line.  The header line
for the additional object files is no longer indented as it was
before, and the line is laid out in a similar style to the main
executable line (with quotes and file type information).

And of course, the biggest change.  If GDB is started with no
executable, but then the user does 'add-symbol-file ....' followed by
'maint info sections ALLOBJ', previously they got nothing, now they
get:

  Object file: `/tmp/hello.x', file type elf64-x86-64.
   [0]      0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
   [1]      0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
   ...

gdb/ChangeLog:

	* maint.c (print_bfd_section_info_maybe_relocated): Delete,
	functionality merged into...
	(maint_print_all_sections): ...this new function.
	(maintenance_info_sections): Make use of maint_print_all_sections,
	allow all objects to be printed even where there's no executable.

gdb/testsuite/ChangeLog:

	* gdb.base/maint-info-sections.exp: Update expected output, and
	add additional tests.
---
 gdb/ChangeLog                                 |   8 ++
 gdb/maint.c                                   | 114 +++++++++---------
 gdb/testsuite/ChangeLog                       |   5 +
 .../gdb.base/maint-info-sections.exp          |  41 ++++++-
 4 files changed, 105 insertions(+), 63 deletions(-)

diff --git a/gdb/maint.c b/gdb/maint.c
index d718d707134..c6fc83ccfb7 100644
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -354,25 +354,50 @@ maint_obj_section_from_bfd_section (bfd *abfd,
   return osect;
 }
 
-/* Print information about ASECT from ABFD.  Where possible the information for
-   ASECT will print the relocated addresses of the section.
+/* Print information about all sections from ABFD, which is the bfd
+   corresponding to OBJFILE.  It is fine for OBJFILE to be nullptr, but
+   ABFD must never be nullptr.  If OBJFILE is provided then the sections of
+   ABFD will (potentially) be displayed relocated (i.e. the object file was
+   loaded with add-symbol-file and custom offsets were provided).
 
-   ARG is the argument string passed by the user to the top level maintenance
-   info sections command.  Used for filtering which sections are printed.  */
+   HEADER is a string that describes this file, e.g. 'Exec file: ', or
+   'Core file: '.
+
+   ARG is a string used for filtering which sections are printed, this can
+   be nullptr for no filtering.  See the top level 'maint info sections'
+   for a fuller description of the possible filtering strings.  */
 
 static void
-print_bfd_section_info_maybe_relocated (bfd *abfd, asection *asect,
-					objfile *objfile, const char *arg,
-					int index_digits)
+maint_print_all_sections (const char *header, bfd *abfd, objfile *objfile,
+			  const char *arg)
 {
-  gdb_assert (objfile->sections != NULL);
-  obj_section *osect
-    = maint_obj_section_from_bfd_section (abfd, asect, objfile);
+  puts_filtered (header);
+  wrap_here ("        ");
+  printf_filtered ("`%s', ", bfd_get_filename (abfd));
+  wrap_here ("        ");
+  printf_filtered (_("file type %s.\n"), bfd_get_target (abfd));
 
-  if (osect->the_bfd_section == NULL)
-    print_bfd_section_info (abfd, asect, arg, index_digits);
-  else
-    print_objfile_section_info (abfd, osect, arg, index_digits);
+  int section_count = gdb_bfd_count_sections (abfd);
+  int digits = index_digits (section_count);
+
+  for (asection *sect : gdb_bfd_sections (abfd))
+    {
+      obj_section *osect = nullptr;
+
+      if (objfile != nullptr)
+	{
+	  gdb_assert (objfile->sections != nullptr);
+	  osect
+	    = maint_obj_section_from_bfd_section (abfd, sect, objfile);
+	  if (osect->the_bfd_section == nullptr)
+	    osect = nullptr;
+	}
+
+      if (osect == nullptr)
+	print_bfd_section_info (abfd, sect, arg, digits);
+      else
+	print_objfile_section_info (abfd, osect, arg, digits);
+    }
 }
 
 /* Implement the "maintenance info sections" command.  */
@@ -380,56 +405,27 @@ print_bfd_section_info_maybe_relocated (bfd *abfd, asection *asect,
 static void
 maintenance_info_sections (const char *arg, int from_tty)
 {
-  if (current_program_space->exec_bfd ())
-    {
-      bool allobj = false;
-
-      printf_filtered (_("Exec file:\n"));
-      printf_filtered ("    `%s', ",
-		       bfd_get_filename (current_program_space->exec_bfd ()));
-      wrap_here ("        ");
-      printf_filtered (_("file type %s.\n"),
-		       bfd_get_target (current_program_space->exec_bfd ()));
-
-      /* Only this function cares about the 'ALLOBJ' argument;
-	 if 'ALLOBJ' is the only argument, discard it rather than
-	 passing it down to print_objfile_section_info (which
-	 wouldn't know how to handle it).  */
-      if (arg && strcmp (arg, "ALLOBJ") == 0)
-	{
-	  arg = NULL;
-	  allobj = true;
-	}
+  bool allobj = false;
 
-      for (objfile *ofile : current_program_space->objfiles ())
-	{
-	  if (allobj)
-	    printf_filtered (_("  Object file: %s\n"),
-			     bfd_get_filename (ofile->obfd));
-	  else if (ofile->obfd != current_program_space->exec_bfd ())
-	    continue;
-
-	  int section_count = gdb_bfd_count_sections (ofile->obfd);
-
-	  for (asection *sect : gdb_bfd_sections (ofile->obfd))
-	    print_bfd_section_info_maybe_relocated
-	      (ofile->obfd, sect, ofile, arg, index_digits (section_count));
-	}
+  /* Only this function cares about the 'ALLOBJ' argument; if 'ALLOBJ' is
+     the only argument, discard it rather than passing it down to
+     print_objfile_section_info (which wouldn't know how to handle it).  */
+  if (arg != nullptr && strcmp (arg, "ALLOBJ") == 0)
+    {
+      arg = nullptr;
+      allobj = true;
     }
 
-  if (core_bfd)
+  for (objfile *ofile : current_program_space->objfiles ())
     {
-      printf_filtered (_("Core file:\n"));
-      printf_filtered ("    `%s', ", bfd_get_filename (core_bfd));
-      wrap_here ("        ");
-      printf_filtered (_("file type %s.\n"), bfd_get_target (core_bfd));
-
-      int section_count = gdb_bfd_count_sections (core_bfd);
-
-      for (asection *sect : gdb_bfd_sections (core_bfd))
-	print_bfd_section_info (core_bfd, sect, arg,
-				index_digits (section_count));
+      if (ofile->obfd == current_program_space->exec_bfd ())
+	maint_print_all_sections (_("Exec file: "), ofile->obfd, ofile, arg);
+      else if (allobj)
+	maint_print_all_sections (_("Object file: "), ofile->obfd, ofile, arg);
     }
+
+  if (core_bfd)
+    maint_print_all_sections (_("Core file: "), core_bfd, nullptr, arg);
 }
 
 static void
diff --git a/gdb/testsuite/gdb.base/maint-info-sections.exp b/gdb/testsuite/gdb.base/maint-info-sections.exp
index 6c41ff2bd90..19e5c122226 100644
--- a/gdb/testsuite/gdb.base/maint-info-sections.exp
+++ b/gdb/testsuite/gdb.base/maint-info-sections.exp
@@ -34,7 +34,7 @@ if ![runto_main] then {
 set seen_header false
 set seen_a_section false
 gdb_test_multiple "maint info sections" "general output check" {
-    -re "Exec file:\r\n\[\t ]+`\[^'\]+', file type \[^.\]+\.\r\n" {
+    -re "Exec file: `\[^'\]+', file type \[^.\]+\.\r\n" {
 	set seen_header true
 	exp_continue
     }
@@ -63,18 +63,18 @@ set text_section ".text"
 set data_section ".data"
 
 gdb_test_multiple "maint info sections" "" {
-    -re -wrap "Exec file:\r\n.*${binfile}., file type.*ER_RO.*" {
+    -re -wrap "Exec file: .*${binfile}., file type.*ER_RO.*" {
 	# Looks like RealView which uses different section names.
 	set text_section ER_RO
 	set data_section ER_RW
 	pass "maint info sections"
     }
-    -re -wrap "Exec file:\r\n.*${binfile}., file type.*neardata.*" {
+    -re -wrap "Exec file: .*${binfile}., file type.*neardata.*" {
 	# c6x doesn't have .data section.  It has .neardata and .fardata section.
 	set data_section ".neardata"
 	pass "maint info sections"
     }
-    -re -wrap "Exec file:\r\n.*${binfile}., file type.*" {
+    -re -wrap "Exec file: .*${binfile}., file type.*" {
 	pass "maint info sections"
     }
 }
@@ -125,3 +125,36 @@ gdb_test_multiple "maint info sections DATA" "" {
 	pass $gdb_test_name
     }
 }
+
+# Restart GDB, but don't load the executable.
+clean_restart
+
+# Now load the executable in as a symbol file.
+gdb_test "add-symbol-file ${binfile}" ".*" \
+    "load the executable as a symbol file" \
+    "add symbol table from file \"${binfile}\"\r\n\\(y or n\\) " \
+    "y"
+
+# As we have no object file 'maint info sections' will print nothing.
+gdb_test_no_output "maint info sections" \
+    "no output when no executable is set"
+
+# Check that the executable shows up as an object file when ALLOBJ is
+# used.
+set seen_header false
+set seen_a_section false
+gdb_test_multiple "maint info sections ALLOBJ" "" {
+    -re "Object file: `${binfile}', file type \[^.\]+\.\r\n" {
+	set seen_header true
+	exp_continue
+    }
+    -re "^ \\\[\[0-9\]+\\\]\[\t \]+$hex->$hex at $hex: \[^*\r\]+\r\n" {
+	set seen_a_section true
+	exp_continue
+    }
+    -re "^$gdb_prompt $" {
+	gdb_assert { $seen_header && $seen_a_section } \
+	    "ensure header and section seen in ALLOBJ case"
+	pass $gdb_test_name
+    }
+}
-- 
2.25.4


  parent reply	other threads:[~2021-02-05 21:29 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-05 21:29 [PATCH 0/3] Changes to 'maint info sections' Andrew Burgess
2021-02-05 21:29 ` [PATCH 1/3] gdb/testsuite: split 'maint info sections' tests to a new file Andrew Burgess
2021-02-08 19:28   ` Tom Tromey
2021-02-05 21:29 ` Andrew Burgess [this message]
2021-02-08 19:29   ` [PATCH 2/3] gdb: 'maint info sections' - handle the no executable case Tom Tromey
2021-02-05 21:29 ` [PATCH 3/3] gdb: change 'maint info section' to use command options Andrew Burgess
2021-02-06  7:16   ` Eli Zaretskii via Gdb-patches
2021-02-08 19:32   ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e49d1445ad73db5bd9ccd4270c7c1d6e7c96b405.1612560410.git.andrew.burgess@embecosm.com \
    --to=andrew.burgess@embecosm.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox