public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* warn unused result for bfd IO functions
@ 2023-08-10  3:33 Alan Modra
  2023-08-10  3:36 ` gdb: " Alan Modra
  0 siblings, 1 reply; 3+ messages in thread
From: Alan Modra @ 2023-08-10  3:33 UTC (permalink / raw)
  To: binutils

This patch fixes all the warnings I found in bfd, binutils and ld,
plus some bitrotted COFF_GO32 code that tried to allocate -168ul
bytes.  When the malloc fail was reported these testsuite fails
resulted:

i386-go32  +FAIL: go32 stub
i386-go32  +ERROR: tcl error sourcing /home/alan/src/binutils-gdb/ld/testsuite/ld-i386/i386.exp.
i386-go32  +ERROR: couldn't open "tmpdir/go32stub": no such file or directory
i386-go32  +FAIL: ld-scripts/sane1
i386-go32  +FAIL: ld-scripts/assign-loc
i386-go32  +FAIL: ld-scripts/pr18963

This does result in some warnings in gdb which are fixed in a followup
patch.

bfd/
	* bfdio.c (bfd_read, bfd_write): Add ATTRIBUTE_WARN_UNUSED_RESULT.
	(bfd_tell, bfd_stat, bfd_seek, bfd_mmap): Likewise.
	* bfd-in2.h: Regenerate.
	* coff-rs6000.c (xcoff_write_armap_big) Don't ignore bfd_write
	return value.
	(xcoff_generate_rtinit): Likewise.  Also free data_buffer and
	string_table before returning.
	* coff64-rs6000.c (xcoff64_generate_rtinit): Likewise.
	* coff-stgo32.c (go32exe_check_format): Don't ignore bfd_seek
	return value.
	* coffcode.h (coff_apply_checksum): Don't ignore bfd_write return.
	(coff_write_object_contents <COFF_GO32>): Likewise, and bfd_malloc.
	Fix bitrotted code to look for first section with non-zero filepos.
	* elf64-ia64-vms.c (elf64_vms_write_shdrs_and_ehdr): Don't ignore
	bfd_seek or bfd_write return values.
	* pef.c (bfd_pef_scan_section): Likewise.
	(bfd_pef_read_header, bfd_pef_xlib_read_header): Likewise.
	* vms-misc.c (_bfd_vms_output_end): Likewise.  Return status.
	* vms.h (_bfd_vms_output_end): Update prototype.
	* vms-alpha.c: Pass _bfd_vms_output_end status up call chains.
	* wasm-module.c (wasm_compute_custom_section_file_position): Don't
	ignore bfd_seek or bfd_write return values.
	(wasm_compute_section_file_positions): Likewise.
	* xsym.c (bfd_sym_scan): Don't ignore bfd_seek return value.
	(bfd_sym_read_name_table): Likewise.
binutils/
	* ar.c (print_contents, extract_file): Don't ignore bfd_seek
	return value.
ld/
	* pdb.c (create_section_contrib_substream): Don't ignore bfd_seek
	return value.
	(create_section_header_stream): Likewise.
	* pe-dll.c (pe_get16, pe_get32): Add fail param to return results
	from bfd_seek and bfd_read.
	(pe_implied_import_dll): Handle these fails, and other bfd_seek
	and bfd_read return values.

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index c405592618e..e2deb107494 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2722,17 +2722,19 @@ bfd_vma bfd_emul_get_commonpagesize (const char *);
 char *bfd_demangle (bfd *, const char *, int);
 
 /* Extracted from bfdio.c.  */
-bfd_size_type bfd_read (void *, bfd_size_type, bfd *);
+bfd_size_type bfd_read (void *, bfd_size_type, bfd *)
+ATTRIBUTE_WARN_UNUSED_RESULT;
 
-bfd_size_type bfd_write (const void *, bfd_size_type, bfd *);
+bfd_size_type bfd_write (const void *, bfd_size_type, bfd *)
+ATTRIBUTE_WARN_UNUSED_RESULT;
 
-file_ptr bfd_tell (bfd *);
+file_ptr bfd_tell (bfd *) ATTRIBUTE_WARN_UNUSED_RESULT;
 
 int bfd_flush (bfd *);
 
-int bfd_stat (bfd *, struct stat *);
+int bfd_stat (bfd *, struct stat *) ATTRIBUTE_WARN_UNUSED_RESULT;
 
-int bfd_seek (bfd *, file_ptr, int);
+int bfd_seek (bfd *, file_ptr, int) ATTRIBUTE_WARN_UNUSED_RESULT;
 
 long bfd_get_mtime (bfd *abfd);
 
@@ -2742,7 +2744,8 @@ ufile_ptr bfd_get_file_size (bfd *abfd);
 
 void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
     int prot, int flags, file_ptr offset,
-    void **map_addr, bfd_size_type *map_len);
+    void **map_addr, bfd_size_type *map_len)
+ATTRIBUTE_WARN_UNUSED_RESULT;
 
 /* Extracted from bfdwin.c.  */
 struct _bfd_window_internal;
diff --git a/bfd/bfdio.c b/bfd/bfdio.c
index 59ac1263007..457562f8c7c 100644
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -234,7 +234,8 @@ FUNCTION
 	bfd_read
 
 SYNOPSIS
-	bfd_size_type bfd_read (void *, bfd_size_type, bfd *);
+	bfd_size_type bfd_read (void *, bfd_size_type, bfd *)
+				ATTRIBUTE_WARN_UNUSED_RESULT;
 
 DESCRIPTION
 	Attempt to read SIZE bytes from ABFD's iostream to PTR.
@@ -299,7 +300,8 @@ FUNCTION
 	bfd_write
 
 SYNOPSIS
-	bfd_size_type bfd_write (const void *, bfd_size_type, bfd *);
+	bfd_size_type bfd_write (const void *, bfd_size_type, bfd *)
+				ATTRIBUTE_WARN_UNUSED_RESULT;
 
 DESCRIPTION
 	Attempt to write SIZE bytes to ABFD's iostream from PTR.
@@ -347,7 +349,7 @@ FUNCTION
 	bfd_tell
 
 SYNOPSIS
-	file_ptr bfd_tell (bfd *);
+	file_ptr bfd_tell (bfd *) ATTRIBUTE_WARN_UNUSED_RESULT;
 
 DESCRIPTION
 	Return ABFD's iostream file position.
@@ -404,7 +406,7 @@ FUNCTION
 	bfd_stat
 
 SYNOPSIS
-	int bfd_stat (bfd *, struct stat *);
+	int bfd_stat (bfd *, struct stat *) ATTRIBUTE_WARN_UNUSED_RESULT;
 
 DESCRIPTION
 	Call fstat on ABFD's iostream.  Return 0 on success, and a
@@ -437,7 +439,7 @@ FUNCTION
 	bfd_seek
 
 SYNOPSIS
-	int bfd_seek (bfd *, file_ptr, int);
+	int bfd_seek (bfd *, file_ptr, int) ATTRIBUTE_WARN_UNUSED_RESULT;
 
 DESCRIPTION
 	Call fseek on ABFD's iostream.  Return 0 on success, and a
@@ -638,7 +640,8 @@ FUNCTION
 SYNOPSIS
 	void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
 			int prot, int flags, file_ptr offset,
-			void **map_addr, bfd_size_type *map_len);
+			void **map_addr, bfd_size_type *map_len)
+			ATTRIBUTE_WARN_UNUSED_RESULT;
 
 DESCRIPTION
 	Return mmap()ed region of the file, if possible and implemented.
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 06d0fd854a6..7dd80a5c08f 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -2193,8 +2193,12 @@ xcoff_write_armap_big (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED,
 	    }
 	}
 
-      bfd_write (symbol_table, symbol_table_size, abfd);
-
+      if (bfd_write (symbol_table, symbol_table_size, abfd)
+	  != symbol_table_size)
+	{
+	  free (symbol_table);
+	  return false;
+	}
       free (symbol_table);
 
       prevoff = nextoff;
@@ -2273,8 +2277,12 @@ xcoff_write_armap_big (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED,
 	    }
 	}
 
-      bfd_write (symbol_table, symbol_table_size, abfd);
-
+      if (bfd_write (symbol_table, symbol_table_size, abfd)
+	  != symbol_table_size)
+	{
+	  free (symbol_table);
+	  return false;
+	}
       free (symbol_table);
 
       PRINT20 (fhdr->symoff64, nextoff);
@@ -4204,7 +4212,10 @@ xcoff_generate_rtinit  (bfd *abfd, const char *init, const char *fini,
       string_table_size += 4;
       string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
       if (string_table == NULL)
-	return false;
+	{
+	  free (data_buffer);
+	  return false;
+	}
 
       val = string_table_size;
       bfd_h_put_32 (abfd, val, &string_table[0]);
@@ -4354,18 +4365,21 @@ xcoff_generate_rtinit  (bfd *abfd, const char *init, const char *fini,
   filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
 
   bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
-  bfd_write (filehdr_ext, FILHSZ, abfd);
   bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
-  bfd_write (scnhdr_ext, SCNHSZ, abfd);
-  bfd_write (data_buffer, data_buffer_size, abfd);
-  bfd_write (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
-  bfd_write (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
-  bfd_write (string_table, string_table_size, abfd);
-
+  bool ret = true;
+  if (bfd_write (filehdr_ext, FILHSZ, abfd) != FILHSZ
+      || bfd_write (scnhdr_ext, SCNHSZ, abfd) != SCNHSZ
+      || bfd_write (data_buffer, data_buffer_size, abfd) != data_buffer_size
+      || (bfd_write (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd)
+	  != scnhdr.s_nreloc * RELSZ)
+      || (bfd_write (syment_ext, filehdr.f_nsyms * SYMESZ, abfd)
+	  != (bfd_size_type) filehdr.f_nsyms * SYMESZ)
+      || bfd_write (string_table, string_table_size, abfd) != string_table_size)
+    ret = false;
+
+  free (string_table);
   free (data_buffer);
-  data_buffer = NULL;
-
-  return true;
+  return ret;
 }
 
 
diff --git a/bfd/coff-stgo32.c b/bfd/coff-stgo32.c
index 84037702889..8f9087970b4 100644
--- a/bfd/coff-stgo32.c
+++ b/bfd/coff-stgo32.c
@@ -299,7 +299,8 @@ go32exe_check_format (bfd *abfd)
   /* Save now the stub to be used later.  Put the stub data to a temporary
      location first as tdata still does not exist.  It may not even
      be ever created if we are just checking the file format of ABFD.  */
-  bfd_seek (abfd, 0, SEEK_SET);
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+    goto fail;
   go32exe_temp_stub = bfd_malloc (stubsize);
   if (go32exe_temp_stub == NULL)
     goto fail;
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 8a7647afc98..54f9dcd5e5a 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -2232,7 +2232,10 @@ xcoff64_generate_rtinit (bfd *abfd, const char *init, const char *fini,
 
   string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
   if (string_table == NULL)
-    return false;
+    {
+      free (data_buffer);
+      return false;
+    }
 
   val = string_table_size;
   bfd_put_32 (abfd, val, &string_table[0]);
@@ -2383,20 +2386,23 @@ xcoff64_generate_rtinit (bfd *abfd, const char *init, const char *fini,
   filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
 
   bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
-  bfd_write (filehdr_ext, FILHSZ, abfd);
   bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
   bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
   bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
-  bfd_write (scnhdr_ext, 3 * SCNHSZ, abfd);
-  bfd_write (data_buffer, data_buffer_size, abfd);
-  bfd_write (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
-  bfd_write (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
-  bfd_write (string_table, string_table_size, abfd);
-
+  bool ret = true;
+  if (bfd_write (filehdr_ext, FILHSZ, abfd) != FILHSZ
+      || bfd_write (scnhdr_ext, 3 * SCNHSZ, abfd) != 3 * SCNHSZ
+      || bfd_write (data_buffer, data_buffer_size, abfd) != data_buffer_size
+      || (bfd_write (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd)
+	  != data_scnhdr.s_nreloc * RELSZ)
+      || (bfd_write (syment_ext, filehdr.f_nsyms * SYMESZ, abfd)
+	  != (bfd_size_type) filehdr.f_nsyms * SYMESZ)
+      || bfd_write (string_table, string_table_size, abfd) != string_table_size)
+    ret = false;
+
+  free (string_table);
   free (data_buffer);
-  data_buffer = NULL;
-
-  return true;
+  return ret;
 }
 
 /* The typical dynamic reloc.  */
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 99d9a5602d7..6789f7f3cc6 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -3411,7 +3411,8 @@ coff_apply_checksum (bfd *abfd)
     return false;
 
   checksum = 0;
-  bfd_write (&checksum, 4, abfd);
+  if (bfd_write (&checksum, 4, abfd) != 4)
+    return false;
 
   if (bfd_seek (abfd, peheader, SEEK_SET) != 0)
     return false;
@@ -3423,9 +3424,7 @@ coff_apply_checksum (bfd *abfd)
   if (bfd_seek (abfd, peheader + 0x58, SEEK_SET) != 0)
     return false;
 
-  bfd_write (&checksum, 4, abfd);
-
-  return true;
+  return bfd_write (&checksum, 4, abfd) == 4;
 }
 
 #endif /* COFF_IMAGE_WITH_PE */
@@ -3885,16 +3884,28 @@ coff_write_object_contents (bfd * abfd)
 
 #if defined (COFF_GO32_EXE) || defined (COFF_GO32)
   /* Pad section headers.  */
-  if ((abfd->flags & EXEC_P) && abfd->sections != NULL)
+  if ((abfd->flags & EXEC_P) != 0)
     {
-      file_ptr cur_ptr = scn_base
-			 + abfd->section_count * bfd_coff_scnhsz (abfd);
-      long fill_size = (abfd->sections->filepos - cur_ptr);
-      bfd_byte *b = bfd_zmalloc (fill_size);
-      if (b)
+      asection *s = abfd->sections;
+      while (s != NULL && s->filepos == 0)
+	s = s->next;
+      if (s != NULL)
 	{
-	  bfd_write (b, fill_size, abfd);
-	  free (b);
+	  file_ptr cur_ptr
+	    = scn_base + abfd->section_count * bfd_coff_scnhsz (abfd);
+	  file_ptr fill_size = s->filepos - cur_ptr;
+	  if (fill_size > 0)
+	    {
+	      bfd_byte *b = bfd_zmalloc (fill_size);
+	      if (!b)
+		return false;
+	      if (bfd_write (b, fill_size, abfd) != (ufile_ptr) fill_size)
+		{
+		  free (b);
+		  return false;
+		}
+	      free (b);
+	    }
 	}
     }
 #endif
diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c
index 28d30692b7d..f8e9922fc4a 100644
--- a/bfd/elf64-ia64-vms.c
+++ b/bfd/elf64-ia64-vms.c
@@ -4712,6 +4712,7 @@ elf64_vms_write_shdrs_and_ehdr (bfd *abfd)
 static bool
 elf64_vms_close_and_cleanup (bfd *abfd)
 {
+  bool ret = true;
   if (bfd_get_format (abfd) == bfd_object)
     {
       long isize;
@@ -4720,15 +4721,16 @@ elf64_vms_close_and_cleanup (bfd *abfd)
       isize = bfd_get_size (abfd);
       if ((isize & 7) != 0)
 	{
-	  int ishort = 8 - (isize & 7);
+	  unsigned int ishort = 8 - (isize & 7);
 	  uint64_t pad = 0;
 
-	  bfd_seek (abfd, isize, SEEK_SET);
-	  bfd_write (&pad, ishort, abfd);
+	  if (bfd_seek (abfd, isize, SEEK_SET) != 0
+	      || bfd_write (&pad, ishort, abfd) != ishort)
+	    ret = false;
 	}
     }
 
-  return _bfd_generic_close_and_cleanup (abfd);
+  return _bfd_generic_close_and_cleanup (abfd) && ret;
 }
 
 /* Add symbols from an ELF object file to the linker hash table.  */
diff --git a/bfd/pef.c b/bfd/pef.c
index 9c436a6fef7..79c7f9d3a70 100644
--- a/bfd/pef.c
+++ b/bfd/pef.c
@@ -386,8 +386,8 @@ bfd_pef_scan_section (bfd *abfd, bfd_pef_section *section)
 {
   unsigned char buf[28];
 
-  bfd_seek (abfd, section->header_offset, SEEK_SET);
-  if (bfd_read (buf, 28, abfd) != 28)
+  if (bfd_seek (abfd, section->header_offset, SEEK_SET) != 0
+      || bfd_read (buf, 28, abfd) != 28)
     return -1;
 
   section->name_offset = bfd_h_get_32 (abfd, buf);
@@ -568,9 +568,8 @@ bfd_pef_read_header (bfd *abfd, bfd_pef_header *header)
 {
   unsigned char buf[40];
 
-  bfd_seek (abfd, 0, SEEK_SET);
-
-  if (bfd_read (buf, 40, abfd) != 40)
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0
+      || bfd_read (buf, 40, abfd) != 40)
     return -1;
 
   header->tag1 = bfd_getb32 (buf);
@@ -1072,9 +1071,8 @@ bfd_pef_xlib_read_header (bfd *abfd, bfd_pef_xlib_header *header)
 {
   unsigned char buf[80];
 
-  bfd_seek (abfd, 0, SEEK_SET);
-
-  if (bfd_read (buf, sizeof buf, abfd) != sizeof buf)
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0
+      || bfd_read (buf, sizeof buf, abfd) != sizeof buf)
     return -1;
 
   header->tag1 = bfd_getb32 (buf);
diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
index 7fc73c655f2..f4d1e009d06 100644
--- a/bfd/vms-alpha.c
+++ b/bfd/vms-alpha.c
@@ -2923,7 +2923,7 @@ alpha_vms_object_p (bfd *abfd)
 
 /* Write an EMH/MHD record.  */
 
-static void
+static bool
 _bfd_vms_write_emh (bfd *abfd)
 {
   struct vms_rec_wr *recwr = &PRIV (recwr);
@@ -2952,12 +2952,12 @@ _bfd_vms_write_emh (bfd *abfd)
   _bfd_vms_output_counted (recwr, BFD_VERSION_STRING);
   _bfd_vms_output_dump (recwr, get_vms_time_string (tbuf), EMH_DATE_LENGTH);
   _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH);
-  _bfd_vms_output_end (abfd, recwr);
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 /* Write an EMH/LMN record.  */
 
-static void
+static bool
 _bfd_vms_write_lmn (bfd *abfd, const char *name)
 {
   char version [64];
@@ -2970,7 +2970,7 @@ _bfd_vms_write_lmn (bfd *abfd, const char *name)
   snprintf (version, sizeof (version), "%s %d.%d.%d", name,
 	    ver / 10000, (ver / 100) % 100, ver % 100);
   _bfd_vms_output_dump (recwr, (unsigned char *)version, strlen (version));
-  _bfd_vms_output_end (abfd, recwr);
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 
@@ -3008,8 +3008,7 @@ _bfd_vms_write_eeom (bfd *abfd)
       _bfd_vms_output_long (recwr, 0);
     }
 
-  _bfd_vms_output_end (abfd, recwr);
-  return true;
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 static void *
@@ -3484,8 +3483,9 @@ alpha_vms_write_exec (bfd *abfd)
       struct vms_rec_wr *recwr = &PRIV (recwr);
       unsigned int i;
 
-      _bfd_vms_write_emh (abfd);
-      _bfd_vms_write_lmn (abfd, "GNU LD");
+      if (!_bfd_vms_write_emh (abfd)
+	  || !_bfd_vms_write_lmn (abfd, "GNU LD"))
+	return false;
 
       /* PSC for the absolute section.  */
       _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
@@ -3496,7 +3496,8 @@ alpha_vms_write_exec (bfd *abfd)
       _bfd_vms_output_long (recwr, 0);
       _bfd_vms_output_counted (recwr, ".$$ABS$$.");
       _bfd_vms_output_end_subrec (recwr);
-      _bfd_vms_output_end (abfd, recwr);
+      if (!_bfd_vms_output_end (abfd, recwr))
+	return false;
 
       for (i = 0; i < PRIV (gsd_sym_count); i++)
 	{
@@ -3529,11 +3530,13 @@ alpha_vms_write_exec (bfd *abfd)
 	  _bfd_vms_output_long (recwr, 0);
 	  _bfd_vms_output_counted (recwr, sym->name);
 	  _bfd_vms_output_end_subrec (recwr);
-	  if ((i % 5) == 4)
-	    _bfd_vms_output_end (abfd, recwr);
+	  if ((i % 5) == 4
+	      && !_bfd_vms_output_end (abfd, recwr))
+	    return false;
 	}
-      if ((i % 5) != 0)
-	_bfd_vms_output_end (abfd, recwr);
+      if ((i % 5) != 0
+	  && !_bfd_vms_output_end (abfd, recwr))
+	return false;
 
       if (!_bfd_vms_write_eeom (abfd))
 	return false;
@@ -3591,7 +3594,8 @@ _bfd_vms_write_egsd (bfd *abfd)
       /* 13 bytes egsd, max 31 chars name -> should be 44 bytes.  */
       if (_bfd_vms_output_check (recwr, 64) < 0)
 	{
-	  _bfd_vms_output_end (abfd, recwr);
+	  if (!_bfd_vms_output_end (abfd, recwr))
+	    return false;
 	  _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
 	  _bfd_vms_output_long (recwr, 0);
 	}
@@ -3687,7 +3691,8 @@ _bfd_vms_write_egsd (bfd *abfd)
 	 bytes for a possible ABS section.  */
       if (_bfd_vms_output_check (recwr, 80 + 16) < 0)
 	{
-	  _bfd_vms_output_end (abfd, recwr);
+	  if (!_bfd_vms_output_end (abfd, recwr))
+	    return false;
 	  _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
 	  _bfd_vms_output_long (recwr, 0);
 	}
@@ -3766,9 +3771,7 @@ _bfd_vms_write_egsd (bfd *abfd)
     }
 
   _bfd_vms_output_alignment (recwr, 8);
-  _bfd_vms_output_end (abfd, recwr);
-
-  return true;
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 /* Write object header for bfd abfd.  Return FALSE on error.  */
@@ -3784,8 +3787,9 @@ _bfd_vms_write_ehdr (bfd *abfd)
 
   _bfd_vms_output_alignment (recwr, 2);
 
-  _bfd_vms_write_emh (abfd);
-  _bfd_vms_write_lmn (abfd, "GNU AS");
+  if (!_bfd_vms_write_emh (abfd)
+      || !_bfd_vms_write_lmn (abfd, "GNU AS"))
+    return false;
 
   /* SRC.  */
   _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
@@ -3806,13 +3810,15 @@ _bfd_vms_write_ehdr (bfd *abfd)
   if (symnum == abfd->symcount)
     _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("noname"));
 
-  _bfd_vms_output_end (abfd, recwr);
+  if (!_bfd_vms_output_end (abfd, recwr))
+    return false;
 
   /* TTL.  */
   _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
   _bfd_vms_output_short (recwr, EMH__C_TTL);
   _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("TTL"));
-  _bfd_vms_output_end (abfd, recwr);
+  if (!_bfd_vms_output_end (abfd, recwr))
+    return false;
 
   /* CPR.  */
   _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
@@ -3820,9 +3826,7 @@ _bfd_vms_write_ehdr (bfd *abfd)
   _bfd_vms_output_dump (recwr,
 			(unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
 			 39);
-  _bfd_vms_output_end (abfd, recwr);
-
-  return true;
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 /* Part 4.6, relocations.  */
@@ -3834,12 +3838,12 @@ _bfd_vms_write_ehdr (bfd *abfd)
 
 /* Close the etir/etbt record.  */
 
-static void
+static bool
 end_etir_record (bfd * abfd)
 {
   struct vms_rec_wr *recwr = &PRIV (recwr);
 
-  _bfd_vms_output_end (abfd, recwr);
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 static void
@@ -3885,7 +3889,7 @@ start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset)
 /* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual
    address VADDR in section specified by SEC_INDEX and NAME.  */
 
-static void
+static bool
 sto_imm (bfd *abfd, asection *section,
 	 bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr)
 {
@@ -3905,7 +3909,8 @@ sto_imm (bfd *abfd, asection *section,
       if (_bfd_vms_output_check (recwr, size) < 0)
 	{
 	  /* Doesn't fit, split !  */
-	  end_etir_record (abfd);
+	  if (!end_etir_record (abfd))
+	    return false;
 
 	  start_etir_or_etbt_record (abfd, section, vaddr);
 
@@ -3928,17 +3933,20 @@ sto_imm (bfd *abfd, asection *section,
       cptr += size;
       ssize -= size;
     }
+  return true;
 }
 
-static void
+static bool
 etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen)
 {
   if (_bfd_vms_output_check (&PRIV (recwr), checklen) < 0)
     {
       /* Not enough room in this record.  Close it and open a new one.  */
-      end_etir_record (abfd);
+      if (!end_etir_record (abfd))
+	return false;
       start_etir_or_etbt_record (abfd, section, vaddr);
     }
+  return true;
 }
 
 /* Return whether RELOC must be deferred till the end.  */
@@ -4056,7 +4064,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		    _bfd_error_handler (_("size error in section %pA"),
 					section);
 		  size = addr - curr_addr;
-		  sto_imm (abfd, section, size, curr_data, curr_addr);
+		  if (!sto_imm (abfd, section, size, curr_data, curr_addr))
+		    return false;
 		  curr_data += size;
 		  curr_addr += size;
 		}
@@ -4073,7 +4082,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		    {
 		      bfd_vma addend = rptr->addend;
 		      slen = strlen ((char *) sym->name);
-		      etir_output_check (abfd, section, curr_addr, slen);
+		      if (!etir_output_check (abfd, section, curr_addr, slen))
+			return false;
 		      if (addend)
 			{
 			  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
@@ -4097,7 +4107,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		    }
 		  else if (bfd_is_abs_section (sym->section))
 		    {
-		      etir_output_check (abfd, section, curr_addr, 16);
+		      if (!etir_output_check (abfd, section, curr_addr, 16))
+			return false;
 		      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
 		      _bfd_vms_output_long (recwr, (unsigned long) sym->value);
 		      _bfd_vms_output_end_subrec (recwr);
@@ -4106,7 +4117,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		    }
 		  else
 		    {
-		      etir_output_check (abfd, section, curr_addr, 32);
+		      if (!etir_output_check (abfd, section, curr_addr, 32))
+			return false;
 		      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
 		      _bfd_vms_output_long (recwr,
 					    (unsigned long) sec->target_index);
@@ -4126,7 +4138,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		    {
 		      bfd_vma addend = rptr->addend;
 		      slen = strlen ((char *) sym->name);
-		      etir_output_check (abfd, section, curr_addr, slen);
+		      if (!etir_output_check (abfd, section, curr_addr, slen))
+			return false;
 		      if (addend)
 			{
 			  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
@@ -4149,7 +4162,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		    }
 		  else if (bfd_is_abs_section (sym->section))
 		    {
-		      etir_output_check (abfd, section, curr_addr, 16);
+		      if (!etir_output_check (abfd, section, curr_addr, 16))
+			return false;
 		      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
 		      _bfd_vms_output_quad (recwr, sym->value);
 		      _bfd_vms_output_end_subrec (recwr);
@@ -4158,7 +4172,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		    }
 		  else
 		    {
-		      etir_output_check (abfd, section, curr_addr, 32);
+		      if (!etir_output_check (abfd, section, curr_addr, 32))
+			return false;
 		      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
 		      _bfd_vms_output_long (recwr,
 					    (unsigned long) sec->target_index);
@@ -4170,12 +4185,14 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		  break;
 
 		case ALPHA_R_HINT:
-		  sto_imm (abfd, section, size, curr_data, curr_addr);
+		  if (!sto_imm (abfd, section, size, curr_data, curr_addr))
+		    return false;
 		  break;
 
 		case ALPHA_R_LINKAGE:
 		  size = 16;
-		  etir_output_check (abfd, section, curr_addr, 64);
+		  if (!etir_output_check (abfd, section, curr_addr, 64))
+		    return false;
 		  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
 		  _bfd_vms_output_long
 		    (recwr, (unsigned long) rptr->addend);
@@ -4188,7 +4205,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 
 		case ALPHA_R_CODEADDR:
 		  slen = strlen ((char *) sym->name);
-		  etir_output_check (abfd, section, curr_addr, slen);
+		  if (!etir_output_check (abfd, section, curr_addr, slen))
+		    return false;
 		  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_CA);
 		  _bfd_vms_output_counted (recwr, sym->name);
 		  _bfd_vms_output_end_subrec (recwr);
@@ -4197,8 +4215,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		case ALPHA_R_NOP:
 		  udata
 		    = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
-		  etir_output_check (abfd, section, curr_addr,
-				     32 + 1 + strlen (udata->origname));
+		  if (!etir_output_check (abfd, section, curr_addr,
+					  32 + 1 + strlen (udata->origname)))
+		    return false;
 		  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_NOP_GBL);
 		  _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
 		  _bfd_vms_output_long
@@ -4219,8 +4238,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		case ALPHA_R_LDA:
 		  udata
 		    = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
-		  etir_output_check (abfd, section, curr_addr,
-				     32 + 1 + strlen (udata->origname));
+		  if (!etir_output_check (abfd, section, curr_addr,
+					  32 + 1 + strlen (udata->origname)))
+		    return false;
 		  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LDA_GBL);
 		  _bfd_vms_output_long
 		    (recwr, (unsigned long) udata->lkindex + 1);
@@ -4238,8 +4258,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		case ALPHA_R_BOH:
 		  udata
 		    = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
-		  etir_output_check (abfd, section, curr_addr,
-				       32 + 1 + strlen (udata->origname));
+		  if (!etir_output_check (abfd, section, curr_addr,
+					  32 + 1 + strlen (udata->origname)))
+		    return false;
 		  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_BOH_GBL);
 		  _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
 		  _bfd_vms_output_long
@@ -4272,7 +4293,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		  return false;
 		}
 	      size = section->size - curr_addr;
-	      sto_imm (abfd, section, size, curr_data, curr_addr);
+	      if (!sto_imm (abfd, section, size, curr_data, curr_addr))
+		return false;
 	      curr_data += size;
 	      curr_addr += size;
 
@@ -4285,9 +4307,11 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 	}
 
       else /* (section->flags & SEC_RELOC) */
-	sto_imm (abfd, section, section->size, section->contents, 0);
+	if (!sto_imm (abfd, section, section->size, section->contents, 0))
+	  return false;
 
-      end_etir_record (abfd);
+      if (!end_etir_record (abfd))
+	return false;
     }
 
   _bfd_vms_output_alignment (recwr, 2);
diff --git a/bfd/vms-misc.c b/bfd/vms-misc.c
index 833e5a3deb7..75cac636ea3 100644
--- a/bfd/vms-misc.c
+++ b/bfd/vms-misc.c
@@ -269,7 +269,7 @@ _bfd_vms_output_end_subrec (struct vms_rec_wr *recwr)
 
 /* Ends current record (and write it).  */
 
-void
+bool
 _bfd_vms_output_end (bfd *abfd, struct vms_rec_wr *recwr)
 {
   vms_debug2 ((6, "_bfd_vms_output_end (size %u)\n", recwr->size));
@@ -278,7 +278,7 @@ _bfd_vms_output_end (bfd *abfd, struct vms_rec_wr *recwr)
   BFD_ASSERT (recwr->subrec_offset == 0);
 
   if (recwr->size == 0)
-    return;
+    return true;
 
   _bfd_vms_output_align (recwr, recwr->size);
 
@@ -289,16 +289,20 @@ _bfd_vms_output_end (bfd *abfd, struct vms_rec_wr *recwr)
      converted to variable length (VAR) format.  VAR format has a length
      word first which must be explicitly output in UDF format.  */
   /* So, first the length word.  */
-  bfd_write (recwr->buf + 2, 2, abfd);
+  if (bfd_write (recwr->buf + 2, 2, abfd) != 2)
+    return false;
 
   /* Align.  */
   if (recwr->size & 1)
     recwr->buf[recwr->size++] = 0;
 
   /* Then the record.  */
-  bfd_write (recwr->buf, (size_t) recwr->size, abfd);
+  if (bfd_write (recwr->buf, (size_t) recwr->size, abfd)
+      != (size_t) recwr->size)
+    return false;
 
   recwr->size = 0;
+  return true;
 }
 
 /* Check remaining buffer size.  Return what's left.  */
diff --git a/bfd/vms.h b/bfd/vms.h
index 47999006ff5..90efe7d7902 100644
--- a/bfd/vms.h
+++ b/bfd/vms.h
@@ -124,7 +124,7 @@ extern void   _bfd_vms_output_begin (struct vms_rec_wr *, int);
 extern void   _bfd_vms_output_alignment (struct vms_rec_wr *, int);
 extern void   _bfd_vms_output_begin_subrec (struct vms_rec_wr *, int);
 extern void   _bfd_vms_output_end_subrec (struct vms_rec_wr *);
-extern void   _bfd_vms_output_end (bfd *, struct vms_rec_wr *);
+extern bool   _bfd_vms_output_end (bfd *, struct vms_rec_wr *);
 extern int    _bfd_vms_output_check (struct vms_rec_wr *, int);
 extern void   _bfd_vms_output_byte (struct vms_rec_wr *, unsigned);
 extern void   _bfd_vms_output_short (struct vms_rec_wr *, unsigned);
diff --git a/bfd/wasm-module.c b/bfd/wasm-module.c
index d887f44ac6c..d97da1519a7 100644
--- a/bfd/wasm-module.c
+++ b/bfd/wasm-module.c
@@ -548,8 +548,8 @@ wasm_compute_custom_section_file_position (bfd *abfd,
 	}
       while (nl);
 
-      bfd_seek (abfd, fs->pos, SEEK_SET);
-      if (! wasm_write_uleb128 (abfd, 0)
+      if (bfd_seek (abfd, fs->pos, SEEK_SET) != 0
+	  || ! wasm_write_uleb128 (abfd, 0)
 	  || ! wasm_write_uleb128 (abfd, payload_len)
 	  || ! wasm_write_uleb128 (abfd, name_len)
 	  || bfd_write (name, name_len, abfd) != name_len)
@@ -586,9 +586,8 @@ wasm_compute_section_file_positions (bfd *abfd)
   struct compute_section_arg fs;
   unsigned int i;
 
-  bfd_seek (abfd, (bfd_vma) 0, SEEK_SET);
-
-  if (bfd_write (magic, sizeof (magic), abfd) != (sizeof magic)
+  if (bfd_seek (abfd, (bfd_vma) 0, SEEK_SET) != 0
+      || bfd_write (magic, sizeof (magic), abfd) != (sizeof magic)
       || bfd_write (vers, sizeof (vers), abfd) != sizeof (vers))
     return false;
 
diff --git a/bfd/xsym.c b/bfd/xsym.c
index 828f752817c..275b1b08369 100644
--- a/bfd/xsym.c
+++ b/bfd/xsym.c
@@ -2207,8 +2207,8 @@ bfd_sym_scan (bfd *abfd, bfd_sym_version version, bfd_sym_data_struct *mdata)
   mdata->sbfd = abfd;
   mdata->version = version;
 
-  bfd_seek (abfd, 0, SEEK_SET);
-  if (bfd_sym_read_header (abfd, &mdata->header, mdata->version) != 0)
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0
+      || bfd_sym_read_header (abfd, &mdata->header, mdata->version) != 0)
     return -1;
 
   mdata->name_table = bfd_sym_read_name_table (abfd, &mdata->header);
@@ -2236,8 +2236,8 @@ bfd_sym_object_p (bfd *abfd)
   bfd_sym_version version = -1;
   bfd_sym_data_struct *mdata;
 
-  bfd_seek (abfd, 0, SEEK_SET);
-  if (bfd_sym_read_version (abfd, &version) != 0)
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0
+      || bfd_sym_read_version (abfd, &version) != 0)
     goto wrong;
 
   mdata = (bfd_sym_data_struct *) bfd_alloc (abfd, sizeof (*mdata));
diff --git a/binutils/ar.c b/binutils/ar.c
index 97bf34bb8cf..fe2d971962a 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -1078,7 +1078,8 @@ print_contents (bfd *abfd)
   if (verbose)
     printf ("\n<%s>\n\n", bfd_get_filename (abfd));
 
-  bfd_seek (abfd, 0, SEEK_SET);
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+    bfd_fatal (bfd_get_filename (abfd));
 
   size = buf.st_size;
   while (ncopied < size)
@@ -1176,7 +1177,8 @@ extract_file (bfd *abfd)
     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
   size = buf.st_size;
 
-  bfd_seek (abfd, 0, SEEK_SET);
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+    bfd_fatal (bfd_get_filename (abfd));
 
   output_file = NULL;
   if (size == 0)
diff --git a/ld/pdb.c b/ld/pdb.c
index 96fc3f13e27..fa3e4a11d27 100644
--- a/ld/pdb.c
+++ b/ld/pdb.c
@@ -4185,10 +4185,9 @@ create_section_contrib_substream (bfd *abfd, void **data, uint32_t *size)
 
   for (unsigned int i = 0; i < abfd->section_count; i++)
     {
-      bfd_seek (abfd, offset, SEEK_SET);
-
-      if (bfd_read (sect_flags + (i * sizeof (uint32_t)), sizeof (uint32_t),
-		     abfd) != sizeof (uint32_t))
+      if (bfd_seek (abfd, offset, SEEK_SET) != 0
+	  || bfd_read (sect_flags + (i * sizeof (uint32_t)), sizeof (uint32_t),
+		       abfd) != sizeof (uint32_t))
 	{
 	  free (*data);
 	  free (sect_flags);
@@ -4993,7 +4992,8 @@ create_section_header_stream (bfd *pdb, bfd *abfd, uint16_t *num)
 
   scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
 
-  bfd_seek (abfd, scn_base, SEEK_SET);
+  if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
+    return false;
 
   len = section_count * sizeof (struct external_scnhdr);
   buf = xmalloc (len);
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index 65bb50bc5b9..df08a57e644 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -3419,22 +3419,30 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
    handled, FALSE if not.  */
 
 static unsigned int
-pe_get16 (bfd *abfd, int where)
+pe_get16 (bfd *abfd, int where, bool *fail)
 {
   unsigned char b[2];
 
-  bfd_seek (abfd, where, SEEK_SET);
-  bfd_read (b, 2, abfd);
+  if (bfd_seek (abfd, where, SEEK_SET) != 0
+      || bfd_read (b, 2, abfd) != 2)
+    {
+      *fail = true;
+      return 0;
+    }
   return b[0] + (b[1] << 8);
 }
 
 static unsigned int
-pe_get32 (bfd *abfd, int where)
+pe_get32 (bfd *abfd, int where, bool *fail)
 {
   unsigned char b[4];
 
-  bfd_seek (abfd, where, SEEK_SET);
-  bfd_read (b, 4, abfd);
+  if (bfd_seek (abfd, where, SEEK_SET) != 0
+      || bfd_read (b, 4, abfd) != 4)
+    {
+      *fail = true;
+      return 0;
+    }
   return b[0] + (b[1] << 8) + (b[2] << 16) + ((unsigned) b[3] << 24);
 }
 
@@ -3481,38 +3489,49 @@ pe_implied_import_dll (const char *filename)
   /* PEI dlls seem to be bfd_objects.  */
   if (!bfd_check_format (dll, bfd_object))
     {
+    notdll:
       einfo (_("%X%P: %s: this doesn't appear to be a DLL\n"), filename);
       return false;
     }
 
   /* Get pe_header, optional header and numbers of directory entries.  */
-  pe_header_offset = pe_get32 (dll, 0x3c);
+  bool fail = false;
+  pe_header_offset = pe_get32 (dll, 0x3c, &fail);
+  if (fail)
+    goto notdll;
   opthdr_ofs = pe_header_offset + 4 + 20;
 #ifdef pe_use_plus
-  num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4); /*  & NumberOfRvaAndSizes.  */
+  /* NumberOfRvaAndSizes.  */
+  num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4, &fail);
 #else
-  num_entries = pe_get32 (dll, opthdr_ofs + 92);
+  num_entries = pe_get32 (dll, opthdr_ofs + 92, &fail);
 #endif
+  if (fail)
+    goto notdll;
 
   /* No import or export directory entry.  */
   if (num_entries < 1)
     return false;
 
 #ifdef pe_use_plus
-  export_rva  = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4);
-  export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4);
+  export_rva  = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4, &fail);
+  export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4, &fail);
 #else
-  export_rva = pe_get32 (dll, opthdr_ofs + 96);
-  export_size = pe_get32 (dll, opthdr_ofs + 100);
+  export_rva = pe_get32 (dll, opthdr_ofs + 96, &fail);
+  export_size = pe_get32 (dll, opthdr_ofs + 100, &fail);
 #endif
+  if (fail)
+    goto notdll;
 
   /* No export table - nothing to export.  */
   if (export_size == 0)
     return false;
 
-  nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
+  nsections = pe_get16 (dll, pe_header_offset + 4 + 2, &fail);
   secptr = (pe_header_offset + 4 + 20 +
-	    pe_get16 (dll, pe_header_offset + 4 + 16));
+	    pe_get16 (dll, pe_header_offset + 4 + 16, &fail));
+  if (fail)
+    goto notdll;
   expptr = 0;
 
   /* Get the rva and size of the export section.  */
@@ -3520,12 +3539,14 @@ pe_implied_import_dll (const char *filename)
     {
       char sname[8];
       bfd_vma secptr1 = secptr + 40 * i;
-      bfd_vma vaddr = pe_get32 (dll, secptr1 + 12);
-      bfd_vma vsize = pe_get32 (dll, secptr1 + 16);
-      bfd_vma fptr = pe_get32 (dll, secptr1 + 20);
+      bfd_vma vaddr = pe_get32 (dll, secptr1 + 12, &fail);
+      bfd_vma vsize = pe_get32 (dll, secptr1 + 16, &fail);
+      bfd_vma fptr = pe_get32 (dll, secptr1 + 20, &fail);
 
-      bfd_seek (dll, secptr1, SEEK_SET);
-      bfd_read (sname, 8, dll);
+      if (fail
+	  || bfd_seek (dll, secptr1, SEEK_SET) != 0
+	  || bfd_read (sname, 8, dll) != 8)
+	goto notdll;
 
       if (vaddr <= export_rva && vaddr + vsize > export_rva)
 	{
@@ -3541,14 +3562,16 @@ pe_implied_import_dll (const char *filename)
   for (i = 0; i < nsections; i++)
     {
       bfd_vma secptr1 = secptr + 40 * i;
-      bfd_vma vsize = pe_get32 (dll, secptr1 + 8);
-      bfd_vma vaddr = pe_get32 (dll, secptr1 + 12);
-      bfd_vma flags = pe_get32 (dll, secptr1 + 36);
+      bfd_vma vsize = pe_get32 (dll, secptr1 + 8, &fail);
+      bfd_vma vaddr = pe_get32 (dll, secptr1 + 12, &fail);
+      bfd_vma flags = pe_get32 (dll, secptr1 + 36, &fail);
       char sec_name[9];
 
       sec_name[8] = '\0';
-      bfd_seek (dll, secptr1 + 0, SEEK_SET);
-      bfd_read (sec_name, 8, dll);
+      if (fail
+	  || bfd_seek (dll, secptr1 + 0, SEEK_SET) != 0
+	  || bfd_read (sec_name, 8, dll) != 8)
+	goto notdll;
 
       if (strcmp(sec_name,".data") == 0)
 	{
@@ -3583,8 +3606,9 @@ pe_implied_import_dll (const char *filename)
     }
 
   expdata = xmalloc (export_size);
-  bfd_seek (dll, expptr, SEEK_SET);
-  bfd_read (expdata, export_size, dll);
+  if (bfd_seek (dll, expptr, SEEK_SET) != 0
+      || bfd_read (expdata, export_size, dll) != export_size)
+    goto notdll;
   erva = (char *) expdata - export_rva;
 
   if (pe_def_file == 0)

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 3+ messages in thread

* gdb: warn unused result for bfd IO functions
  2023-08-10  3:33 warn unused result for bfd IO functions Alan Modra
@ 2023-08-10  3:36 ` Alan Modra
  2023-08-11 12:15   ` Andrew Burgess
  0 siblings, 1 reply; 3+ messages in thread
From: Alan Modra @ 2023-08-10  3:36 UTC (permalink / raw)
  To: binutils, gdb-patches

From 3dd00a9f25bc78028ba4b3820b45d34f51c4a25d Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Wed, 9 Aug 2023 09:58:36 +0930
Subject: 

This fixes the compilation warnings introduced by my bfdio.c patch.

The removed bfd_seeks in coff_symfile_read date back to 1994, commit
7f4c859520, prior to which the file used stdio rather than bfd to read
symbols.  Since it now uses bfd to read the file there should be no
need to synchronise to bfd's idea of the file position.  I also fixed
a potential uninitialised memory access.

OK to apply?

diff --git a/gdb/coff-pe-read.c b/gdb/coff-pe-read.c
index b82b43c84cf..34360eb72f1 100644
--- a/gdb/coff-pe-read.c
+++ b/gdb/coff-pe-read.c
@@ -254,23 +254,31 @@ read_pe_truncate_name (char *dll_name)
 \f
 /* Low-level support functions, direct from the ld module pe-dll.c.  */
 static unsigned int
-pe_get16 (bfd *abfd, int where)
+pe_get16 (bfd *abfd, int where, bool *fail)
 {
   unsigned char b[2];
 
-  bfd_seek (abfd, (file_ptr) where, SEEK_SET);
-  bfd_read (b, (bfd_size_type) 2, abfd);
+  if (bfd_seek (abfd, where, SEEK_SET) != 0
+      || bfd_read (b, 2, abfd) != 2)
+    {
+      *fail = true;
+      return 0;
+    }
   return b[0] + (b[1] << 8);
 }
 
 static unsigned int
-pe_get32 (bfd *abfd, int where)
+pe_get32 (bfd *abfd, int where, bool *fail)
 {
   unsigned char b[4];
 
-  bfd_seek (abfd, (file_ptr) where, SEEK_SET);
-  bfd_read (b, (bfd_size_type) 4, abfd);
-  return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
+  if (bfd_seek (abfd, where, SEEK_SET) != 0
+      || bfd_read (b, 4, abfd) != 4)
+    {
+      *fail = true;
+      return 0;
+    }
+  return b[0] + (b[1] << 8) + (b[2] << 16) + ((unsigned) b[3] << 24);
 }
 
 static unsigned int
@@ -286,7 +294,7 @@ pe_as32 (void *ptr)
 {
   unsigned char *b = (unsigned char *) ptr;
 
-  return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
+  return b[0] + (b[1] << 8) + (b[2] << 16) + ((unsigned) b[3] << 24);
 }
 \f
 /* Read the (non-debug) export symbol table from a portable
@@ -340,32 +348,46 @@ read_pe_exported_syms (minimal_symbol_reader &reader,
       /* This is not a recognized PE format file.  Abort now, because
 	 the code is untested on anything else.  *FIXME* test on
 	 further architectures and loosen or remove this test.  */
+    notdll:
+      if (debug_coff_pe_read)
+	gdb_printf (gdb_stdlog, _("%s doesn't appear to be a DLL\n"),
+		    bfd_get_filename (dll));
       return;
     }
 
   /* Get pe_header, optional header and numbers of export entries.  */
-  pe_header_offset = pe_get32 (dll, 0x3c);
+  bool fail = false;
+  pe_header_offset = pe_get32 (dll, 0x3c, &fail);
+  if (fail)
+    goto notdll;
   opthdr_ofs = pe_header_offset + 4 + 20;
   if (is_pe64)
-    num_entries = pe_get32 (dll, opthdr_ofs + 108);
+    num_entries = pe_get32 (dll, opthdr_ofs + 108, &fail);
   else
-    num_entries = pe_get32 (dll, opthdr_ofs + 92);
+    num_entries = pe_get32 (dll, opthdr_ofs + 92, &fail);
+  if (fail)
+    goto notdll;
 
   if (num_entries < 1)		/* No exports.  */
     return;
   if (is_pe64)
     {
-      export_opthdrrva = pe_get32 (dll, opthdr_ofs + 112);
-      export_opthdrsize = pe_get32 (dll, opthdr_ofs + 116);
+      export_opthdrrva = pe_get32 (dll, opthdr_ofs + 112, &fail);
+      export_opthdrsize = pe_get32 (dll, opthdr_ofs + 116, &fail);
     }
   else
     {
-      export_opthdrrva = pe_get32 (dll, opthdr_ofs + 96);
-      export_opthdrsize = pe_get32 (dll, opthdr_ofs + 100);
+      export_opthdrrva = pe_get32 (dll, opthdr_ofs + 96, &fail);
+      export_opthdrsize = pe_get32 (dll, opthdr_ofs + 100, &fail);
     }
-  nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
+  if (fail)
+    goto notdll;
+
+  nsections = pe_get16 (dll, pe_header_offset + 4 + 2, &fail);
   secptr = (pe_header_offset + 4 + 20 +
-	    pe_get16 (dll, pe_header_offset + 4 + 16));
+	    pe_get16 (dll, pe_header_offset + 4 + 16, &fail));
+  if (fail)
+    goto notdll;
   expptr = 0;
   export_size = 0;
 
@@ -374,12 +396,13 @@ read_pe_exported_syms (minimal_symbol_reader &reader,
     {
       char sname[8];
       unsigned long secptr1 = secptr + 40 * i;
-      unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
-      unsigned long vsize = pe_get32 (dll, secptr1 + 16);
-      unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+      unsigned long vaddr = pe_get32 (dll, secptr1 + 12, &fail);
+      unsigned long vsize = pe_get32 (dll, secptr1 + 16, &fail);
+      unsigned long fptr = pe_get32 (dll, secptr1 + 20, &fail);
 
-      bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);
-      bfd_read (sname, (bfd_size_type) sizeof (sname), dll);
+      if (fail
+	  || bfd_seek (dll, secptr1, SEEK_SET) != 0
+	  || bfd_read (sname, sizeof (sname), dll) != sizeof (sname))
 
       if ((strcmp (sname, ".edata") == 0)
 	  || (vaddr <= export_opthdrrva && export_opthdrrva < vaddr + vsize))
@@ -420,16 +443,18 @@ read_pe_exported_syms (minimal_symbol_reader &reader,
   for (i = 0; i < nsections; i++)
     {
       unsigned long secptr1 = secptr + 40 * i;
-      unsigned long vsize = pe_get32 (dll, secptr1 + 8);
-      unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
-      unsigned long characteristics = pe_get32 (dll, secptr1 + 36);
+      unsigned long vsize = pe_get32 (dll, secptr1 + 8, &fail);
+      unsigned long vaddr = pe_get32 (dll, secptr1 + 12, &fail);
+      unsigned long characteristics = pe_get32 (dll, secptr1 + 36, &fail);
       char sec_name[SCNNMLEN + 1];
       int sectix;
       unsigned int bfd_section_index;
       asection *section;
 
-      bfd_seek (dll, (file_ptr) secptr1 + 0, SEEK_SET);
-      bfd_read (sec_name, (bfd_size_type) SCNNMLEN, dll);
+      if (fail
+	  || bfd_seek (dll, secptr1 + 0, SEEK_SET) != 0
+	  || bfd_read (sec_name, SCNNMLEN, dll) != SCNNMLEN)
+	goto notdll;
       sec_name[SCNNMLEN] = '\0';
 
       sectix = read_pe_section_index (sec_name);
@@ -468,8 +493,9 @@ read_pe_exported_syms (minimal_symbol_reader &reader,
   gdb::def_vector<unsigned char> expdata_storage (export_size);
   expdata = expdata_storage.data ();
 
-  bfd_seek (dll, (file_ptr) expptr, SEEK_SET);
-  bfd_read (expdata, (bfd_size_type) export_size, dll);
+  if (bfd_seek (dll, expptr, SEEK_SET) != 0
+      || bfd_read (expdata, export_size, dll) != export_size)
+    goto notdll;
   erva = expdata - export_rva;
 
   nexp = pe_as32 (expdata + 24);
@@ -626,20 +652,27 @@ pe_text_section_offset (struct bfd *abfd)
     }
 
   /* Get pe_header, optional header and numbers of sections.  */
-  pe_header_offset = pe_get32 (abfd, 0x3c);
-  nsections = pe_get16 (abfd, pe_header_offset + 4 + 2);
+  bool fail = false;
+  pe_header_offset = pe_get32 (abfd, 0x3c, &fail);
+  if (fail)
+    return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;
+  nsections = pe_get16 (abfd, pe_header_offset + 4 + 2, &fail);
   secptr = (pe_header_offset + 4 + 20 +
-	    pe_get16 (abfd, pe_header_offset + 4 + 16));
+	    pe_get16 (abfd, pe_header_offset + 4 + 16, &fail));
+  if (fail)
+    return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;
 
   /* Get the rva and size of the export section.  */
   for (i = 0; i < nsections; i++)
     {
       char sname[SCNNMLEN + 1];
       unsigned long secptr1 = secptr + 40 * i;
-      unsigned long vaddr = pe_get32 (abfd, secptr1 + 12);
+      unsigned long vaddr = pe_get32 (abfd, secptr1 + 12, &fail);
 
-      bfd_seek (abfd, (file_ptr) secptr1, SEEK_SET);
-      bfd_read (sname, (bfd_size_type) SCNNMLEN, abfd);
+      if (fail
+	  || bfd_seek (abfd, secptr1, SEEK_SET) != 0
+	  || bfd_read (sname, SCNNMLEN, abfd) != SCNNMLEN)
+	return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;
       sname[SCNNMLEN] = '\0';
       if (strcmp (sname, ".text") == 0)
 	return vaddr;
diff --git a/gdb/coffread.c b/gdb/coffread.c
index 583db6bceb0..6a995ae2241 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -711,8 +711,6 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 
       /* FIXME: dubious.  Why can't we use something normal like
 	 bfd_get_section_contents?  */
-      bfd_seek (abfd, abfd->where, 0);
-
       stabstrsize = bfd_section_size (info->stabstrsect);
 
       coffstab_build_psymtabs (objfile,
@@ -807,22 +805,6 @@ coff_symtab_read (minimal_symbol_reader &reader,
 
   scoped_free_pendings free_pending;
 
-  /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
-     it's hard to know I've really worked around it.  The fix should
-     be harmless, anyway).  The symptom of the bug is that the first
-     fread (in read_one_sym), will (in my example) actually get data
-     from file offset 268, when the fseek was to 264 (and ftell shows
-     264).  This causes all hell to break loose.  I was unable to
-     reproduce this on a short test program which operated on the same
-     file, performing (I think) the same sequence of operations.
-
-     It stopped happening when I put in this (former) rewind().
-
-     FIXME: Find out if this has been reported to Sun, whether it has
-     been fixed in a later release, etc.  */
-
-  bfd_seek (objfile->obfd.get (), 0, 0);
-
   /* Position to read the symbol table.  */
   val = bfd_seek (objfile->obfd.get (), symtab_offset, 0);
   if (val < 0)
@@ -1308,12 +1290,13 @@ init_stringtab (bfd *abfd, file_ptr offset, gdb::unique_xmalloc_ptr<char> *stora
   if (bfd_seek (abfd, offset, 0) < 0)
     return -1;
 
-  val = bfd_read ((char *) lengthbuf, sizeof lengthbuf, abfd);
-  length = bfd_h_get_32 (symfile_bfd, lengthbuf);
-
+  val = bfd_read (lengthbuf, sizeof lengthbuf, abfd);
   /* If no string table is needed, then the file may end immediately
      after the symbols.  Just return with `stringtab' set to null.  */
