X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcoffgen.c;h=7f26e18c4509167b54eac29046e47960211fdba1;hb=b61121178ec07f9da1242e439fe1a23a314ad30e;hp=4917a5fe61556fbcdf79008fc319f94d8c08a8c9;hpb=07d6d2b8345ef3dc82eab49635acac9ee67dbb18;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 4917a5fe61..7f26e18c45 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -1,5 +1,5 @@ /* Support for the generic parts of COFF, for BFD. - Copyright (C) 1990-2017 Free Software Foundation, Inc. + Copyright (C) 1990-2019 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -37,6 +37,7 @@ coff_data (abfd). */ #include "sysdep.h" +#include #include "bfd.h" #include "libbfd.h" #include "coff/internal.h" @@ -175,7 +176,7 @@ make_a_section_from_file (bfd *abfd, { _bfd_error_handler /* xgettext: c-format */ - (_("%B: unable to initialize compress status for section %s"), + (_("%pB: unable to initialize compress status for section %s"), abfd, name); return FALSE; } @@ -199,7 +200,7 @@ make_a_section_from_file (bfd *abfd, { _bfd_error_handler /* xgettext: c-format */ - (_("%B: unable to initialize decompress status for section %s"), + (_("%pB: unable to initialize decompress status for section %s"), abfd, name); return FALSE; } @@ -216,7 +217,7 @@ make_a_section_from_file (bfd *abfd, break; } if (new_name != NULL) - bfd_rename_section (abfd, return_section, new_name); + bfd_rename_section (return_section, new_name); } return result; @@ -256,14 +257,14 @@ coff_real_object_p (bfd *abfd, if ((internal_f->f_flags & F_EXEC) != 0) abfd->flags |= D_PAGED; - bfd_get_symcount (abfd) = internal_f->f_nsyms; + abfd->symcount = internal_f->f_nsyms; if (internal_f->f_nsyms) abfd->flags |= HAS_SYMS; if (internal_a != (struct internal_aouthdr *) NULL) - bfd_get_start_address (abfd) = internal_a->entry; + abfd->start_address = internal_a->entry; else - bfd_get_start_address (abfd) = 0; + abfd->start_address = 0; /* Set up the tdata area. ECOFF uses its own routine, and overrides abfd->flags. */ @@ -308,7 +309,7 @@ coff_real_object_p (bfd *abfd, fail2: abfd->tdata.any = tdata_save; abfd->flags = oflags; - bfd_get_start_address (abfd) = ostart; + abfd->start_address = ostart; return (const bfd_target *) NULL; } @@ -1521,7 +1522,8 @@ coff_pointerize_aux (bfd *abfd, combined_entry_type *table_base, combined_entry_type *symbol, unsigned int indaux, - combined_entry_type *auxent) + combined_entry_type *auxent, + combined_entry_type *table_end) { unsigned int type = symbol->u.syment.n_type; unsigned int n_sclass = symbol->u.syment.n_sclass; @@ -1547,15 +1549,22 @@ coff_pointerize_aux (bfd *abfd, if ((ISFCN (type) || ISTAG (n_sclass) || n_sclass == C_BLOCK || n_sclass == C_FCN) - && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0) + && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0 + && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l + < (long) obj_raw_syment_count (abfd) + && table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l + < table_end) { auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; auxent->fix_end = 1; } + /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can generate one, so we must be careful to ignore it. */ - if (auxent->u.auxent.x_sym.x_tagndx.l > 0) + if ((unsigned long) auxent->u.auxent.x_sym.x_tagndx.l + < obj_raw_syment_count (abfd) + && table_base + auxent->u.auxent.x_sym.x_tagndx.l < table_end) { auxent->u.auxent.x_sym.x_tagndx.p = table_base + auxent->u.auxent.x_sym.x_tagndx.l; @@ -1646,8 +1655,8 @@ _bfd_coff_get_external_symbols (bfd *abfd) && size > bfd_get_file_size (abfd))) { - _bfd_error_handler (_("%B: corrupt symbol count: %#Lx"), - abfd, obj_raw_syment_count (abfd)); + _bfd_error_handler (_("%pB: corrupt symbol count: %#" PRIx64 ""), + abfd, (uint64_t) obj_raw_syment_count (abfd)); return FALSE; } @@ -1655,8 +1664,10 @@ _bfd_coff_get_external_symbols (bfd *abfd) if (syms == NULL) { /* PR 21013: Provide an error message when the alloc fails. */ - _bfd_error_handler (_("%B: not enough memory to allocate space for %#Lx symbols of size %#Lx"), - abfd, obj_raw_syment_count (abfd), symesz); + _bfd_error_handler (_("%pB: not enough memory to allocate space " + "for %#" PRIx64 " symbols of size %#" PRIx64), + abfd, (uint64_t) obj_raw_syment_count (abfd), + (uint64_t) symesz); return FALSE; } @@ -1722,7 +1733,7 @@ _bfd_coff_read_string_table (bfd *abfd) { _bfd_error_handler /* xgettext: c-format */ - (_("%B: bad string table size %Lu"), abfd, strsize); + (_("%pB: bad string table size %" PRIu64), abfd, (uint64_t) strsize); bfd_set_error (bfd_error_bad_value); return NULL; } @@ -1803,10 +1814,11 @@ coff_get_normalized_symtab (bfd *abfd) if (! _bfd_coff_get_external_symbols (abfd)) return NULL; - size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type); + size = obj_raw_syment_count (abfd); /* Check for integer overflow. */ - if (size < obj_raw_syment_count (abfd)) + if (size > (bfd_size_type) -1 / sizeof (combined_entry_type)) return NULL; + size *= sizeof (combined_entry_type); internal = (combined_entry_type *) bfd_zalloc (abfd, size); if (internal == NULL && size != 0) return NULL; @@ -1833,29 +1845,20 @@ coff_get_normalized_symtab (bfd *abfd) symbol_ptr = internal_ptr; internal_ptr->is_sym = TRUE; - /* PR 17512: file: 1353-1166-0.004. */ - if (symbol_ptr->u.syment.n_sclass == C_FILE - && symbol_ptr->u.syment.n_numaux > 0 - && raw_src + symesz + symbol_ptr->u.syment.n_numaux - * symesz > raw_end) - { - bfd_release (abfd, internal); - return NULL; - } - for (i = 0; i < symbol_ptr->u.syment.n_numaux; i++) { internal_ptr++; + raw_src += symesz; + /* PR 17512: Prevent buffer overrun. */ - if (internal_ptr >= internal_end) + if (raw_src >= raw_end || internal_ptr >= internal_end) { bfd_release (abfd, internal); return NULL; } - raw_src += symesz; bfd_coff_swap_aux_in (abfd, (void *) raw_src, symbol_ptr->u.syment.n_type, symbol_ptr->u.syment.n_sclass, @@ -1864,7 +1867,7 @@ coff_get_normalized_symtab (bfd *abfd) internal_ptr->is_sym = FALSE; coff_pointerize_aux (abfd, internal, symbol_ptr, i, - internal_ptr); + internal_ptr, internal_end); } } @@ -2004,6 +2007,13 @@ coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) bfd_set_error (bfd_error_invalid_operation); return -1; } +#if SIZEOF_LONG == SIZEOF_INT + if (asect->reloc_count >= LONG_MAX / sizeof (arelent *)) + { + bfd_set_error (bfd_error_file_too_big); + return -1; + } +#endif return (asect->reloc_count + 1) * sizeof (arelent *); } @@ -2272,7 +2282,7 @@ coff_find_nearest_line_with_names (bfd *abfd, /* Also try examining DWARF2 debugging information. */ if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset, filename_ptr, functionname_ptr, - line_ptr, NULL, debug_sections, 0, + line_ptr, NULL, debug_sections, &coff_data(abfd)->dwarf2_find_line_info)) return TRUE; @@ -2284,7 +2294,7 @@ coff_find_nearest_line_with_names (bfd *abfd, information. So try again, using a bias against the address sought. */ if (coff_data (abfd)->dwarf2_find_line_info != NULL) { - bfd_signed_vma bias; + bfd_signed_vma bias = 0; /* Create a cache of the result for the next call. */ if (sec_data == NULL && section->owner == abfd) @@ -2296,10 +2306,11 @@ coff_find_nearest_line_with_names (bfd *abfd, if (sec_data != NULL && sec_data->saved_bias) bias = sec_data->saved_bias; - else + else if (symbols) { bias = _bfd_dwarf2_find_symbol_bias (symbols, & coff_data (abfd)->dwarf2_find_line_info); + if (sec_data) { sec_data->saved_bias = TRUE; @@ -2311,7 +2322,7 @@ coff_find_nearest_line_with_names (bfd *abfd, && _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset + bias, filename_ptr, functionname_ptr, - line_ptr, NULL, debug_sections, 0, + line_ptr, NULL, debug_sections, &coff_data(abfd)->dwarf2_find_line_info)) return TRUE; } @@ -2347,7 +2358,7 @@ coff_find_nearest_line_with_names (bfd *abfd, bfd_vma maxdiff; /* Look through the C_FILE symbols to find the best one. */ - sec_vma = bfd_get_section_vma (abfd, section); + sec_vma = bfd_section_vma (section); *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; maxdiff = (bfd_vma) 0 - (bfd_vma) 1; while (1) @@ -2389,13 +2400,16 @@ coff_find_nearest_line_with_names (bfd *abfd, maxdiff = offset + sec_vma - p2->u.syment.n_value; } + if (p->u.syment.n_value >= cof->raw_syment_count) + break; + /* Avoid endless loops on erroneous files by ensuring that we always move forward in the file. */ if (p >= cof->raw_syments + p->u.syment.n_value) break; p = cof->raw_syments + p->u.syment.n_value; - if (p > pend || p->u.syment.n_sclass != C_FILE) + if (!p->is_sym || p->u.syment.n_sclass != C_FILE) break; } } @@ -2628,6 +2642,9 @@ _bfd_coff_section_already_linked (bfd *abfd, struct bfd_section_already_linked_hash_entry *already_linked_list; struct coff_comdat_info *s_comdat; + if (sec->output_section == bfd_abs_section_ptr) + return FALSE; + flags = sec->flags; if ((flags & SEC_LINK_ONCE) == 0) return FALSE; @@ -2636,7 +2653,7 @@ _bfd_coff_section_already_linked (bfd *abfd, if ((flags & SEC_GROUP) != 0) return FALSE; - name = bfd_get_section_name (abfd, sec); + name = bfd_section_name (sec); s_comdat = bfd_coff_get_comdat_section (abfd, sec); if (s_comdat != NULL) @@ -3021,7 +3038,7 @@ coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) if (info->print_gc_sections && o->size != 0) /* xgettext: c-format */ - _bfd_error_handler (_("Removing unused section '%A' in file '%B'"), + _bfd_error_handler (_("removing unused section '%pA' in file '%pB'"), o, sub); #if 0 @@ -3098,7 +3115,7 @@ bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) if (!bed->can_gc_sections || !is_coff_hash_table (info->hash)) { - _bfd_error_handler(_("Warning: gc-sections option ignored")); + _bfd_error_handler(_("warning: gc-sections option ignored")); return TRUE; } #endif @@ -3133,3 +3150,14 @@ bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) /* ... and mark SEC_EXCLUDE for those that go. */ return coff_gc_sweep (abfd, info); } + +/* Return name used to identify a comdat group. */ + +const char * +bfd_coff_group_name (bfd *abfd, const asection *sec) +{ + struct coff_comdat_info *ci = bfd_coff_get_comdat_section (abfd, sec); + if (ci != NULL) + return ci->name; + return NULL; +}