X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fecoff.c;h=dcded6f4a7e6bf384f311232958b7fbe74ecd11c;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=15c18aca76d937990b387dda59d453cd38c2339b;hpb=1f4361a77b18c5ab32baf2f30fefe5e301e017be;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 15c18aca76..dcded6f4a7 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -78,8 +78,10 @@ static asection bfd_debug_section = NULL, /* symbol_ptr_ptr, */ NULL, - /* map_head, map_tail */ - { NULL }, { NULL } + /* map_head, map_tail, */ + { NULL }, { NULL }, + /* already_assigned */ + NULL, }; /* Create an ECOFF object. */ @@ -156,14 +158,14 @@ _bfd_ecoff_new_section_hook (bfd *abfd, asection *section) { _INIT, SEC_ALLOC | SEC_CODE | SEC_LOAD }, { _FINI, SEC_ALLOC | SEC_CODE | SEC_LOAD }, { _DATA, SEC_ALLOC | SEC_DATA | SEC_LOAD }, - { _SDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD }, + { _SDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_SMALL_DATA }, { _RDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, - { _LIT8, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, - { _LIT4, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, + { _LIT8, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_SMALL_DATA}, + { _LIT4, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_SMALL_DATA}, { _RCONST, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, { _PDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, { _BSS, SEC_ALLOC}, - { _SBSS, SEC_ALLOC}, + { _SBSS, SEC_ALLOC | SEC_SMALL_DATA}, /* An Irix 4 shared libary. */ { _LIB, SEC_COFF_SHARED_LIBRARY} }; @@ -412,16 +414,19 @@ _bfd_ecoff_styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED, || styp_flags == STYP_PDATA || styp_flags == STYP_RCONST) sec_flags |= SEC_READONLY; + if (styp_flags & STYP_SDATA) + sec_flags |= SEC_SMALL_DATA; } - else if ((styp_flags & STYP_BSS) - || (styp_flags & STYP_SBSS)) + else if (styp_flags & STYP_SBSS) + sec_flags |= SEC_ALLOC | SEC_SMALL_DATA; + else if (styp_flags & STYP_BSS) sec_flags |= SEC_ALLOC; else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT) sec_flags |= SEC_NEVER_LOAD; else if ((styp_flags & STYP_LITA) || (styp_flags & STYP_LIT8) || (styp_flags & STYP_LIT4)) - sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY; + sec_flags |= SEC_DATA |SEC_SMALL_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY; else if (styp_flags & STYP_ECOFF_LIB) sec_flags |= SEC_COFF_SHARED_LIBRARY; else @@ -465,13 +470,12 @@ ecoff_slurp_symbolic_header (bfd *abfd) } /* Read the symbolic information header. */ - raw = bfd_malloc (external_hdr_size); + if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0) + goto error_return; + raw = _bfd_malloc_and_read (abfd, external_hdr_size, external_hdr_size); if (raw == NULL) goto error_return; - if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0 - || bfd_bread (raw, external_hdr_size, abfd) != external_hdr_size) - goto error_return; internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; (*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr); @@ -484,12 +488,10 @@ ecoff_slurp_symbolic_header (bfd *abfd) /* Now we can get the correct number of symbols. */ abfd->symcount = internal_symhdr->isymMax + internal_symhdr->iextMax; - if (raw != NULL) - free (raw); + free (raw); return TRUE; error_return: - if (raw != NULL) - free (raw); + free (raw); return FALSE; } @@ -571,18 +573,13 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd, ecoff_data (abfd)->sym_filepos = 0; return TRUE; } - raw = bfd_alloc (abfd, raw_size); - if (raw == NULL) - return FALSE; - pos = ecoff_data (abfd)->sym_filepos; pos += backend->debug_swap.external_hdr_size; - if (bfd_seek (abfd, pos, SEEK_SET) != 0 - || bfd_bread (raw, raw_size, abfd) != raw_size) - { - bfd_release (abfd, raw); - return FALSE; - } + if (bfd_seek (abfd, pos, SEEK_SET) != 0) + return FALSE; + raw = _bfd_alloc_and_read (abfd, raw_size, raw_size); + if (raw == NULL) + return FALSE; ecoff_data (abfd)->raw_syments = raw; @@ -1611,7 +1608,7 @@ ecoff_slurp_reloc_table (bfd *abfd, arelent *internal_relocs; bfd_size_type external_reloc_size; bfd_size_type amt; - char *external_relocs; + bfd_byte *external_relocs; arelent *rptr; unsigned int i; @@ -1623,20 +1620,23 @@ ecoff_slurp_reloc_table (bfd *abfd, if (! _bfd_ecoff_slurp_symbol_table (abfd)) return FALSE; - amt = section->reloc_count; - amt *= sizeof (arelent); - internal_relocs = (arelent *) bfd_alloc (abfd, amt); - external_reloc_size = backend->external_reloc_size; amt = external_reloc_size * section->reloc_count; - external_relocs = (char *) bfd_alloc (abfd, amt); - if (internal_relocs == NULL || external_relocs == NULL) - return FALSE; if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0) return FALSE; - if (bfd_bread (external_relocs, amt, abfd) != amt) + external_relocs = _bfd_malloc_and_read (abfd, amt, amt); + if (external_relocs == NULL) return FALSE; + amt = section->reloc_count; + amt *= sizeof (arelent); + internal_relocs = (arelent *) bfd_alloc (abfd, amt); + if (internal_relocs == NULL) + { + free (external_relocs); + return FALSE; + } + for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++) { struct internal_reloc intern; @@ -1701,7 +1701,7 @@ ecoff_slurp_reloc_table (bfd *abfd, (*backend->adjust_reloc_in) (abfd, &intern, rptr); } - bfd_release (abfd, external_relocs); + free (external_relocs); section->relocation = internal_relocs; @@ -2795,14 +2795,12 @@ _bfd_ecoff_write_object_contents (bfd *abfd) if (reloc_buff != NULL) bfd_release (abfd, reloc_buff); - if (buff != NULL) - free (buff); + free (buff); return TRUE; error_return: if (reloc_buff != NULL) bfd_release (abfd, reloc_buff); - if (buff != NULL) - free (buff); + free (buff); return FALSE; } @@ -2881,7 +2879,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd) char nextname[17]; unsigned int i; struct areltdata *mapdata; - bfd_size_type parsed_size; + bfd_size_type parsed_size, stringsize; char *raw_armap; struct artdata *ardata; unsigned int count; @@ -2893,9 +2891,9 @@ _bfd_ecoff_slurp_armap (bfd *abfd) /* Get the name of the first element. */ i = bfd_bread ((void *) nextname, (bfd_size_type) 16, abfd); if (i == 0) - return TRUE; + return TRUE; if (i != 16) - return FALSE; + return FALSE; if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) return FALSE; @@ -2940,21 +2938,22 @@ _bfd_ecoff_slurp_armap (bfd *abfd) parsed_size = mapdata->parsed_size; free (mapdata); - raw_armap = (char *) bfd_alloc (abfd, parsed_size); - if (raw_armap == NULL) - return FALSE; - - if (bfd_bread ((void *) raw_armap, parsed_size, abfd) != parsed_size) + if (parsed_size + 1 < 9) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - bfd_release (abfd, (void *) raw_armap); + bfd_set_error (bfd_error_malformed_archive); return FALSE; } + raw_armap = (char *) _bfd_alloc_and_read (abfd, parsed_size + 1, parsed_size); + if (raw_armap == NULL) + return FALSE; + raw_armap[parsed_size] = 0; + ardata->tdata = (void *) raw_armap; count = H_GET_32 (abfd, raw_armap); + if ((parsed_size - 8) / 8 < count) + goto error_malformed; ardata->symdef_count = 0; ardata->cache = NULL; @@ -2962,6 +2961,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd) /* This code used to overlay the symdefs over the raw archive data, but that doesn't work on a 64 bit host. */ stringbase = raw_armap + count * 8 + 8; + stringsize = parsed_size - (count * 8 + 8); #ifdef CHECK_ARMAP_HASH { @@ -3009,7 +3009,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd) amt *= sizeof (carsym); symdef_ptr = (carsym *) bfd_alloc (abfd, amt); if (!symdef_ptr) - return FALSE; + goto error_exit; ardata->symdefs = symdef_ptr; @@ -3022,6 +3022,8 @@ _bfd_ecoff_slurp_armap (bfd *abfd) if (file_offset == 0) continue; name_offset = H_GET_32 (abfd, raw_ptr); + if (name_offset > stringsize) + goto error_malformed; symdef_ptr->name = stringbase + name_offset; symdef_ptr->file_offset = file_offset; ++symdef_ptr; @@ -3030,10 +3032,17 @@ _bfd_ecoff_slurp_armap (bfd *abfd) ardata->first_file_filepos = bfd_tell (abfd); /* Pad to an even boundary. */ ardata->first_file_filepos += ardata->first_file_filepos % 2; - abfd->has_armap = TRUE; - return TRUE; + + error_malformed: + bfd_set_error (bfd_error_malformed_archive); + error_exit: + ardata->symdef_count = 0; + ardata->symdefs = NULL; + ardata->tdata = NULL; + bfd_release (abfd, raw_armap); + return FALSE; } /* Write out an armap. */ @@ -3093,7 +3102,7 @@ _bfd_ecoff_write_armap (bfd *abfd, complain that the index is out of date. Actually, the Ultrix linker just checks the archive name; the GNU linker may check the date. */ - stat (abfd->filename, &statbuf); + stat (bfd_get_filename (abfd), &statbuf); _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", (long) (statbuf.st_mtime + 60)); @@ -3498,38 +3507,30 @@ ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; /* Read in the external symbols and external strings. */ + if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0) + return FALSE; external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size; esize = symhdr->iextMax * external_ext_size; - external_ext = bfd_malloc (esize); + external_ext = _bfd_malloc_and_read (abfd, esize, esize); if (external_ext == NULL && esize != 0) goto error_return; - if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0 - || bfd_bread (external_ext, esize, abfd) != esize) + if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0) goto error_return; - - ssext = (char *) bfd_malloc ((bfd_size_type) symhdr->issExtMax); + ssext = (char *) _bfd_malloc_and_read (abfd, symhdr->issExtMax, + symhdr->issExtMax); if (ssext == NULL && symhdr->issExtMax != 0) goto error_return; - if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0 - || (bfd_bread (ssext, (bfd_size_type) symhdr->issExtMax, abfd) - != (bfd_size_type) symhdr->issExtMax)) - goto error_return; - result = ecoff_link_add_externals (abfd, info, external_ext, ssext); - if (ssext != NULL) - free (ssext); - if (external_ext != NULL) - free (external_ext); + free (ssext); + free (external_ext); return result; error_return: - if (ssext != NULL) - free (ssext); - if (external_ext != NULL) - free (external_ext); + free (ssext); + free (external_ext); return FALSE; } @@ -3770,14 +3771,13 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd, ret = FALSE; \ goto return_something; \ } \ - debug->ptr = (type) bfd_malloc (amt); \ - if (debug->ptr == NULL) \ + if (bfd_seek (input_bfd, symhdr->offset, SEEK_SET) != 0) \ { \ ret = FALSE; \ goto return_something; \ } \ - if (bfd_seek (input_bfd, symhdr->offset, SEEK_SET) != 0 \ - || bfd_bread (debug->ptr, amt, input_bfd) != amt) \ + debug->ptr = (type) _bfd_malloc_and_read (input_bfd, amt, amt); \ + if (debug->ptr == NULL) \ { \ ret = FALSE; \ goto return_something; \ @@ -3812,24 +3812,15 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd, return_something: if (ecoff_data (input_bfd)->raw_syments == NULL) { - if (debug->line != NULL) - free (debug->line); - if (debug->external_dnr != NULL) - free (debug->external_dnr); - if (debug->external_pdr != NULL) - free (debug->external_pdr); - if (debug->external_sym != NULL) - free (debug->external_sym); - if (debug->external_opt != NULL) - free (debug->external_opt); - if (debug->external_aux != NULL) - free (debug->external_aux); - if (debug->ss != NULL) - free (debug->ss); - if (debug->external_fdr != NULL) - free (debug->external_fdr); - if (debug->external_rfd != NULL) - free (debug->external_rfd); + free (debug->line); + free (debug->external_dnr); + free (debug->external_pdr); + free (debug->external_sym); + free (debug->external_opt); + free (debug->external_aux); + free (debug->ss); + free (debug->external_fdr); + free (debug->external_rfd); /* Make sure we don't accidentally follow one of these pointers into freed memory. */ @@ -3882,13 +3873,11 @@ ecoff_indirect_link_order (bfd *output_bfd, external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size; external_relocs_size = external_reloc_size * input_section->reloc_count; - external_relocs = bfd_malloc (external_relocs_size); - if (external_relocs == NULL && external_relocs_size != 0) + if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0) goto error_return; - - if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0 - || (bfd_bread (external_relocs, external_relocs_size, input_bfd) - != external_relocs_size)) + external_relocs = _bfd_malloc_and_read (input_bfd, external_relocs_size, + external_relocs_size); + if (external_relocs == NULL && external_relocs_size != 0) goto error_return; /* Relocate the section contents. */ @@ -3920,17 +3909,13 @@ ecoff_indirect_link_order (bfd *output_bfd, output_section->reloc_count += input_section->reloc_count; } - if (contents != NULL) - free (contents); - if (external_relocs != NULL) - free (external_relocs); + free (contents); + free (external_relocs); return TRUE; error_return: - if (contents != NULL) - free (contents); - if (external_relocs != NULL) - free (external_relocs); + free (contents); + free (external_relocs); return FALSE; }