diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2021-02-05 11:16:31 +0000 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2021-02-11 10:26:18 +0000 |
commit | 4790db149699b21113c566b8b9249953038fd3a7 (patch) | |
tree | 7db522b99ff19d4ba66e78141059bcedacbf59df /gdb | |
parent | f4be677293a68a4d54f978bccbd703c3909b5149 (diff) | |
download | gdb-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')
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/maint.c | 114 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/maint-info-sections.exp | 41 |
4 files changed, 105 insertions, 63 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 69e14b3..14b11be 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> + * 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. + +2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> + * breakpoint.c (resolve_sal_pc): Make use of bound_minimal_symbol::obj_section. * maint.c (maintenance_translate_address): Likewise. 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 diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c2cc222..0102a93 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> + * gdb.base/maint-info-sections.exp: Update expected output, and + add additional tests. + +2021-02-11 Andrew Burgess <andrew.burgess@embecosm.com> + * gdb.base/maint-info-sections.exp: New file, content is moved from gdb.base/maint.exp and cleaned up to use latest testsuite techniques. diff --git a/gdb/testsuite/gdb.base/maint-info-sections.exp b/gdb/testsuite/gdb.base/maint-info-sections.exp index 6c41ff2..19e5c12 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 + } +} |