X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=bfd%2Fcoffcode.h;h=eef3fa8d1da6be75d83be01a56334a5a11239b9b;hb=a43942db49b07a457ee4f960d0f118b23641ec38;hp=48709f4dec799ab2d9454b5627c11dfc1080b490;hpb=5a3f568b70bdfb91aacdfb66657b56d8c6d242f1;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 48709f4dec..eef3fa8d1d 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1,5 +1,5 @@ /* Support for the generic parts of most COFF variants, for BFD. - Copyright (C) 1990-2014 Free Software Foundation, Inc. + Copyright (C) 1990-2016 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -307,7 +307,7 @@ CODE_FRAGMENT .typedef struct coff_ptr_struct .{ . {* Remembers the offset from the first symbol in the file for -. this symbol. Generated by coff_renumber_symbols. *} +. this symbol. Generated by coff_renumber_symbols. *} . unsigned int offset; . . {* Should the value of this symbol be renumbered. Used for @@ -315,15 +315,15 @@ CODE_FRAGMENT . unsigned int fix_value : 1; . . {* Should the tag field of this symbol be renumbered. -. Created by coff_pointerize_aux. *} +. Created by coff_pointerize_aux. *} . unsigned int fix_tag : 1; . . {* Should the endidx field of this symbol be renumbered. -. Created by coff_pointerize_aux. *} +. Created by coff_pointerize_aux. *} . unsigned int fix_end : 1; . . {* Should the x_csect.x_scnlen field be renumbered. -. Created by coff_pointerize_aux. *} +. Created by coff_pointerize_aux. *} . unsigned int fix_scnlen : 1; . . {* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the @@ -331,12 +331,15 @@ CODE_FRAGMENT . unsigned int fix_line : 1; . . {* The container for the symbol structure as read and translated -. from the file. *} +. from the file. *} . union . { . union internal_auxent auxent; . struct internal_syment syment; . } u; +. +. {* Selector for the union above. *} +. bfd_boolean is_sym; .} combined_entry_type; . . @@ -928,12 +931,7 @@ handle_COMDAT (bfd * abfd, bfd_coff_swap_sym_in (abfd, esym, & isym); - if (sizeof (internal_s->s_name) > SYMNMLEN) - { - /* This case implies that the matching - symbol name will be in the string table. */ - abort (); - } + BFD_ASSERT (sizeof (internal_s->s_name) <= SYMNMLEN); if (isym.n_scnum == section->target_index) { @@ -964,8 +962,12 @@ handle_COMDAT (bfd * abfd, /* All 3 branches use this. */ symname = _bfd_coff_internal_syment_name (abfd, &isym, buf); + /* PR 17512 file: 078-11867-0.004 */ if (symname == NULL) - abort (); + { + _bfd_error_handler (_("%B: unable to load COMDAT section name"), abfd); + break; + } switch (seen_state) { @@ -1007,6 +1009,13 @@ handle_COMDAT (bfd * abfd, seen_state = 1; + /* PR 17512: file: e2cfe54f. */ + if (esym + bfd_coff_symesz (abfd) >= esymend) + { + _bfd_error_handler (_("%B: warning: No symbol for section '%s' found"), + abfd, symname); + break; + } /* This is the section symbol. */ bfd_coff_swap_aux_in (abfd, (esym + bfd_coff_symesz (abfd)), isym.n_type, isym.n_sclass, @@ -1160,7 +1169,7 @@ styp_to_sec_flags (bfd *abfd, flagword *flags_ptr) { struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; - long styp_flags = internal_s->s_flags; + unsigned long styp_flags = internal_s->s_flags; flagword sec_flags; bfd_boolean result = TRUE; bfd_boolean is_dbg = FALSE; @@ -1183,7 +1192,7 @@ styp_to_sec_flags (bfd *abfd, /* Process each flag bit in styp_flags in turn. */ while (styp_flags) { - long flag = styp_flags & - styp_flags; + unsigned long flag = styp_flags & - styp_flags; char * unhandled = NULL; styp_flags &= ~ flag; @@ -1343,6 +1352,10 @@ CODE_FRAGMENT . COFF_SYMBOL_PE_SECTION .}; . +.typedef asection * (*coff_gc_mark_hook_fn) +. (asection *, struct bfd_link_info *, struct internal_reloc *, +. struct coff_link_hash_entry *, struct internal_syment *); +. Special entry points for gdb to swap in coff symbol table parts: .typedef struct .{ @@ -1797,6 +1810,7 @@ coff_new_section_hook (bfd * abfd, asection * section) in case this symbol winds up getting written out. The value 0 for n_numaux is already correct. */ + native->is_sym = TRUE; native->u.syment.n_type = T_NULL; native->u.syment.n_sclass = sclass; @@ -2070,7 +2084,11 @@ coff_mkobject_hook (bfd * abfd, #endif if ((internal_f->f_flags & F_GO32STUB) != 0) - coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE); + { + coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE); + if (coff->go32stub == NULL) + return NULL; + } if (coff->go32stub != NULL) memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE); @@ -2275,6 +2293,8 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) bfd_size_type amt = bfd_coff_symesz (abfd); buf = bfd_malloc (amt); + if (buf == NULL) + return FALSE; if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 || bfd_bread (buf, amt, abfd) != amt) { @@ -2498,11 +2518,13 @@ coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED, unsigned int indaux, combined_entry_type *aux) { + BFD_ASSERT (symbol->is_sym); int n_sclass = symbol->u.syment.n_sclass; if (CSECT_SYM_P (n_sclass) && indaux + 1 == symbol->u.syment.n_numaux) { + BFD_ASSERT (! aux->is_sym); if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD) { aux->u.auxent.x_csect.x_scnlen.p = @@ -2535,6 +2557,7 @@ coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED, /* Return TRUE if we don't want to pointerize this aux entry, which is the case for the lastfirst aux entry for a C_LEAFPROC symbol. */ return (indaux == 1 + && symbol->is_sym && (symbol->u.syment.n_sclass == C_LEAFPROC || symbol->u.syment.n_sclass == C_LEAFSTAT || symbol->u.syment.n_sclass == C_LEAFEXT)); @@ -2557,6 +2580,8 @@ coff_print_aux (bfd *abfd ATTRIBUTE_UNUSED, combined_entry_type *aux ATTRIBUTE_UNUSED, unsigned int indaux ATTRIBUTE_UNUSED) { + BFD_ASSERT (symbol->is_sym); + BFD_ASSERT (! aux->is_sym); #ifdef RS6000COFF_C if (CSECT_SYM_P (symbol->u.syment.n_sclass) && indaux + 1 == symbol->u.syment.n_numaux) @@ -2658,10 +2683,16 @@ coff_write_relocs (bfd * abfd, int first_undef) amt = s->reloc_count; amt *= sizeof (arelent *); p = bfd_malloc (amt); - if (p == NULL && s->reloc_count > 0) - return FALSE; - memcpy (p, s->orelocation, (size_t) amt); - qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr); + if (p == NULL) + { + if (s->reloc_count > 0) + return FALSE; + } + else + { + memcpy (p, s->orelocation, (size_t) amt); + qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr); + } } #endif @@ -3143,6 +3174,15 @@ coff_compute_section_file_positions (bfd * abfd) This repairs 'ld -r' for arm-wince-pe target. */ if (page_size == 0) page_size = 1; + + /* PR 17512: file: 0ac816d3. */ + if (page_size < 0) + { + bfd_set_error (bfd_error_file_too_big); + (*_bfd_error_handler) + (_("%B: page size is too large (0x%x)"), abfd, page_size); + return FALSE; + } } else page_size = PE_DEF_FILE_ALIGNMENT; @@ -3166,9 +3206,10 @@ coff_compute_section_file_positions (bfd * abfd) { coff_symbol_type *cf; - cf = coff_symbol_from (abfd, *symp); + cf = coff_symbol_from (*symp); if (cf != NULL && cf->native != NULL + && cf->native->is_sym && SYMNAME_IN_DEBUG (&cf->native->u.syment)) { size_t len; @@ -3863,9 +3904,10 @@ coff_write_object_contents (bfd * abfd) /* See if this is the section symbol. */ if (strcmp ((*psym)->name, current->name) == 0) { - csym = coff_symbol_from (abfd, *psym); + csym = coff_symbol_from (*psym); if (csym == NULL || csym->native == NULL + || ! csym->native->is_sym || csym->native->u.syment.n_numaux < 1 || csym->native->u.syment.n_sclass != C_STAT || csym->native->u.syment.n_type != T_NULL) @@ -3888,6 +3930,7 @@ coff_write_object_contents (bfd * abfd) x_associated field is not currently supported. */ aux = csym->native + 1; + BFD_ASSERT (! aux->is_sym); switch (current->flags & SEC_LINK_DUPLICATES) { case SEC_LINK_DUPLICATES_DISCARD: @@ -4456,11 +4499,11 @@ buy_and_read (bfd *abfd, file_ptr where, bfd_size_type size) void * area = bfd_alloc (abfd, size); if (!area) - return (NULL); + return NULL; if (bfd_seek (abfd, where, SEEK_SET) != 0 || bfd_bread (area, size, abfd) != size) - return (NULL); - return (area); + return NULL; + return area; } /* @@ -4494,6 +4537,8 @@ coff_sort_func_alent (const void * arg1, const void * arg2) const coff_symbol_type *s1 = (const coff_symbol_type *) (al1->u.sym); const coff_symbol_type *s2 = (const coff_symbol_type *) (al2->u.sym); + if (s1 == NULL || s2 == NULL) + return 0; if (s1->symbol.value < s2->symbol.value) return -1; else if (s1->symbol.value > s2->symbol.value) @@ -4511,9 +4556,11 @@ coff_slurp_line_table (bfd *abfd, asection *asect) unsigned int counter; alent *cache_ptr; bfd_vma prev_offset = 0; - int ordered = 1; + bfd_boolean ordered = TRUE; unsigned int nbr_func; LINENO *src; + bfd_boolean have_func; + bfd_boolean ret = TRUE; BFD_ASSERT (asect->lineno == NULL); @@ -4536,35 +4583,65 @@ coff_slurp_line_table (bfd *abfd, asection *asect) asect->lineno = lineno_cache; src = native_lineno; nbr_func = 0; + have_func = FALSE; - for (counter = 0; counter < asect->lineno_count; counter++) + for (counter = 0; counter < asect->lineno_count; counter++, src++) { struct internal_lineno dst; bfd_coff_swap_lineno_in (abfd, src, &dst); cache_ptr->line_number = dst.l_lnno; + /* Appease memory checkers that get all excited about + uninitialised memory when copying alents if u.offset is + larger than u.sym. (64-bit BFD on 32-bit host.) */ + memset (&cache_ptr->u, 0, sizeof (cache_ptr->u)); if (cache_ptr->line_number == 0) { - bfd_signed_vma symndx; + combined_entry_type * ent; + bfd_vma symndx; coff_symbol_type *sym; - nbr_func++; + have_func = FALSE; symndx = dst.l_addr.l_symndx; - if (symndx < 0 - || (bfd_vma) symndx >= obj_raw_syment_count (abfd)) + if (symndx >= obj_raw_syment_count (abfd)) { (*_bfd_error_handler) (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), abfd, (long) symndx, counter); + cache_ptr->line_number = -1; + ret = FALSE; continue; } + ent = obj_raw_syments (abfd) + symndx; /* FIXME: We should not be casting between ints and pointers like this. */ - sym = ((coff_symbol_type *) - ((symndx + obj_raw_syments (abfd)) - ->u.syment._n._n_n._n_zeroes)); + if (! ent->is_sym) + { + (*_bfd_error_handler) + (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), + abfd, (long) symndx, counter); + cache_ptr->line_number = -1; + ret = FALSE; + continue; + } + sym = (coff_symbol_type *) (ent->u.syment._n._n_n._n_zeroes); + + /* PR 17512 file: 078-10659-0.004 */ + if (sym < obj_symbols (abfd) + || sym >= obj_symbols (abfd) + bfd_get_symcount (abfd)) + { + (*_bfd_error_handler) + (_("%B: warning: illegal symbol in line number entry %d"), + abfd, counter); + cache_ptr->line_number = -1; + ret = FALSE; + continue; + } + + have_func = TRUE; + nbr_func++; cache_ptr->u.sym = (asymbol *) sym; if (sym->lineno != NULL) (*_bfd_error_handler) @@ -4573,17 +4650,21 @@ coff_slurp_line_table (bfd *abfd, asection *asect) sym->lineno = cache_ptr; if (sym->symbol.value < prev_offset) - ordered = 0; + ordered = FALSE; prev_offset = sym->symbol.value; } + else if (!have_func) + /* Drop line information that has no associated function. + PR 17521: file: 078-10659-0.004. */ + continue; else - cache_ptr->u.offset = dst.l_addr.l_paddr - - bfd_section_vma (abfd, asect); - + cache_ptr->u.offset = (dst.l_addr.l_paddr + - bfd_section_vma (abfd, asect)); cache_ptr++; - src++; } - cache_ptr->line_number = 0; + + asect->lineno_count = cache_ptr - lineno_cache; + memset (cache_ptr, 0, sizeof (*cache_ptr)); bfd_release (abfd, native_lineno); /* On some systems (eg AIX5.3) the lineno table may not be sorted. */ @@ -4600,15 +4681,17 @@ coff_slurp_line_table (bfd *abfd, asection *asect) alent **p = func_table; unsigned int i; - for (i = 0; i < counter; i++) + for (i = 0; i < asect->lineno_count; i++) if (lineno_cache[i].line_number == 0) *p++ = &lineno_cache[i]; + BFD_ASSERT ((unsigned int) (p - func_table) == nbr_func); + /* Sort by functions. */ qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent); /* Create the new sorted table. */ - amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent); + amt = (bfd_size_type) asect->lineno_count * sizeof (alent); n_lineno_cache = (alent *) bfd_alloc (abfd, amt); if (n_lineno_cache != NULL) { @@ -4619,25 +4702,29 @@ coff_slurp_line_table (bfd *abfd, asection *asect) coff_symbol_type *sym; alent *old_ptr = func_table[i]; - /* Copy the function entry and update it. */ - *n_cache_ptr = *old_ptr; - sym = (coff_symbol_type *)n_cache_ptr->u.sym; - sym->lineno = n_cache_ptr; - n_cache_ptr++; - old_ptr++; - - /* Copy the line number entries. */ - while (old_ptr->line_number != 0) + /* Update the function entry. */ + sym = (coff_symbol_type *) old_ptr->u.sym; + /* PR binutils/17512: Point the lineno to where + this entry will be after the memcpy below. */ + sym->lineno = lineno_cache + (n_cache_ptr - n_lineno_cache); + /* Copy the function and line number entries. */ + do *n_cache_ptr++ = *old_ptr++; + while (old_ptr->line_number != 0); } - n_cache_ptr->line_number = 0; + BFD_ASSERT ((bfd_size_type) (n_cache_ptr - n_lineno_cache) == (amt / sizeof (alent))); + memcpy (lineno_cache, n_lineno_cache, amt); } + else + ret = FALSE; bfd_release (abfd, func_table); } + else + ret = FALSE; } - return TRUE; + return ret; } /* Slurp in the symbol table, converting it to generic form. Note @@ -4652,6 +4739,7 @@ coff_slurp_symbol_table (bfd * abfd) unsigned int *table_ptr; bfd_size_type amt; unsigned int number_of_symbols = 0; + bfd_boolean ret = TRUE; if (obj_symbols (abfd)) return TRUE; @@ -4669,7 +4757,7 @@ coff_slurp_symbol_table (bfd * abfd) amt = obj_raw_syment_count (abfd); amt *= sizeof (unsigned int); - table_ptr = (unsigned int *) bfd_alloc (abfd, amt); + table_ptr = (unsigned int *) bfd_zalloc (abfd, amt); if (table_ptr == NULL) return FALSE; @@ -4683,14 +4771,17 @@ coff_slurp_symbol_table (bfd * abfd) { combined_entry_type *src = native_symbols + this_index; table_ptr[this_index] = number_of_symbols; - dst->symbol.the_bfd = abfd; + dst->symbol.the_bfd = abfd; + BFD_ASSERT (src->is_sym); dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset); /* We use the native name field to point to the cached field. */ src->u.syment._n._n_n._n_zeroes = (bfd_hostptr_t) dst; dst->symbol.section = coff_section_from_bfd_index (abfd, src->u.syment.n_scnum); dst->symbol.flags = 0; + /* PR 17512: file: 079-7098-0.001:0.1. */ + dst->symbol.value = 0; dst->done_lineno = FALSE; switch (src->u.syment.n_sclass) @@ -4964,22 +5055,23 @@ coff_slurp_symbol_table (bfd * abfd) #if defined(TIC80COFF) || defined(TICOFF) case C_UEXT: /* Tentative external definition. */ #endif - case C_EXTLAB: /* External load time label. */ - case C_HIDDEN: /* Ext symbol in dmert public lib. */ default: (*_bfd_error_handler) (_("%B: Unrecognized storage class %d for %s symbol `%s'"), abfd, src->u.syment.n_sclass, dst->symbol.section->name, dst->symbol.name); + ret = FALSE; + case C_EXTLAB: /* External load time label. */ + case C_HIDDEN: /* Ext symbol in dmert public lib. */ dst->symbol.flags = BSF_DEBUGGING; dst->symbol.value = (src->u.syment.n_value); break; } dst->native = src; - dst->symbol.udata.i = 0; dst->lineno = NULL; + this_index += (src->u.syment.n_numaux) + 1; dst++; number_of_symbols++; @@ -4998,12 +5090,13 @@ coff_slurp_symbol_table (bfd * abfd) p = abfd->sections; while (p) { - coff_slurp_line_table (abfd, p); + if (! coff_slurp_line_table (abfd, p)) + return FALSE; p = p->next; } } - return TRUE; + return ret; } /* Classify a COFF symbol. A couple of targets have globally visible @@ -5062,13 +5155,13 @@ coff_classify_symbol (bfd *abfd, if (syment->n_value == 0) { asection *sec; - char buf[SYMNMLEN + 1]; + char * name; + char buf[SYMNMLEN + 1]; - sec = coff_section_from_bfd_index (abfd, syment->n_scnum); - if (sec != NULL - && (strcmp (bfd_get_section_name (abfd, sec), - _bfd_coff_internal_syment_name (abfd, syment, buf)) - == 0)) + name = _bfd_coff_internal_syment_name (abfd, syment, buf) + sec = coff_section_from_bfd_index (abfd, syment->n_scnum); + if (sec != NULL && name != NULL + && (strcmp (bfd_get_section_name (abfd, sec), name) == 0)) return COFF_SYMBOL_PE_SECTION; } #endif @@ -5137,8 +5230,9 @@ SUBSUBSECTION coffsym = (obj_symbols (abfd) \ + (cache_ptr->sym_ptr_ptr - symbols)); \ else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ + coffsym = coff_symbol_from (ptr); \ if (coffsym != NULL \ + && coffsym->native->is_sym \ && coffsym->native->u.syment.n_scnum == 0) \ cache_ptr->addend = 0; \ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ @@ -5261,7 +5355,7 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols) static reloc_howto_type * coff_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, - struct internal_reloc *rel, + struct internal_reloc *rel ATTRIBUTE_UNUSED, struct coff_link_hash_entry *h ATTRIBUTE_UNUSED, struct internal_syment *sym ATTRIBUTE_UNUSED, bfd_vma *addendp ATTRIBUTE_UNUSED) @@ -5386,6 +5480,8 @@ dummy_reloc16_extra_cases (bfd *abfd ATTRIBUTE_UNUSED, _bfd_generic_copy_link_hash_symbol_type #define coff_bfd_link_split_section _bfd_generic_link_split_section +#define coff_bfd_link_check_relocs _bfd_generic_link_check_relocs + #ifndef coff_start_final_link #define coff_start_final_link NULL #endif @@ -5584,7 +5680,7 @@ static bfd_coff_backend_data ticoff1_swap_table = #endif #ifdef COFF_WITH_PE_BIGOBJ -/* The UUID for bigobj files. */ +/* The UID for bigobj files. */ static const char header_bigobj_classid[16] = { @@ -5667,6 +5763,7 @@ coff_bigobj_swap_sym_in (bfd * abfd, void * ext1, void * in1) } in->n_value = H_GET_32 (abfd, ext->e_value); + BFD_ASSERT (sizeof (in->n_scnum) >= 4); in->n_scnum = H_GET_32 (abfd, ext->e_scnum); in->n_type = H_GET_16 (abfd, ext->e_type); in->n_sclass = H_GET_8 (abfd, ext->e_sclass); @@ -5905,7 +6002,7 @@ static bfd_coff_backend_data bigobj_swap_table = #endif #ifndef coff_bfd_gc_sections -#define coff_bfd_gc_sections bfd_generic_gc_sections +#define coff_bfd_gc_sections bfd_coff_gc_sections #endif #ifndef coff_bfd_lookup_section_flags