From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 88266 invoked by alias); 19 Feb 2020 03:23:45 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 88254 invoked by uid 89); 19 Feb 2020 03:23:45 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.2 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.1 spammy=reopened, HX-Languages-Length:4591 X-HELO: mail-pf1-f181.google.com Received: from mail-pf1-f181.google.com (HELO mail-pf1-f181.google.com) (209.85.210.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 19 Feb 2020 03:23:43 +0000 Received: by mail-pf1-f181.google.com with SMTP id 185so11765776pfv.3 for ; Tue, 18 Feb 2020 19:23:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=//j6PLzXsPvCNRIVFiHH6avRRhHbBUFV0hBlZgCNpM8=; b=fpOj+zejFrRYlhsiKmuUMvJlu/R5oKc4s5Su34r8LSGU34SgWg4dZe/mnin5wiKsuA vVZ4zF2YH1XxIYfFiz9cwvzgUzS1zqSLnPirLie3ORQoMv8/tbVGPt5ZCR7MMLPlJERB O8amXCCmWNdd6beVS27kM0DIBG2y9ipHVwymtehGttsJ3AJ7UQTxmMi/LYJnm34ViAtm g2jxkR3Wj/v2WG8uVHVtdRTpoKGQVfBllLA34f34x6ik+Q+9ZnBXsmvWtMJcm54LiAV5 HQG0OVW3hNc18r3XM8RDPhsg7tJad02+sXcCAcD79pKzHVjgrWaaJz/Xf6vIzADP7Jx6 D/mA== Return-Path: Received: from bubble.grove.modra.org (158.106.96.58.static.exetel.com.au. [58.96.106.158]) by smtp.gmail.com with ESMTPSA id f127sm447995pfa.112.2020.02.18.19.23.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 19:23:40 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 908A78ADF5; Wed, 19 Feb 2020 13:53:36 +1030 (ACDT) Date: Wed, 19 Feb 2020 03:23:00 -0000 From: Alan Modra To: binutils@sourceware.org Subject: bfd_get_size cache Message-ID: <20200219032336.GI5570@bubble.grove.modra.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.9.4 (2018-02-28) X-IsSubscribed: yes X-SW-Source: 2020-02/txt/msg00437.txt.bz2 We have calls to bfd_get_size when swapping in ELF section headers. Since object files can have a large number of sections, it's worth caching the file size rather than making lots of stat system calls. * bfd.c (struct bfd): Move format and direction to other bitfields. Add "size". * bfdio.c (bfd_get_size): Cache size when not writing file. * opncls.c (bfd_get_debug_link_info_1): Allow for bfd_get_size returning zero, ie. unknown. (bfd_get_alt_debug_link_info): Likewise. * bfd-in2.h: Regenerate. diff --git a/bfd/bfd.c b/bfd/bfd.c index 574cebd8de..463f94bb94 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -85,12 +85,6 @@ CODE_FRAGMENT . {* A unique identifier of the BFD *} . unsigned int id; . -. {* The format which belongs to the BFD. (object, core, etc.) *} -. ENUM_BITFIELD (bfd_format) format : 3; -. -. {* The direction with which the BFD was opened. *} -. ENUM_BITFIELD (bfd_direction) direction : 2; -. . {* Format_specific flags. *} . flagword flags; . @@ -194,6 +188,12 @@ CODE_FRAGMENT . | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT \ . | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON) . +. {* The format which belongs to the BFD. (object, core, etc.) *} +. ENUM_BITFIELD (bfd_format) format : 3; +. +. {* The direction with which the BFD was opened. *} +. ENUM_BITFIELD (bfd_direction) direction : 2; +. . {* Is the file descriptor being cached? That is, can it be closed as . needed, and re-opened when accessed later? *} . unsigned int cacheable : 1; @@ -283,7 +283,7 @@ CODE_FRAGMENT . . {* Symbol table for output BFD (with symcount entries). . Also used by the linker to cache input BFD symbols. *} -. struct bfd_symbol **outsymbols; +. struct bfd_symbol **outsymbols; . . {* Used for input and output. *} . unsigned int symcount; @@ -294,6 +294,11 @@ CODE_FRAGMENT . {* Pointer to structure which contains architecture information. *} . const struct bfd_arch_info *arch_info; . +. {* Cached length of file for bfd_get_size. 0 until bfd_get_size is +. called, 1 if stat returns an error or the file size is too large to +. return in ufile_ptr. Both 0 and 1 should be treated as "unknown". *} +. ufile_ptr size; +. . {* Stuff only useful for archives. *} . void *arelt_data; . struct bfd *my_archive; {* The containing archive BFD. *} diff --git a/bfd/bfdio.c b/bfd/bfdio.c index fd81b93cd9..49e0958526 100644 --- a/bfd/bfdio.c +++ b/bfd/bfdio.c @@ -415,17 +415,32 @@ DESCRIPTION of space for the 15 bazillon byte table it is about to read. This function at least allows us to answer the question, "is the size reasonable?". + + A return value of zero indicates the file size is unknown. */ ufile_ptr bfd_get_size (bfd *abfd) { - struct stat buf; + /* A size of 0 means we haven't yet called bfd_stat. A size of 1 + means we have a cached value of 0, ie. unknown. */ + if (abfd->size <= 1 || bfd_write_p (abfd)) + { + struct stat buf; - if (bfd_stat (abfd, &buf) != 0) - return 0; + if (abfd->size == 1 && !bfd_write_p (abfd)) + return 0; - return buf.st_size; + if (bfd_stat (abfd, &buf) != 0 + || buf.st_size == 0 + || buf.st_size - (ufile_ptr) buf.st_size != 0) + { + abfd->size = 1; + return 0; + } + abfd->size = buf.st_size; + } + return abfd->size; } /* diff --git a/bfd/opncls.c b/bfd/opncls.c index a03ad51c8f..796202d31a 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -1209,6 +1209,7 @@ bfd_get_debug_link_info_1 (bfd *abfd, void *crc32_out) unsigned int crc_offset; char *name; bfd_size_type size; + ufile_ptr file_size; BFD_ASSERT (abfd); BFD_ASSERT (crc32_out); @@ -1219,9 +1220,10 @@ bfd_get_debug_link_info_1 (bfd *abfd, void *crc32_out) return NULL; size = bfd_section_size (sect); + file_size = bfd_get_size (abfd); /* PR 22794: Make sure that the section has a reasonable size. */ - if (size < 8 || size >= bfd_get_size (abfd)) + if (size < 8 || (file_size != 0 && size >= file_size)) return NULL; if (!bfd_malloc_and_get_section (abfd, sect, &contents)) @@ -1298,6 +1300,7 @@ bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len, unsigned int buildid_offset; char *name; bfd_size_type size; + ufile_ptr file_size; BFD_ASSERT (abfd); BFD_ASSERT (buildid_len); @@ -1309,7 +1312,8 @@ bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len, return NULL; size = bfd_section_size (sect); - if (size < 8 || size >= bfd_get_size (abfd)) + file_size = bfd_get_size (abfd); + if (size < 8 || (file_size != 0 && size >= file_size)) return NULL; if (!bfd_malloc_and_get_section (abfd, sect, & contents)) -- Alan Modra Australia Development Lab, IBM