From e416bd75c3fd471c1e0222a72b17f6c585b37e93 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 7 Aug 2023 20:59:08 +0930 Subject: [PATCH] warn unused result for bfd IO functions 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 ): 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. --- bfd/bfd-in2.h | 15 +++--- bfd/bfdio.c | 15 +++--- bfd/coff-rs6000.c | 44 +++++++++------ bfd/coff-stgo32.c | 3 +- bfd/coff64-rs6000.c | 28 ++++++---- bfd/coffcode.h | 35 +++++++----- bfd/elf64-ia64-vms.c | 10 ++-- bfd/pef.c | 14 +++-- bfd/vms-alpha.c | 124 ++++++++++++++++++++++++++----------------- bfd/vms-misc.c | 12 +++-- bfd/vms.h | 2 +- bfd/wasm-module.c | 9 ++-- bfd/xsym.c | 8 +-- binutils/ar.c | 6 ++- ld/pdb.c | 10 ++-- ld/pe-dll.c | 78 +++++++++++++++++---------- 16 files changed, 252 insertions(+), 161 deletions(-) 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) -- 2.30.2