aboutsummaryrefslogtreecommitdiff
path: root/gdb/maint.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2021-02-05 11:16:31 +0000
committerAndrew Burgess <andrew.burgess@embecosm.com>2021-02-11 10:26:18 +0000
commit4790db149699b21113c566b8b9249953038fd3a7 (patch)
tree7db522b99ff19d4ba66e78141059bcedacbf59df /gdb/maint.c
parentf4be677293a68a4d54f978bccbd703c3909b5149 (diff)
downloadgdb-4790db149699b21113c566b8b9249953038fd3a7.zip
gdb-4790db149699b21113c566b8b9249953038fd3a7.tar.gz
gdb-4790db149699b21113c566b8b9249953038fd3a7.tar.bz2
gdb: 'maint info sections' - handle the no executable case
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.
Diffstat (limited to 'gdb/maint.c')
-rw-r--r--gdb/maint.c114
1 files changed, 55 insertions, 59 deletions
diff --git a/gdb/maint.c b/gdb/maint.c
index f6e42f6..0dda11b 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