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=149df6455eed48658dccc5808cedac7748240fc9;hpb=9d0a14d3f3339d988a395262538629b05cac99d3;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 149df6455e..dcded6f4a7 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -1,6 +1,5 @@ /* Generic ECOFF (Extended-COFF) routines. - Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 1990-2020 Free Software Foundation, Inc. Original version by Per Bothner. Full support added by Ian Lance Taylor, ian@cygnus.com. @@ -25,8 +24,8 @@ #include "bfd.h" #include "bfdlink.h" #include "libbfd.h" +#include "ecoff-bfd.h" #include "aout/ar.h" -#include "aout/ranlib.h" #include "aout/stab_gnu.h" /* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines @@ -53,32 +52,36 @@ /* This stuff is somewhat copied from coffcode.h. */ static asection bfd_debug_section = { - /* name, id, index, next, prev, flags, user_set_vma, */ - "*DEBUG*", 0, 0, NULL, NULL, 0, 0, - /* linker_mark, linker_has_input, gc_mark, */ - 0, 0, 1, - /* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, */ - 0, 0, 0, 0, - /* has_gp_reloc, need_finalize_relax, reloc_done, */ - 0, 0, 0, - /* vma, lma, size, rawsize, */ - 0, 0, 0, 0, - /* output_offset, output_section, alignment_power, */ - 0, NULL, 0, + /* name, id, section_id, index, next, prev, flags, */ + "*DEBUG*", 0, 0, 0, NULL, NULL, 0, + /* user_set_vma, */ + 0, + /* linker_mark, linker_has_input, gc_mark, compress_status, */ + 0, 0, 1, 0, + /* segment_mark, sec_info_type, use_rela_p, */ + 0, 0, 0, + /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ + 0, 0, 0, 0, 0, 0, + /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ + 0, 0, 0, 0, 0, 0, 0, + /* output_offset, output_section, alignment_power, */ + 0, NULL, 0, /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ - NULL, NULL, 0, 0, 0, - /* line_filepos, userdata, contents, lineno, lineno_count, */ - 0, NULL, NULL, NULL, 0, - /* entsize, kept_section, moving_line_filepos, */ - 0, NULL, 0, - /* target_index, used_by_bfd, constructor_chain, owner, */ - 0, NULL, NULL, NULL, - /* symbol, */ + NULL, NULL, 0, 0, 0, + /* line_filepos, userdata, contents, lineno, lineno_count, */ + 0, NULL, NULL, NULL, 0, + /* entsize, kept_section, moving_line_filepos, */ + 0, NULL, 0, + /* target_index, used_by_bfd, constructor_chain, owner, */ + 0, NULL, NULL, NULL, + /* symbol, */ NULL, - /* symbol_ptr_ptr, */ + /* symbol_ptr_ptr, */ + NULL, + /* map_head, map_tail, */ + { NULL }, { NULL }, + /* already_assigned */ NULL, - /* map_head, map_tail */ - { NULL }, { NULL } }; /* Create an ECOFF object. */ @@ -86,9 +89,9 @@ static asection bfd_debug_section = bfd_boolean _bfd_ecoff_mkobject (bfd *abfd) { - bfd_size_type amt = sizeof (ecoff_data_type); + size_t amt = sizeof (ecoff_data_type); - abfd->tdata.ecoff_obj_data = bfd_zalloc (abfd, amt); + abfd->tdata.ecoff_obj_data = (struct ecoff_tdata *) bfd_zalloc (abfd, amt); if (abfd->tdata.ecoff_obj_data == NULL) return FALSE; @@ -155,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} }; @@ -184,6 +187,13 @@ _bfd_ecoff_new_section_hook (bfd *abfd, asection *section) return _bfd_generic_new_section_hook (abfd, section); } +void +_bfd_ecoff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED, + asection *section ATTRIBUTE_UNUSED, + void *scnhdr ATTRIBUTE_UNUSED) +{ +} + /* Determine the machine architecture and type. This is called from the generic COFF routines. It is the inverse of ecoff_get_magic, below. This could be an ECOFF backend routine, with one version @@ -192,7 +202,7 @@ _bfd_ecoff_new_section_hook (bfd *abfd, asection *section) bfd_boolean _bfd_ecoff_set_arch_mach_hook (bfd *abfd, void * filehdr) { - struct internal_filehdr *internal_f = filehdr; + struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; enum bfd_architecture arch; unsigned long mach; @@ -233,6 +243,14 @@ _bfd_ecoff_set_arch_mach_hook (bfd *abfd, void * filehdr) return bfd_default_set_arch_mach (abfd, arch, mach); } +bfd_boolean +_bfd_ecoff_no_long_sections (bfd *abfd, int enable) +{ + (void) abfd; + (void) enable; + return FALSE; +} + /* Get the magic number to use based on the architecture and machine. This is the inverse of _bfd_ecoff_set_arch_mach_hook, above. */ @@ -288,29 +306,29 @@ ecoff_sec_to_styp_flags (const char *name, flagword flags) } styp_flags [] = { - { _TEXT, STYP_TEXT }, - { _DATA, STYP_DATA }, - { _SDATA, STYP_SDATA }, - { _RDATA, STYP_RDATA }, - { _LITA, STYP_LITA }, - { _LIT8, STYP_LIT8 }, - { _LIT4, STYP_LIT4 }, - { _BSS, STYP_BSS }, - { _SBSS, STYP_SBSS }, - { _INIT, STYP_ECOFF_INIT }, - { _FINI, STYP_ECOFF_FINI }, - { _PDATA, STYP_PDATA }, - { _XDATA, STYP_XDATA }, - { _LIB, STYP_ECOFF_LIB }, - { _GOT, STYP_GOT }, - { _HASH, STYP_HASH }, - { _DYNAMIC, STYP_DYNAMIC }, - { _LIBLIST, STYP_LIBLIST }, - { _RELDYN, STYP_RELDYN }, - { _CONFLIC, STYP_CONFLIC }, - { _DYNSTR, STYP_DYNSTR }, - { _DYNSYM, STYP_DYNSYM }, - { _RCONST, STYP_RCONST } + { _TEXT, STYP_TEXT }, + { _DATA, STYP_DATA }, + { _SDATA, STYP_SDATA }, + { _RDATA, STYP_RDATA }, + { _LITA, STYP_LITA }, + { _LIT8, STYP_LIT8 }, + { _LIT4, STYP_LIT4 }, + { _BSS, STYP_BSS }, + { _SBSS, STYP_SBSS }, + { _INIT, STYP_ECOFF_INIT }, + { _FINI, STYP_ECOFF_FINI }, + { _PDATA, STYP_PDATA }, + { _XDATA, STYP_XDATA }, + { _LIB, STYP_ECOFF_LIB }, + { _GOT, STYP_GOT }, + { _HASH, STYP_HASH }, + { _DYNAMIC, STYP_DYNAMIC }, + { _LIBLIST, STYP_LIBLIST }, + { _RELDYN, STYP_RELDYN }, + { _CONFLIC, STYP_CONFLIC }, + { _DYNSTR, STYP_DYNSTR }, + { _DYNSYM, STYP_DYNSYM }, + { _RCONST, STYP_RCONST } }; long styp = 0; @@ -355,7 +373,7 @@ _bfd_ecoff_styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED, asection *section ATTRIBUTE_UNUSED, flagword * flags_ptr) { - struct internal_scnhdr *internal_s = hdr; + struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; long styp_flags = internal_s->s_flags; flagword sec_flags = 0; @@ -396,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 @@ -433,7 +454,7 @@ ecoff_slurp_symbolic_header (bfd *abfd) /* See whether there is a symbolic header. */ if (ecoff_data (abfd)->sym_filepos == 0) { - bfd_get_symcount (abfd) = 0; + abfd->symcount = 0; return TRUE; } @@ -449,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); @@ -466,15 +486,12 @@ ecoff_slurp_symbolic_header (bfd *abfd) } /* Now we can get the correct number of symbols. */ - bfd_get_symcount (abfd) = (internal_symhdr->isymMax - + internal_symhdr->iextMax); + 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; } @@ -498,8 +515,8 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd, struct fdr *fdr_ptr; bfd_size_type raw_end; bfd_size_type cb_end; - bfd_size_type amt; file_ptr pos; + size_t amt; BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info); @@ -509,7 +526,7 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd, return TRUE; if (ecoff_data (abfd)->sym_filepos == 0) { - bfd_get_symcount (abfd) = 0; + abfd->symcount = 0; return TRUE; } @@ -556,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; @@ -601,14 +613,21 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd, We need to look at the fdr to deal with a lot of information in the symbols, so we swap them here. */ - amt = internal_symhdr->ifdMax; - amt *= sizeof (struct fdr); - debug->fdr = bfd_alloc (abfd, amt); + if (_bfd_mul_overflow ((unsigned long) internal_symhdr->ifdMax, + sizeof (struct fdr), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return FALSE; + } + debug->fdr = (FDR *) bfd_alloc (abfd, amt); if (debug->fdr == NULL) return FALSE; external_fdr_size = backend->debug_swap.external_fdr_size; fdr_ptr = debug->fdr; fraw_src = (char *) debug->external_fdr; + /* PR 17512: file: 3372-1243-0.004. */ + if (fraw_src == NULL && internal_symhdr->ifdMax > 0) + return FALSE; fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size; for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) (*backend->debug_swap.swap_fdr_in) (abfd, (void *) fraw_src, fdr_ptr); @@ -633,18 +652,18 @@ static asymbol *ecoff_scom_symbol_ptr; asymbol * _bfd_ecoff_make_empty_symbol (bfd *abfd) { - ecoff_symbol_type *new; - bfd_size_type amt = sizeof (ecoff_symbol_type); + ecoff_symbol_type *new_symbol; + size_t amt = sizeof (ecoff_symbol_type); - new = bfd_zalloc (abfd, amt); - if (new == NULL) + new_symbol = (ecoff_symbol_type *) bfd_zalloc (abfd, amt); + if (new_symbol == NULL) return NULL; - new->symbol.section = NULL; - new->fdr = NULL; - new->local = FALSE; - new->native = NULL; - new->symbol.the_bfd = abfd; - return &new->symbol; + new_symbol->symbol.section = NULL; + new_symbol->fdr = NULL; + new_symbol->local = FALSE; + new_symbol->native = NULL; + new_symbol->symbol.the_bfd = abfd; + return &new_symbol->symbol; } /* Set the BFD flags and section for an ECOFF symbol. */ @@ -690,11 +709,11 @@ ecoff_set_symbol_info (bfd *abfd, { asym->flags = BSF_LOCAL; /* Normally, a local stProc symbol will have a corresponding - external symbol. We mark the local symbol as a debugging - symbol, in order to prevent nm from printing both out. - Similarly, we mark stLabel and stabs symbols as debugging - symbols. In both cases, we do want to set the value - correctly based on the symbol class. */ + external symbol. We mark the local symbol as a debugging + symbol, in order to prevent nm from printing both out. + Similarly, we mark stLabel and stabs symbols as debugging + symbols. In both cases, we do want to set the value + correctly based on the symbol class. */ if (ecoff_sym->st == stProc || ecoff_sym->st == stLabel || ECOFF_IS_STAB (ecoff_sym)) @@ -850,13 +869,13 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd) = backend->debug_swap.swap_ext_in; void (* const swap_sym_in) (bfd *, void *, SYMR *) = backend->debug_swap.swap_sym_in; - bfd_size_type internal_size; ecoff_symbol_type *internal; ecoff_symbol_type *internal_ptr; char *eraw_src; char *eraw_end; FDR *fdr_ptr; FDR *fdr_end; + size_t amt; /* If we've already read in the symbol table, do nothing. */ if (ecoff_data (abfd)->canonical_symbols != NULL) @@ -869,9 +888,13 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd) if (bfd_get_symcount (abfd) == 0) return TRUE; - internal_size = bfd_get_symcount (abfd); - internal_size *= sizeof (ecoff_symbol_type); - internal = bfd_alloc (abfd, internal_size); + if (_bfd_mul_overflow (bfd_get_symcount (abfd), + sizeof (ecoff_symbol_type), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return FALSE; + } + internal = (ecoff_symbol_type *) bfd_alloc (abfd, amt); if (internal == NULL) return FALSE; @@ -885,16 +908,30 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd) EXTR internal_esym; (*swap_ext_in) (abfd, (void *) eraw_src, &internal_esym); + + /* PR 17512: file: 3372-1000-0.004. */ + if (internal_esym.asym.iss >= ecoff_data (abfd)->debug_info.symbolic_header.issExtMax + || internal_esym.asym.iss < 0) + return FALSE; + internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext + internal_esym.asym.iss); + if (!ecoff_set_symbol_info (abfd, &internal_esym.asym, &internal_ptr->symbol, 1, internal_esym.weakext)) return FALSE; + /* The alpha uses a negative ifd field for section symbols. */ if (internal_esym.ifd >= 0) - internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr - + internal_esym.ifd); + { + /* PR 17512: file: 3372-1983-0.004. */ + if (internal_esym.ifd >= ecoff_data (abfd)->debug_info.symbolic_header.ifdMax) + internal_ptr->fdr = NULL; + else + internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr + + internal_esym.ifd); + } else internal_ptr->fdr = NULL; internal_ptr->local = FALSE; @@ -932,6 +969,21 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd) } } + /* PR 17512: file: 3372-3080-0.004. + A discrepancy between ecoff_data (abfd)->debug_info.symbolic_header.isymMax + and ecoff_data (abfd)->debug_info.symbolic_header.ifdMax can mean that + we have fewer symbols than we were expecting. Allow for this by updating + the symbol count and warning the user. */ + if (internal_ptr - internal < (ptrdiff_t) bfd_get_symcount (abfd)) + { + abfd->symcount = internal_ptr - internal; + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: warning: isymMax (%ld) is greater than ifdMax (%ld)"), + abfd, ecoff_data (abfd)->debug_info.symbolic_header.isymMax, + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax); + } + ecoff_data (abfd)->canonical_symbols = internal; return TRUE; @@ -1038,7 +1090,7 @@ ecoff_emit_aggregate (bfd *abfd, sprintf (string, "%s %s { ifd = %u, index = %lu }", which, name, ifd, - ((long) indx + ((unsigned long) indx + debug_info->symbolic_header.iextMax)); } @@ -1224,7 +1276,7 @@ ecoff_type_to_string (bfd *abfd, FDR *fdr, unsigned int indx) break; default: - sprintf (p1, _("Unknown basic type %d"), (int) basic_type); + sprintf (p1, _("unknown basic type %d"), (int) basic_type); break; } @@ -1244,12 +1296,12 @@ ecoff_type_to_string (bfd *abfd, FDR *fdr, unsigned int indx) if (qualifiers[0].type != tqNil) { /* Snarf up any array bounds in the correct order. Arrays - store 5 successive words in the aux. table: - word 0 RNDXR to type of the bounds (ie, int) - word 1 Current file descriptor index - word 2 low bound - word 3 high bound (or -1 if []) - word 4 stride size in bits. */ + store 5 successive words in the aux. table: + word 0 RNDXR to type of the bounds (ie, int) + word 1 Current file descriptor index + word 2 low bound + word 3 high bound (or -1 if []) + word 4 stride size in bits. */ for (i = 0; i < 7; i++) { if (qualifiers[i].type == tqArray) @@ -1503,6 +1555,7 @@ _bfd_ecoff_print_symbol (bfd *abfd, if (ECOFF_IS_STAB (&ecoff_ext.asym)) ; else if (ecoffsymbol (symbol)->local) + /* xgettext:c-format */ fprintf (file, _("\n End+1 symbol: %-7ld Type: %s"), ((long) (AUX_GET_ISYM (bigendian, @@ -1555,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; @@ -1567,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 = bfd_alloc (abfd, amt); - external_reloc_size = backend->external_reloc_size; amt = external_reloc_size * section->reloc_count; - external_relocs = 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; @@ -1635,17 +1691,17 @@ ecoff_slurp_reloc_table (bfd *abfd, abort (); rptr->sym_ptr_ptr = sec->symbol_ptr_ptr; - rptr->addend = - bfd_get_section_vma (abfd, sec); + rptr->addend = - bfd_section_vma (sec); } - rptr->address = intern.r_vaddr - bfd_get_section_vma (abfd, section); + rptr->address = intern.r_vaddr - bfd_section_vma (section); /* Let the backend select the howto field and do any other required processing. */ (*backend->adjust_reloc_in) (abfd, &intern, rptr); } - bfd_release (abfd, external_relocs); + free (external_relocs); section->relocation = internal_relocs; @@ -1698,12 +1754,13 @@ _bfd_ecoff_canonicalize_reloc (bfd *abfd, bfd_boolean _bfd_ecoff_find_nearest_line (bfd *abfd, + asymbol **symbols ATTRIBUTE_UNUSED, asection *section, - asymbol **ignore_symbols ATTRIBUTE_UNUSED, bfd_vma offset, const char **filename_ptr, const char **functionname_ptr, - unsigned int *retline_ptr) + unsigned int *retline_ptr, + unsigned int *discriminator_ptr) { const struct ecoff_debug_swap * const debug_swap = &ecoff_backend (abfd)->debug_swap; @@ -1717,14 +1774,17 @@ _bfd_ecoff_find_nearest_line (bfd *abfd, if (ecoff_data (abfd)->find_line_info == NULL) { - bfd_size_type amt = sizeof (struct ecoff_find_line); + size_t amt = sizeof (struct ecoff_find_line); - ecoff_data (abfd)->find_line_info = bfd_zalloc (abfd, amt); + ecoff_data (abfd)->find_line_info = + (struct ecoff_find_line *) bfd_zalloc (abfd, amt); if (ecoff_data (abfd)->find_line_info == NULL) return FALSE; } - line_info = ecoff_data (abfd)->find_line_info; + if (discriminator_ptr) + *discriminator_ptr = 0; + line_info = ecoff_data (abfd)->find_line_info; return _bfd_ecoff_locate_line (abfd, section, offset, debug_info, debug_swap, line_info, filename_ptr, functionname_ptr, retline_ptr); @@ -1879,7 +1939,7 @@ _bfd_ecoff_sizeof_headers (bfd *abfd, ret = (bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd) + c * bfd_coff_scnhsz (abfd)); - return BFD_ALIGN (ret, 16); + return (int) BFD_ALIGN (ret, 16); } /* Get the contents of a section. */ @@ -1944,7 +2004,7 @@ ecoff_compute_section_file_positions (bfd *abfd) /* Sort the sections by VMA. */ amt = abfd->section_count; amt *= sizeof (asection *); - sorted_hdrs = bfd_malloc (amt); + sorted_hdrs = (asection **) bfd_malloc (amt); if (sorted_hdrs == NULL) return FALSE; for (current = abfd->sections, i = 0; @@ -2027,8 +2087,8 @@ ecoff_compute_section_file_positions (bfd *abfd) && (abfd->flags & D_PAGED) != 0) { /* Skip up to the next page for an unallocated section, such - as the .comment section on the Alpha. This leaves room - for the .bss section. */ + as the .comment section on the Alpha. This leaves room + for the .bss section. */ first_nonalloc = FALSE; sofar = (sofar + round - 1) &~ (round - 1); file_sofar = (file_sofar + round - 1) &~ (round - 1); @@ -2172,22 +2232,6 @@ _bfd_ecoff_set_section_contents (bfd *abfd, return TRUE; } -/* Get the GP value for an ECOFF file. This is a hook used by - nlmconv. */ - -bfd_vma -bfd_ecoff_get_gp_value (bfd *abfd) -{ - if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour - || bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - - return ecoff_data (abfd)->gp; -} - /* Set the GP value for an ECOFF file. This is a hook used by the assembler. */ @@ -2283,7 +2327,7 @@ ecoff_get_extr (asymbol *sym, EXTR *esym) symbol. */ if ((esym->asym.sc == scUndefined || esym->asym.sc == scSUndefined) - && ! bfd_is_und_section (bfd_get_section (sym))) + && ! bfd_is_und_section (bfd_asymbol_section (sym))) esym->asym.sc = scAbs; /* Adjust the FDR index for the symbol by that used for the input @@ -2402,7 +2446,7 @@ _bfd_ecoff_write_object_contents (bfd *abfd) strncpy (section.s_name, current->name, sizeof section.s_name); /* This seems to be correct for Irix 4 shared libraries. */ - vma = bfd_get_section_vma (abfd, current); + vma = bfd_section_vma (current); if (streq (current->name, _LIB)) section.s_vaddr = 0; else @@ -2653,8 +2697,7 @@ _bfd_ecoff_write_object_contents (bfd *abfd) if (reloc->howto == NULL) continue; - in.r_vaddr = (reloc->address - + bfd_get_section_vma (abfd, current)); + in.r_vaddr = reloc->address + bfd_section_vma (current); in.r_type = reloc->howto->type; if ((sym->flags & BSF_SECTION_SYM) == 0) @@ -2665,7 +2708,7 @@ _bfd_ecoff_write_object_contents (bfd *abfd) else { const char *name; - unsigned int i; + unsigned int j; static struct { const char * name; @@ -2690,16 +2733,16 @@ _bfd_ecoff_write_object_contents (bfd *abfd) { _RCONST, RELOC_SECTION_RCONST } }; - name = bfd_get_section_name (abfd, bfd_get_section (sym)); + name = bfd_section_name (bfd_asymbol_section (sym)); - for (i = 0; i < ARRAY_SIZE (section_symndx); i++) - if (streq (name, section_symndx[i].name)) + for (j = 0; j < ARRAY_SIZE (section_symndx); j++) + if (streq (name, section_symndx[j].name)) { - in.r_symndx = section_symndx[i].r_symndx; + in.r_symndx = section_symndx[j].r_symndx; break; } - if (i == ARRAY_SIZE (section_symndx)) + if (j == ARRAY_SIZE (section_symndx)) abort (); in.r_extern = 0; } @@ -2752,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; } @@ -2793,19 +2834,19 @@ _bfd_ecoff_write_object_contents (bfd *abfd) The Alpha seems to use ________64E[BL]E[BL]_. */ -#define ARMAP_BIG_ENDIAN 'B' -#define ARMAP_LITTLE_ENDIAN 'L' -#define ARMAP_MARKER 'E' -#define ARMAP_START_LENGTH 10 +#define ARMAP_BIG_ENDIAN 'B' +#define ARMAP_LITTLE_ENDIAN 'L' +#define ARMAP_MARKER 'E' +#define ARMAP_START_LENGTH 10 #define ARMAP_HEADER_MARKER_INDEX 10 -#define ARMAP_HEADER_ENDIAN_INDEX 11 -#define ARMAP_OBJECT_MARKER_INDEX 12 -#define ARMAP_OBJECT_ENDIAN_INDEX 13 -#define ARMAP_END_INDEX 14 -#define ARMAP_END "_ " +#define ARMAP_HEADER_ENDIAN_INDEX 11 +#define ARMAP_OBJECT_MARKER_INDEX 12 +#define ARMAP_OBJECT_ENDIAN_INDEX 13 +#define ARMAP_END_INDEX 14 +#define ARMAP_END "_ " /* This is a magic number used in the hashing algorithm. */ -#define ARMAP_HASH_MAGIC 0x9dd68ab5 +#define ARMAP_HASH_MAGIC 0x9dd68ab5 /* This returns the hash value to use for a string. It also sets *REHASH to the rehash adjustment if the first slot is taken. SIZE @@ -2838,21 +2879,21 @@ _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; char *raw_ptr; - struct symdef *symdef_ptr; + carsym *symdef_ptr; char *stringbase; bfd_size_type amt; /* 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; @@ -2875,7 +2916,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd) && nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN) || ! strneq (nextname + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1)) { - bfd_has_map (abfd) = FALSE; + abfd->has_armap = FALSE; return TRUE; } @@ -2895,23 +2936,24 @@ _bfd_ecoff_slurp_armap (bfd *abfd) if (mapdata == NULL) return FALSE; parsed_size = mapdata->parsed_size; - bfd_release (abfd, (void *) mapdata); - - raw_armap = bfd_alloc (abfd, parsed_size); - if (raw_armap == NULL) - return FALSE; + free (mapdata); - 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; @@ -2919,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 { @@ -2963,12 +3006,12 @@ _bfd_ecoff_slurp_armap (bfd *abfd) ++ardata->symdef_count; amt = ardata->symdef_count; - amt *= sizeof (struct symdef); - symdef_ptr = bfd_alloc (abfd, amt); + amt *= sizeof (carsym); + symdef_ptr = (carsym *) bfd_alloc (abfd, amt); if (!symdef_ptr) - return FALSE; + goto error_exit; - ardata->symdefs = (carsym *) symdef_ptr; + ardata->symdefs = symdef_ptr; raw_ptr = raw_armap + 4; for (i = 0; i < count; i++, raw_ptr += 8) @@ -2979,7 +3022,9 @@ _bfd_ecoff_slurp_armap (bfd *abfd) if (file_offset == 0) continue; name_offset = H_GET_32 (abfd, raw_ptr); - symdef_ptr->s.name = stringbase + name_offset; + if (name_offset > stringsize) + goto error_malformed; + symdef_ptr->name = stringbase + name_offset; symdef_ptr->file_offset = file_offset; ++symdef_ptr; } @@ -2987,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; - - bfd_has_map (abfd) = TRUE; - + 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. */ @@ -3050,8 +3102,9 @@ _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); - sprintf (hdr.ar_date, "%ld", (long) (statbuf.st_mtime + 60)); + stat (bfd_get_filename (abfd), &statbuf); + _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", + (long) (statbuf.st_mtime + 60)); /* The DECstation uses zeroes for the uid, gid and mode of the armap. */ @@ -3062,7 +3115,7 @@ _bfd_ecoff_write_armap (bfd *abfd, hdr.ar_mode[1] = '4'; hdr.ar_mode[2] = '4'; - sprintf (hdr.ar_size, "%-10d", (int) mapsize); + _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize); hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\012'; @@ -3080,7 +3133,7 @@ _bfd_ecoff_write_armap (bfd *abfd, if (bfd_bwrite ((void *) temp, (bfd_size_type) 4, abfd) != 4) return FALSE; - hashtable = bfd_zalloc (abfd, symdefsize); + hashtable = (bfd_byte *) bfd_zalloc (abfd, symdefsize); if (!hashtable) return FALSE; @@ -3154,89 +3207,6 @@ _bfd_ecoff_write_armap (bfd *abfd, return TRUE; } - -/* See whether this BFD is an archive. If it is, read in the armap - and the extended name table. */ - -const bfd_target * -_bfd_ecoff_archive_p (bfd *abfd) -{ - struct artdata *tdata_hold; - char armag[SARMAG + 1]; - bfd_size_type amt; - - if (bfd_bread ((void *) armag, (bfd_size_type) SARMAG, abfd) != SARMAG) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if (! strneq (armag, ARMAG, SARMAG)) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - tdata_hold = bfd_ardata (abfd); - - amt = sizeof (struct artdata); - bfd_ardata (abfd) = bfd_zalloc (abfd, amt); - if (bfd_ardata (abfd) == NULL) - { - bfd_ardata (abfd) = tdata_hold; - return NULL; - } - - bfd_ardata (abfd)->first_file_filepos = SARMAG; - /* Already cleared by bfd_zalloc above. - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->extended_names_size = 0; - bfd_ardata (abfd)->tdata = NULL; */ - - if (! _bfd_ecoff_slurp_armap (abfd) - || ! _bfd_ecoff_slurp_extended_name_table (abfd)) - { - bfd_release (abfd, bfd_ardata (abfd)); - bfd_ardata (abfd) = tdata_hold; - return NULL; - } - - if (bfd_has_map (abfd)) - { - bfd *first; - - /* This archive has a map, so we may presume that the contents - are object files. Make sure that if the first file in the - archive can be recognized as an object file, it is for this - target. If not, assume that this is the wrong format. If - the first file is not an object file, somebody is doing - something weird, and we permit it so that ar -t will work. */ - - first = bfd_openr_next_archived_file (abfd, NULL); - if (first != NULL) - { - first->target_defaulted = FALSE; - if (bfd_check_format (first, bfd_object) - && first->xvec != abfd->xvec) - { - /* We ought to close `first' here, but we can't, because - we have no way to remove it from the archive cache. - It's almost impossible to figure out when we can - release bfd_ardata. FIXME. */ - bfd_set_error (bfd_error_wrong_object_format); - bfd_ardata (abfd) = tdata_hold; - return NULL; - } - /* And we ought to close `first' here too. */ - } - } - - return abfd->xvec; -} /* ECOFF linker code. */ @@ -3281,9 +3251,9 @@ struct bfd_link_hash_table * _bfd_ecoff_bfd_link_hash_table_create (bfd *abfd) { struct ecoff_link_hash_table *ret; - bfd_size_type amt = sizeof (struct ecoff_link_hash_table); + size_t amt = sizeof (struct ecoff_link_hash_table); - ret = bfd_malloc (amt); + ret = (struct ecoff_link_hash_table *) bfd_malloc (amt); if (ret == NULL) return NULL; if (!_bfd_link_hash_table_init (&ret->root, abfd, @@ -3302,14 +3272,6 @@ _bfd_ecoff_bfd_link_hash_table_create (bfd *abfd) ((struct ecoff_link_hash_entry *) \ bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow))) -/* Traverse an ECOFF link hash table. */ - -#define ecoff_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func), \ - (info))) - /* Get the ECOFF link hash table from the info structure. This is just a cast. */ @@ -3341,7 +3303,7 @@ ecoff_link_add_externals (bfd *abfd, amt = ext_count; amt *= sizeof (struct bfd_link_hash_entry *); - sym_hash = bfd_alloc (abfd, amt); + sym_hash = (struct bfd_link_hash_entry **) bfd_alloc (abfd, amt); if (!sym_hash) return FALSE; ecoff_data (abfd)->sym_hashes = (struct ecoff_link_hash_entry **) sym_hash; @@ -3485,7 +3447,7 @@ ecoff_link_add_externals (bfd *abfd, /* If we are building an ECOFF hash table, save the external symbol information. */ - if (info->hash->creator->flavour == bfd_get_flavour (abfd)) + if (bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd)) { if (h->abfd == NULL || (! bfd_is_und_section (section) @@ -3545,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 = 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; } @@ -3586,124 +3540,23 @@ ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) static bfd_boolean ecoff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, + struct bfd_link_hash_entry *h, + const char *name, bfd_boolean *pneeded) { - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - void (* const swap_ext_in) (bfd *, void *, EXTR *) - = backend->debug_swap.swap_ext_in; - HDRR *symhdr; - bfd_size_type external_ext_size; - void * external_ext = NULL; - bfd_size_type esize; - char *ssext = NULL; - char *ext_ptr; - char *ext_end; - *pneeded = FALSE; - if (! ecoff_slurp_symbolic_header (abfd)) - goto error_return; - - /* If there are no symbols, we don't want it. */ - if (bfd_get_symcount (abfd) == 0) - goto successful_return; - - symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; - - /* Read in the external symbols and external strings. */ - external_ext_size = backend->debug_swap.external_ext_size; - esize = symhdr->iextMax * external_ext_size; - external_ext = bfd_malloc (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) - goto error_return; - - ssext = bfd_malloc ((bfd_size_type) 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; - - /* Look through the external symbols to see if they define some - symbol that is currently undefined. */ - ext_ptr = (char *) external_ext; - ext_end = ext_ptr + esize; - for (; ext_ptr < ext_end; ext_ptr += external_ext_size) - { - EXTR esym; - bfd_boolean def; - const char *name; - struct bfd_link_hash_entry *h; - - (*swap_ext_in) (abfd, (void *) ext_ptr, &esym); - - /* See if this symbol defines something. */ - if (esym.asym.st != stGlobal - && esym.asym.st != stLabel - && esym.asym.st != stProc) - continue; - - switch (esym.asym.sc) - { - case scText: - case scData: - case scBss: - case scAbs: - case scSData: - case scSBss: - case scRData: - case scCommon: - case scSCommon: - case scInit: - case scFini: - case scRConst: - def = TRUE; - break; - default: - def = FALSE; - break; - } - - if (! def) - continue; - - name = ssext + esym.asym.iss; - h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); - - /* Unlike the generic linker, we do not pull in elements because - of common symbols. */ - if (h == NULL - || h->type != bfd_link_hash_undefined) - continue; - - /* Include this element. */ - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - goto error_return; - if (! ecoff_link_add_externals (abfd, info, external_ext, ssext)) - goto error_return; + /* Unlike the generic linker, we do not pull in elements because + of common symbols. */ + if (h->type != bfd_link_hash_undefined) + return TRUE; - *pneeded = TRUE; - goto successful_return; - } + /* Include this element? */ + if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd)) + return TRUE; + *pneeded = TRUE; - successful_return: - if (external_ext != NULL) - free (external_ext); - if (ssext != NULL) - free (ssext); - return TRUE; - error_return: - if (external_ext != NULL) - free (external_ext); - if (ssext != NULL) - free (ssext); - return FALSE; + return ecoff_link_add_object_symbols (abfd, info); } /* Add the symbols from an archive file to the global hash table. @@ -3848,7 +3701,8 @@ ecoff_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) /* Unlike the generic linker, we know that this element provides a definition for an undefined symbol and we know that we want to include it. We don't need to check anything. */ - if (! (*info->callbacks->add_archive_element) (info, element, name)) + if (!(*info->callbacks + ->add_archive_element) (info, element, name, &element)) return FALSE; if (! ecoff_link_add_object_symbols (element, info)) return FALSE; @@ -3904,25 +3758,31 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd, HDRR *symhdr = &debug->symbolic_header; bfd_boolean ret; -#define READ(ptr, offset, count, size, type) \ - if (symhdr->count == 0) \ - debug->ptr = NULL; \ - else \ - { \ - bfd_size_type amt = (bfd_size_type) size * symhdr->count; \ - debug->ptr = bfd_malloc (amt); \ - if (debug->ptr == NULL) \ - { \ - ret = FALSE; \ - goto return_something; \ - } \ - if (bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ - || bfd_bread (debug->ptr, amt, input_bfd) != amt) \ - { \ - ret = FALSE; \ - goto return_something; \ - } \ - } +#define READ(ptr, offset, count, size, type) \ + do \ + { \ + size_t amt; \ + debug->ptr = NULL; \ + if (symhdr->count == 0) \ + break; \ + if (_bfd_mul_overflow (size, symhdr->count, &amt)) \ + { \ + bfd_set_error (bfd_error_file_too_big); \ + ret = FALSE; \ + goto return_something; \ + } \ + if (bfd_seek (input_bfd, symhdr->offset, SEEK_SET) != 0) \ + { \ + ret = FALSE; \ + goto return_something; \ + } \ + debug->ptr = (type) _bfd_malloc_and_read (input_bfd, amt, amt); \ + if (debug->ptr == NULL) \ + { \ + ret = FALSE; \ + goto return_something; \ + } \ + } while (0) /* If raw_syments is not NULL, then the data was already by read by _bfd_ecoff_slurp_symbolic_info. */ @@ -3952,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. */ @@ -4022,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. */ @@ -4049,7 +3898,7 @@ ecoff_indirect_link_order (bfd *output_bfd, modified, and we write them out now. We use the reloc_count field of output_section to keep track of the number of relocs we have output so far. */ - if (info->relocatable) + if (bfd_link_relocatable (info)) { file_ptr pos = (output_section->rel_filepos + output_section->reloc_count * external_reloc_size); @@ -4060,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; } @@ -4120,7 +3965,7 @@ ecoff_reloc_link_order (bfd *output_bfd, struct bfd_link_hash_entry *h; /* Treat a reloc against a defined symbol as though it were - actually against the section. */ + actually against the section. */ h = bfd_wrapped_link_hash_lookup (output_bfd, info, link_order->u.reloc.p->u.name, FALSE, FALSE, FALSE); @@ -4131,8 +3976,8 @@ ecoff_reloc_link_order (bfd *output_bfd, type = bfd_section_reloc_link_order; section = h->u.def.section->output_section; /* It seems that we ought to add the symbol value to the - addend here, but in practice it has already been added - because it was passed to constructor_callback. */ + addend here, but in practice it has already been added + because it was passed to constructor_callback. */ addend += section->vma + h->u.def.section->output_offset; } else @@ -4155,8 +4000,8 @@ ecoff_reloc_link_order (bfd *output_bfd, bfd_byte *buf; size = bfd_get_reloc_size (rel.howto); - buf = bfd_zmalloc (size); - if (buf == NULL) + buf = (bfd_byte *) bfd_zmalloc (size); + if (buf == NULL && size != 0) return FALSE; rstat = _bfd_relocate_contents (rel.howto, output_bfd, (bfd_vma) addend, buf); @@ -4168,17 +4013,12 @@ ecoff_reloc_link_order (bfd *output_bfd, case bfd_reloc_outofrange: abort (); case bfd_reloc_overflow: - if (! ((*info->callbacks->reloc_overflow) - (info, NULL, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (output_bfd, section) - : link_order->u.reloc.p->u.name), - rel.howto->name, addend, NULL, - NULL, (bfd_vma) 0))) - { - free (buf); - return FALSE; - } + (*info->callbacks->reloc_overflow) + (info, NULL, + (link_order->type == bfd_section_reloc_link_order + ? bfd_section_name (section) + : link_order->u.reloc.p->u.name), + rel.howto->name, addend, NULL, NULL, (bfd_vma) 0); break; } ok = bfd_set_section_contents (output_bfd, output_section, (void *) buf, @@ -4191,8 +4031,7 @@ ecoff_reloc_link_order (bfd *output_bfd, rel.addend = 0; /* Move the information into an internal_reloc structure. */ - in.r_vaddr = (rel.address - + bfd_get_section_vma (output_bfd, output_section)); + in.r_vaddr = rel.address + bfd_section_vma (output_section); in.r_type = rel.howto->type; if (type == bfd_symbol_reloc_link_order) @@ -4208,10 +4047,8 @@ ecoff_reloc_link_order (bfd *output_bfd, in.r_symndx = h->indx; else { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, NULL, - NULL, (bfd_vma) 0))) - return FALSE; + (*info->callbacks->unattached_reloc) + (info, link_order->u.reloc.p->u.name, NULL, NULL, (bfd_vma) 0); in.r_symndx = 0; } in.r_extern = 1; @@ -4244,7 +4081,7 @@ ecoff_reloc_link_order (bfd *output_bfd, { _RCONST, RELOC_SECTION_RCONST } }; - name = bfd_get_section_name (output_bfd, section); + name = bfd_section_name (section); for (i = 0; i < ARRAY_SIZE (section_symndx); i++) if (streq (name, section_symndx[i].name)) @@ -4264,7 +4101,7 @@ ecoff_reloc_link_order (bfd *output_bfd, /* Get some memory and swap out the reloc. */ external_reloc_size = ecoff_backend (output_bfd)->external_reloc_size; - rbuf = bfd_malloc (external_reloc_size); + rbuf = (bfd_byte *) bfd_malloc (external_reloc_size); if (rbuf == NULL) return FALSE; @@ -4288,8 +4125,9 @@ ecoff_reloc_link_order (bfd *output_bfd, the hash table. */ static bfd_boolean -ecoff_link_write_external (struct ecoff_link_hash_entry *h, void * data) +ecoff_link_write_external (struct bfd_hash_entry *bh, void * data) { + struct ecoff_link_hash_entry *h = (struct ecoff_link_hash_entry *) bh; struct extsym_info *einfo = (struct extsym_info *) data; bfd *output_bfd = einfo->abfd; bfd_boolean strip; @@ -4356,7 +4194,7 @@ ecoff_link_write_external (struct ecoff_link_hash_entry *h, void * data) }; output_section = h->root.u.def.section->output_section; - name = bfd_section_name (output_section->owner, output_section); + name = bfd_section_name (output_section); for (i = 0; i < ARRAY_SIZE (section_storage_classes); i++) if (streq (name, section_storage_classes[i].name)) @@ -4487,7 +4325,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) /* Accumulate the debugging symbols from each input BFD. */ for (input_bfd = info->input_bfds; input_bfd != NULL; - input_bfd = input_bfd->link_next) + input_bfd = input_bfd->link.next) { bfd_boolean ret; @@ -4520,11 +4358,9 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) /* Write out the external symbols. */ einfo.abfd = abfd; einfo.info = info; - ecoff_link_hash_traverse (ecoff_hash_table (info), - ecoff_link_write_external, - (void *) &einfo); + bfd_hash_traverse (&info->hash->table, ecoff_link_write_external, &einfo); - if (info->relocatable) + if (bfd_link_relocatable (info)) { /* We need to make a pass over the link_orders to count up the number of relocations we will need to output, so that we know @@ -4554,7 +4390,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) bfd_ecoff_debug_free (handle, abfd, debug, &backend->debug_swap, info); - if (info->relocatable) + if (bfd_link_relocatable (info)) { /* Now reset the reloc_count field of the sections in the output BFD to 0, so that we can use them to keep track of how many @@ -4574,7 +4410,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) ecoff_data (abfd)->gp = (h->u.def.value + h->u.def.section->output_section->vma + h->u.def.section->output_offset); - else if (info->relocatable) + else if (bfd_link_relocatable (info)) { bfd_vma lo; @@ -4627,7 +4463,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) } } - bfd_get_symcount (abfd) = symhdr->iextMax + symhdr->isymMax; + abfd->symcount = symhdr->iextMax + symhdr->isymMax; ecoff_data (abfd)->linker = TRUE;