From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id OJ1ICra4HWD2LAAAWB0awg (envelope-from ) for ; Fri, 05 Feb 2021 16:29:26 -0500 Received: by simark.ca (Postfix, from userid 112) id 285851EFCD; Fri, 5 Feb 2021 16:29:26 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED, MAILING_LIST_MULTI,T_DKIM_INVALID,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 19A521EF7C for ; Fri, 5 Feb 2021 16:29:24 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A8D023857815; Fri, 5 Feb 2021 21:29:23 +0000 (GMT) Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by sourceware.org (Postfix) with ESMTPS id CD3B63857C68 for ; Fri, 5 Feb 2021 21:29:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org CD3B63857C68 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=andrew.burgess@embecosm.com Received: by mail-wm1-x335.google.com with SMTP id u14so6994279wmq.4 for ; Fri, 05 Feb 2021 13:29:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yYyqwIVCO0bN5bM40pIHkthpWNalaNWnEbYlrlhj1sM=; b=aD0pi5k4nMkeWpDH1xFs78Gi1E7PTHbF6x54jX/mS9ejpwnQBSFJ/JKYVxtfRR8Cuz VQjgYvK7IYcKdW1lQDYJa2xjmcXYFOsShhU4g6ptkDriCz76UlhYgVX5chyAM+EGKvoS DgK5EtYuTCXLt4+igM8ShdIJZN8B6EKGNkuLmoqLKmvFwlpaS8ESXIbdKh+HER2u7xUR KQamcM10JJkyAFjz6I/XKihW+UuzadiDi4ZaV72kthdSOrM9pjjuVkii9c2TIPl4XUk+ n4PNTvx/L+PakjpsKBfyEuLwvkTs3UKRruUB5mCxJKoVRl6oOc+hxwVZQKIS3Tzvv3Qm I4dA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yYyqwIVCO0bN5bM40pIHkthpWNalaNWnEbYlrlhj1sM=; b=CqZEhXYF+bE/B1IgEqzON5UTRFGP3MvF6mHI8kn7QFEPJUYvkogr7h3PF3f5YO8Tey bJ2Q/bQKbxDEu5Yvdwt6/a49HPUlW+RrltkWNB5pZ9sxyeF8sl6gpdWueiMcuBSXIGm4 NQmU3I7ZAn5dJdLt5TrSxaTearF2WQ+Y+x+lQiTED/53zMO82e/qEnL8JJracB4gM189 yE1bG2WDLNWyGF4SIoXeVP/gn2cVbLWQKwKHv7gBZZomzXh6/pi3DZwLhR/vZ9xn4lGK lJOeaO+itApVcsKVASPQI3+JPczmK5qcTpgeWPloeNmBS9vaFYyTcPaLG2/+VdoziB24 5DZw== X-Gm-Message-State: AOAM532u9KmzfSTUvmUX/7AdBzSedBFfYiLszQVCL4c4/x1OBRyGQ0r2 QuCl2C8k7KU4cHqusOOFJ//hWmkX89l1Sw== X-Google-Smtp-Source: ABdhPJzhaEo5/5rj4Rckn0uw9JsEkzAFKshXukJZeKkYbCAdl9JY67HPZ3uXcZ/QUL+YuX4R+TWJzQ== X-Received: by 2002:a1c:8083:: with SMTP id b125mr5111262wmd.188.1612560558270; Fri, 05 Feb 2021 13:29:18 -0800 (PST) Received: from localhost (host109-151-46-64.range109-151.btcentralplus.com. [109.151.46.64]) by smtp.gmail.com with ESMTPSA id i15sm8948791wmq.26.2021.02.05.13.29.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Feb 2021 13:29:17 -0800 (PST) From: Andrew Burgess 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 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" 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