-  if (val != sizeof lengthbuf || length < sizeof lengthbuf)
+  if (val != sizeof lengthbuf)
+    return 0;
+  length = bfd_h_get_32 (symfile_bfd, lengthbuf);
+  if (length < sizeof lengthbuf)
     return 0;
 
   storage->reset ((char *) xmalloc (length));
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index 75bbd510155..ddc61d9d539 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -809,7 +809,8 @@ stabs_seek (int sym_offset)
       symbuf_left -= sym_offset;
     }
   else
-    bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
+    if (bfd_seek (symfile_bfd, sym_offset, SEEK_CUR) != 0)
+      perror_with_name (bfd_get_filename (symfile_bfd));
 }
 
 #define INTERNALIZE_SYMBOL(intern, extern, abfd)			\
@@ -2155,8 +2156,8 @@ dbx_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
       symbol_size = SYMBOL_SIZE (pst);
 
       /* Read in this file's symbols.  */
-      bfd_seek (objfile->obfd.get (), SYMBOL_OFFSET (pst), SEEK_SET);
-      read_ofile_symtab (objfile, pst);
+      if (bfd_seek (objfile->obfd.get (), SYMBOL_OFFSET (pst), SEEK_SET) == 0)
+	read_ofile_symtab (objfile, pst);
     }
 
   pst->readin = true;
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index 8ce4b28d133..63eb538ca05 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -779,8 +779,9 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset,
 
   while (curoffset <= limit_offset)
     {
-      bfd_seek (abfd, curoffset, SEEK_SET);
-      bfd_read (ext_lnno, linesz, abfd);
+      if (bfd_seek (abfd, curoffset, SEEK_SET) != 0
+	  || bfd_read (ext_lnno, linesz, abfd) != linesz)
+	return;
       bfd_coff_swap_lineno_in (abfd, ext_lnno, &int_lnno);
 
       /* Find the address this line represents.  */

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: gdb: warn unused result for bfd IO functions
  2023-08-10  3:36 ` gdb: " Alan Modra
@ 2023-08-11 12:15   ` Andrew Burgess
  0 siblings, 0 replies; 3+ messages in thread
From: Andrew Burgess @ 2023-08-11 12:15 UTC (permalink / raw)
  To: Alan Modra, binutils, gdb-patches

Alan Modra via Binutils <binutils@sourceware.org> writes:

> From 3dd00a9f25bc78028ba4b3820b45d34f51c4a25d Mon Sep 17 00:00:00 2001
> From: Alan Modra <amodra@gmail.com>
> Date: Wed, 9 Aug 2023 09:58:36 +0930
> Subject: 
>
> This fixes the compilation warnings introduced by my bfdio.c patch.
>
> The removed bfd_seeks in coff_symfile_read date back to 1994, commit
> 7f4c859520, prior to which the file used stdio rather than bfd to read
> symbols.  Since it now uses bfd to read the file there should be no
> need to synchronise to bfd's idea of the file position.  I also fixed
> a potential uninitialised memory access.
>
> OK to apply?

I had a look through, this all looks OK, except I think we can easily
avoid adding a new 'goto' with the patch below.

If you're happy to take this change then:

Approved-By: Andrew Burgess <aburgess@redhat.com>

Thanks,
Andrew

---

diff --git a/gdb/coff-pe-read.c b/gdb/coff-pe-read.c
index 34360eb72f1..0d76ebdbfce 100644
--- a/gdb/coff-pe-read.c
+++ b/gdb/coff-pe-read.c
@@ -343,30 +343,29 @@ read_pe_exported_syms (minimal_symbol_reader &reader,
 	     || strcmp (target, "pei-i386") == 0
 	     || strcmp (target, "pe-arm-wince-little") == 0
 	     || strcmp (target, "pei-arm-wince-little") == 0);
+
+  /* Possibly print a debug message about DLL not having a valid format.  */
+  auto maybe_print_debug_msg = [&] () -> void {
+    if (debug_coff_pe_read)
+      gdb_printf (gdb_stdlog, _("%s doesn't appear to be a DLL\n"),
+		  bfd_get_filename (dll));
+  };
+
   if (!is_pe32 && !is_pe64)
-    {
-      /* This is not a recognized PE format file.  Abort now, because
-	 the code is untested on anything else.  *FIXME* test on
-	 further architectures and loosen or remove this test.  */
-    notdll:
-      if (debug_coff_pe_read)
-	gdb_printf (gdb_stdlog, _("%s doesn't appear to be a DLL\n"),
-		    bfd_get_filename (dll));
-      return;
-    }
+    return maybe_print_debug_msg ();
 
   /* Get pe_header, optional header and numbers of export entries.  */
   bool fail = false;
   pe_header_offset = pe_get32 (dll, 0x3c, &fail);
   if (fail)
-    goto notdll;
+    return maybe_print_debug_msg ();
   opthdr_ofs = pe_header_offset + 4 + 20;
   if (is_pe64)
     num_entries = pe_get32 (dll, opthdr_ofs + 108, &fail);
   else
     num_entries = pe_get32 (dll, opthdr_ofs + 92, &fail);
   if (fail)
-    goto notdll;
+    return maybe_print_debug_msg ();
 
   if (num_entries < 1)		/* No exports.  */
     return;
@@ -381,13 +380,13 @@ read_pe_exported_syms (minimal_symbol_reader &reader,
       export_opthdrsize = pe_get32 (dll, opthdr_ofs + 100, &fail);
     }
   if (fail)
-    goto notdll;
+    return maybe_print_debug_msg ();
 
   nsections = pe_get16 (dll, pe_header_offset + 4 + 2, &fail);
   secptr = (pe_header_offset + 4 + 20 +
 	    pe_get16 (dll, pe_header_offset + 4 + 16, &fail));
   if (fail)
-    goto notdll;
+    return maybe_print_debug_msg ();
   expptr = 0;
   export_size = 0;
 
@@ -454,7 +453,7 @@ read_pe_exported_syms (minimal_symbol_reader &reader,
       if (fail
 	  || bfd_seek (dll, secptr1 + 0, SEEK_SET) != 0
 	  || bfd_read (sec_name, SCNNMLEN, dll) != SCNNMLEN)
-	goto notdll;
+	return maybe_print_debug_msg ();
       sec_name[SCNNMLEN] = '\0';
 
       sectix = read_pe_section_index (sec_name);
@@ -495,7 +494,7 @@ read_pe_exported_syms (minimal_symbol_reader &reader,
 
   if (bfd_seek (dll, expptr, SEEK_SET) != 0
       || bfd_read (expdata, export_size, dll) != export_size)
-    goto notdll;
+    return maybe_print_debug_msg ();
   erva = expdata - export_rva;
 
   nexp = pe_as32 (expdata + 24);


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-08-11 12:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-10  3:33 warn unused result for bfd IO functions Alan Modra
2023-08-10  3:36 ` gdb: " Alan Modra
2023-08-11 12:15   ` Andrew Burgess

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).