aboutsummaryrefslogtreecommitdiff
path: root/bfd/bfdio.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-02-19 13:14:28 +1030
committerAlan Modra <amodra@gmail.com>2020-02-19 13:14:28 +1030
commitb03202e32c8235997b3485b0b4655926ad97a1cc (patch)
tree0697dbbcfdd4c7b08d717ce5fcc5b640872e0367 /bfd/bfdio.c
parent7c5fa58ea907c46817b915ec8b9b35a180e0e74c (diff)
downloadfsf-binutils-gdb-b03202e32c8235997b3485b0b4655926ad97a1cc.zip
fsf-binutils-gdb-b03202e32c8235997b3485b0b4655926ad97a1cc.tar.gz
fsf-binutils-gdb-b03202e32c8235997b3485b0b4655926ad97a1cc.tar.bz2
bfd_get_size cache
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.
Diffstat (limited to 'bfd/bfdio.c')
-rw-r--r--bfd/bfdio.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/bfd/bfdio.c b/bfd/bfdio.c
index fd81b93..49e0958 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;
}
/*