Clear cached file size when bfd changed to BFD_IN_MEMORY
authorAlan Modra <amodra@gmail.com>
Wed, 8 Feb 2023 04:11:58 +0000 (14:41 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 8 Feb 2023 23:09:45 +0000 (09:39 +1030)
If file size is calculated by bfd_get_file_size, as it is by
_bfd_alloc_and_read calls in coff_object_p, then it is cached and when
pe_ILF_build_a_bfd converts an archive entry over to BFD_IN_MEMORY,
the file size is no longer valid.  Found when attempting objdump -t on
a very small (27 bytes) ILF file and hitting the pr24707 fix (commit
781152ec18f5).  So, clear file size when setting BFD_IN_MEMORY on bfds
that may have been read.  (It's not necessary in writable bfds,
because caching is ignored by bfd_get_size when bfd_write_p.)

I also think the PR 24707 fix is no longer neeeded.  All of the
testcases in that PR and in PR24712 are caught earlier by file size
checks when reading the symbols from file.  So I'm reverting that fix,
which just compared the size of an array of symbol pointers against
file size.  That's only valid if on-disk symbols are larger than a
host pointer, so the test is better done in format-specific code.

bfd/
* coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Clear cached
file size when making a BFD_IN_MEMORY bfd.
* opncls.c (bfd_make_readable): Likewise.
* peicode.h (pe_ILF_build_a_bfd): Likewise.
binutils/
PR 24707
* objdump.c (slurp_symtab): Revert PR24707 fix.  Tidy.
(slurp_dynamic_symtab): Tidy.

bfd/coff-alpha.c
bfd/opncls.c
bfd/peicode.h
binutils/objdump.c

index 61dc05e805dbc43cddf59ef39e1bc501660caca7..45b3f760f55e77b88d80c897b5409908174b0482 100644 (file)
@@ -2174,6 +2174,7 @@ alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos,
   nbfd->iostream = bim;
   nbfd->iovec = &_bfd_memory_iovec;
   nbfd->origin = 0;
+  nbfd->size = 0;
   BFD_ASSERT (! nbfd->cacheable);
 
   return nbfd;
index 6ae3af054e4b6d9457e3dc1cd0659db4a8247811..4dbd30d2fe95085ba510a79fe9b13d2c80aa1cb8 100644 (file)
@@ -987,6 +987,7 @@ bfd_make_readable (bfd *abfd)
   abfd->symcount = 0;
   abfd->outsymbols = 0;
   abfd->tdata.any = 0;
+  abfd->size = 0;
 
   bfd_section_list_clear (abfd);
   bfd_check_format (abfd, bfd_object);
index 22ffec989f294a81bfd6a206e5793dcf07b44387..fef7d0dd69b727e2297adaa51916b1b2584998b2 100644 (file)
@@ -1105,6 +1105,7 @@ pe_ILF_build_a_bfd (bfd *     abfd,
   abfd->iovec = &_bfd_memory_iovec;
   abfd->where = 0;
   abfd->origin = 0;
+  abfd->size = 0;
   obj_sym_filepos (abfd) = 0;
 
   /* Now create a symbol describing the imported value.  */
index 9e76684c0718992cdd639b50925db2a6393624b2..4292c23a9aba029c01f2b272d4d050040e1f1d1a 100644 (file)
@@ -994,45 +994,22 @@ dump_headers (bfd *abfd)
 static asymbol **
 slurp_symtab (bfd *abfd)
 {
-  asymbol **sy = NULL;
-  long storage;
-
+  symcount = 0;
   if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
-    {
-      symcount = 0;
-      return NULL;
-    }
+    return NULL;
 
-  storage = bfd_get_symtab_upper_bound (abfd);
+  long storage = bfd_get_symtab_upper_bound (abfd);
   if (storage < 0)
     {
-      non_fatal (_("failed to read symbol table from: %s"), bfd_get_filename (abfd));
+      non_fatal (_("failed to read symbol table from: %s"),
+                bfd_get_filename (abfd));
       bfd_fatal (_("error message was"));
     }
 
-  if (storage)
-    {
-      off_t filesize = bfd_get_file_size (abfd);
-
-      /* qv PR 24707.  */
-      if (filesize > 0
-         && filesize < storage
-         /* The MMO file format supports its own special compression
-            technique, so its sections can be larger than the file size.  */
-         && bfd_get_flavour (abfd) != bfd_target_mmo_flavour)
-       {
-         bfd_nonfatal_message (bfd_get_filename (abfd), abfd, NULL,
-                               _("error: symbol table size (%#lx) "
-                                 "is larger than filesize (%#lx)"),
-                               storage, (long) filesize);
-         exit_status = 1;
-         symcount = 0;
-         return NULL;
-       }
-
-      sy = (asymbol **) xmalloc (storage);
-    }
+  if (storage == 0)
+    return NULL;
 
+  asymbol **sy = (asymbol **) xmalloc (storage);
   symcount = bfd_canonicalize_symtab (abfd, sy);
   if (symcount < 0)
     bfd_fatal (bfd_get_filename (abfd));
@@ -1044,26 +1021,24 @@ slurp_symtab (bfd *abfd)
 static asymbol **
 slurp_dynamic_symtab (bfd *abfd)
 {
-  asymbol **sy = NULL;
-  long storage;
-
-  storage = bfd_get_dynamic_symtab_upper_bound (abfd);
+  dynsymcount = 0;
+  long storage = bfd_get_dynamic_symtab_upper_bound (abfd);
   if (storage < 0)
     {
       if (!(bfd_get_file_flags (abfd) & DYNAMIC))
        {
          non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd));
          exit_status = 1;
-         dynsymcount = 0;
          return NULL;
        }
 
       bfd_fatal (bfd_get_filename (abfd));
     }
 
-  if (storage)
-    sy = (asymbol **) xmalloc (storage);
+  if (storage == 0)
+    return NULL;
 
+  asymbol **sy = (asymbol **) xmalloc (storage);
   dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
   if (dynsymcount < 0)
     bfd_fatal (bfd_get_filename (abfd));