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.
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index fe2ffd3..58dbb56 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,15 @@
 2020-02-19  Alan Modra  <amodra@gmail.com>
 
+	* 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.
+
+2020-02-19  Alan Modra  <amodra@gmail.com>
+
 	* coffgen.c (_bfd_coff_get_external_symbols): Don't call
 	bfd_get_file_size twice.
 	(_bfd_coff_read_string_table): Allow for bfd_get_file_size
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 6b30f5f..2d56fda 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6497,12 +6497,6 @@
   /* 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;
 
@@ -6606,6 +6600,12 @@
    | 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;
@@ -6695,7 +6695,7 @@
 
   /* 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;
@@ -6706,6 +6706,11 @@
   /* 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/bfd.c b/bfd/bfd.c
index 574cebd..463f94b 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -85,12 +85,6 @@
 .  {* 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 @@
 .   | 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 @@
 .
 .  {* 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 @@
 .  {* 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 fd81b93..49e0958 100644
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -415,17 +415,32 @@
 	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 a03ad51..796202d 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -1209,6 +1209,7 @@
   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 @@
     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 @@
   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 @@
     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))