From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id D6A56388A02F for ; Thu, 2 Apr 2020 14:55:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D6A56388A02F Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 032Et7oa020510 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 2 Apr 2020 10:55:12 -0400 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 032Et7oa020510 Received: from [10.0.0.11] (unknown [192.222.164.54]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 24ACB1E581; Thu, 2 Apr 2020 10:55:07 -0400 (EDT) Subject: [PATCH] gdb: use bfd_get_section_contents to read section contents in, is_linked_with_cygwin_dll (was: Re: [PATCH 6/7] gdb: select "Cygwin" OS ABI for Cygwin binaries) To: Tom Tromey , Pedro Alves via Gdb-patches Cc: Pedro Alves , Simon Marchi , Jon Turney References: <20200316170845.184386-1-simon.marchi@polymtl.ca> <20200316170845.184386-7-simon.marchi@polymtl.ca> <0b76517a-f6dd-0aa8-17fb-ce5a9accbf42@redhat.com> <87ftdmvx85.fsf@tromey.com> From: Simon Marchi Message-ID: <6b6b7467-2db4-56c9-dd98-3082b7b68abe@polymtl.ca> Date: Thu, 2 Apr 2020 10:55:06 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.6.0 MIME-Version: 1.0 In-Reply-To: <87ftdmvx85.fsf@tromey.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US-large Content-Transfer-Encoding: 7bit X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Thu, 2 Apr 2020 14:55:07 +0000 X-Spam-Status: No, score=-24.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org 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: , X-List-Received-Date: Thu, 02 Apr 2020 14:55:25 -0000 On 2020-04-02 9:22 a.m., Tom Tromey wrote: > There's no way to ever release this data. Since it's only used once, it > may be better to use bfd_get_full_section_contents, so the memory can be > freed when done. Good point, I hadn't thought of that. Here's a patch. I only tested it on GNU/Linux, making sure GDB is still able to recognize a mingw binary and a cygwin binary. >From b7f4f941018c7b4a7431837ccf5eee5c992f4111 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Thu, 2 Apr 2020 10:34:39 -0400 Subject: [PATCH] gdb: use bfd_get_section_contents to read section contents in is_linked_with_cygwin_dll The function is_linked_with_cygwin_dll currently uses gdb_bfd_map_section to get some section contents. This is not ideal because that memory, which is only used in this function, can't be released. Instead, it was suggested to use bfd_get_section_contents, and this is what this patch does. I decided to make a small bfd_get_section_contents wrapper in gdb_bfd.c, which returns the contents in a gdb::byte_vector. The wrapper also makes it easy to get the full section contents into a gdb::byte_vector. Note that BFD provides the bfd_get_full_section_contents function, but this one returns a newly-allocated buffer. gdb_bfd_get_section_contents offers a consistent interface, regardless of whether you need to read part of a section or the full section. gdb_bfd_get_section_contents could be used at many places that already allocate a vector of the size of the section and then call bfd_get_section_contents. I think these call sites can be updated over time. gdb/ChangeLog: * gdb_bfd.h: Include gdbsupport/byte-vector.h and gdbsupport/gdb_optional.h. (BFD_SIZE_TYPE_MAX): New macro. (gdb_bfd_get_section_contents): New declaration. * gdb_bfd.c (gdb_bfd_get_section_contents): New function. * windows-tdep.c (is_linked_with_cygwin_dll): Use gdb_bfd_get_section_contents. --- gdb/gdb_bfd.c | 25 ++++++++++++++++++++++++- gdb/gdb_bfd.h | 15 +++++++++++++++ gdb/windows-tdep.c | 13 ++++++------- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index 5a6dee2d51a8..2b34e0f3e17c 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -926,7 +926,30 @@ gdb_bfd_requires_relocations (bfd *abfd) return gdata->needs_relocations; } - +/* See gdb_bfd.h. */ + +bool +gdb_bfd_get_section_contents (bfd *abfd, asection *section, + gdb::byte_vector *contents, file_ptr offset, + bfd_size_type count) +{ + bfd_size_type section_size = bfd_section_size (section); + + /* Allow `offset == section_size`, to allow the corner case of + `offset == section_size`, `count = 0`. */ + gdb_assert (offset <= section_size); + + /* If COUNT is unspecified, get the contents from OFFSET until the end of the + section. */ + if (count == BFD_SIZE_TYPE_MAX) + count = section_size - offset; + + gdb_assert ((offset + count) <= section_size); + + contents->resize (count); + + return bfd_get_section_contents (abfd, section, contents->data (), offset, count); +} /* A callback for htab_traverse that prints a single BFD. */ diff --git a/gdb/gdb_bfd.h b/gdb/gdb_bfd.h index 9b1e292bf18f..ffea4f6b715e 100644 --- a/gdb/gdb_bfd.h +++ b/gdb/gdb_bfd.h @@ -21,6 +21,8 @@ #define GDB_BFD_H #include "registry.h" +#include "gdbsupport/byte-vector.h" +#include "gdbsupport/gdb_optional.h" #include "gdbsupport/gdb_ref_ptr.h" DECLARE_REGISTRY (bfd); @@ -30,6 +32,8 @@ DECLARE_REGISTRY (bfd); #define TARGET_SYSROOT_PREFIX "target:" +#define BFD_SIZE_TYPE_MAX ((bfd_size_type) -1) + /* Returns nonzero if NAME starts with TARGET_SYSROOT_PREFIX, zero otherwise. */ @@ -181,4 +185,15 @@ int gdb_bfd_count_sections (bfd *abfd); int gdb_bfd_requires_relocations (bfd *abfd); +/* Wrapper around bfd_get_section_contents, returning the requested section + contents in *CONTENTS. Return true on success, false otherwise. + + If COUNT is not specified, read from OFFSET until the end of the + section. */ + +bool +gdb_bfd_get_section_contents (bfd *abfd, asection *section, + gdb::byte_vector *contents, file_ptr offset = 0, + bfd_size_type count = BFD_SIZE_TYPE_MAX); + #endif /* GDB_BFD_H */ diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c index 9c5dfd183bfa..9b7dc1d12b26 100644 --- a/gdb/windows-tdep.c +++ b/gdb/windows-tdep.c @@ -1005,18 +1005,17 @@ is_linked_with_cygwin_dll (bfd *abfd) bfd_vma idata_addr = pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress; - /* Map the section's data. */ - bfd_size_type idata_size; - const gdb_byte *const idata_contents - = gdb_bfd_map_section (idata_section, &idata_size); - if (idata_contents == nullptr) + /* Get the section's data. */ + gdb::byte_vector idata_contents; + if (!gdb_bfd_get_section_contents(abfd, idata_section, &idata_contents)) { warning (_("Failed to get content of .idata section.")); return false; } - const gdb_byte *iter = idata_contents; - const gdb_byte *end = idata_contents + idata_size; + size_t idata_size = idata_contents.size (); + const gdb_byte *iter = idata_contents.data (); + const gdb_byte *end = idata_contents.data () + idata_size; const pe_import_directory_entry null_dir_entry = { 0 }; /* Iterate through all directory entries. */ -- 2.26.0