X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcoffgen.c;h=7f26e18c4509167b54eac29046e47960211fdba1;hb=84e098cdea4eb6a5ddc525a2145ffe66475fa2af;hp=31c2c5a1baa620fb181dd49d6dab7e954627729c;hpb=dae82561a286618acf097ad9894eafba98377f66;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 31c2c5a1ba..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" @@ -72,9 +73,9 @@ make_a_section_from_file (bfd *abfd, const char *strings; /* Flag that this BFD uses long names, even though the format might - expect them to be off by default. This won't directly affect the - format of any output BFD created from this one, but the information - can be used to decide what to do. */ + expect them to be off by default. This won't directly affect the + format of any output BFD created from this one, but the information + can be used to decide what to do. */ bfd_coff_set_long_section_names (abfd, TRUE); memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1); buf[SCNNMLEN - 1] = '\0'; @@ -88,7 +89,7 @@ make_a_section_from_file (bfd *abfd, return FALSE; strings += strindex; name = (char *) bfd_alloc (abfd, - (bfd_size_type) strlen (strings) + 1 + 1); + (bfd_size_type) strlen (strings) + 1 + 1); if (name == NULL) return FALSE; strcpy (name, strings); @@ -99,7 +100,7 @@ make_a_section_from_file (bfd *abfd, { /* Assorted wastage to null-terminate the name, thanks AT&T! */ name = (char *) bfd_alloc (abfd, - (bfd_size_type) sizeof (hdr->s_name) + 1 + 1); + (bfd_size_type) sizeof (hdr->s_name) + 1 + 1); if (name == NULL) return FALSE; strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); @@ -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; } @@ -193,13 +194,13 @@ make_a_section_from_file (bfd *abfd, memcpy (new_name + 2, name + 1, len); } } - break; + break; case decompress: if (!bfd_init_section_decompress_status (abfd, return_section)) { _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; @@ -226,9 +227,9 @@ make_a_section_from_file (bfd *abfd, ECOFF as well. */ const bfd_target * coff_real_object_p (bfd *, - unsigned, - struct internal_filehdr *, - struct internal_aouthdr *); + unsigned, + struct internal_filehdr *, + struct internal_aouthdr *); const bfd_target * coff_real_object_p (bfd *abfd, unsigned nscns, @@ -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; } @@ -595,7 +596,7 @@ coff_count_linenumbers (bfd *abfd) if (limit == 0) { /* This may be from the backend linker, in which case the - lineno_count in the sections is correct. */ + lineno_count in the sections is correct. */ for (s = abfd->sections; s != NULL; s = s->next) total += s->lineno_count; return total; @@ -613,13 +614,13 @@ coff_count_linenumbers (bfd *abfd) coff_symbol_type *q = coffsymbol (q_maybe); /* The AIX 4.1 compiler can sometimes generate line numbers - attached to debugging symbols. We try to simply ignore - those here. */ + attached to debugging symbols. We try to simply ignore + those here. */ if (q->lineno != NULL && q->symbol.section->owner != NULL) { /* This symbol has line numbers. Increment the owning - section's linenumber count. */ + section's linenumber count. */ alent *l = q->lineno; do @@ -675,11 +676,11 @@ fixup_symbol_value (bfd *abfd, syment->n_value = (coff_symbol_ptr->symbol.value + coff_symbol_ptr->symbol.section->output_offset); if (! obj_pe (abfd)) - { - syment->n_value += (syment->n_sclass == C_STATLAB) - ? coff_symbol_ptr->symbol.section->output_section->lma - : coff_symbol_ptr->symbol.section->output_section->vma; - } + { + syment->n_value += (syment->n_sclass == C_STATLAB) + ? coff_symbol_ptr->symbol.section->output_section->lma + : coff_symbol_ptr->symbol.section->output_section->vma; + } } else { @@ -823,8 +824,8 @@ coff_mangle_symbols (bfd *bfd_ptr) if (s->fix_line) { /* The value is the offset into the line number entries - for the symbol's section. On output, the symbol's - section should be N_DEBUG. */ + for the symbol's section. On output, the symbol's + section should be N_DEBUG. */ s->u.syment.n_value = (coff_symbol_ptr->symbol.section->output_section->line_filepos + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr)); @@ -888,13 +889,13 @@ coff_fix_symbol_name (bfd *abfd, if (bfd_coff_force_symnames_in_strings (abfd)) { - native->u.syment._n._n_n._n_offset = + native->u.syment._n._n_n._n_offset = (*string_size_p + STRING_SIZE_SIZE); native->u.syment._n._n_n._n_zeroes = 0; *string_size_p += 6; /* strlen(".file") + 1 */ } else - strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN); + strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN); BFD_ASSERT (! (native + 1)->is_sym); auxent = &(native + 1)->u.auxent; @@ -1088,7 +1089,7 @@ coff_write_alien_symbol (bfd *abfd, { symbol->name = ""; if (isym != NULL) - memset (isym, 0, sizeof (*isym)); + memset (isym, 0, sizeof (*isym)); return TRUE; } native = dummy; @@ -1115,12 +1116,12 @@ coff_write_alien_symbol (bfd *abfd, else if (symbol->flags & BSF_DEBUGGING) { /* There isn't much point to writing out a debugging symbol - unless we are prepared to convert it into COFF debugging - format. So, we just ignore them. We must clobber the symbol - name to keep it from being put in the string table. */ + unless we are prepared to convert it into COFF debugging + format. So, we just ignore them. We must clobber the symbol + name to keep it from being put in the string table. */ symbol->name = ""; if (isym != NULL) - memset (isym, 0, sizeof (*isym)); + memset (isym, 0, sizeof (*isym)); return TRUE; } else @@ -1132,7 +1133,7 @@ coff_write_alien_symbol (bfd *abfd, native->u.syment.n_value += output_section->vma; /* Copy the any flags from the file header into the symbol. - FIXME: Why? */ + FIXME: Why? */ { coff_symbol_type *c = coff_symbol_from (symbol); if (c != (coff_symbol_type *) NULL) @@ -1418,8 +1419,8 @@ coff_write_symbols (bfd *abfd) else { /* We would normally not write anything here, but we'll write - out 4 so that any stupid coff reader which tries to read the - string table even when there isn't one won't croak. */ + out 4 so that any stupid coff reader which tries to read the + string table even when there isn't one won't croak. */ unsigned int size = STRING_SIZE_SIZE; bfd_byte buffer[STRING_SIZE_SIZE]; @@ -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; @@ -1640,13 +1649,25 @@ _bfd_coff_get_external_symbols (bfd *abfd) size = obj_raw_syment_count (abfd) * symesz; if (size == 0) return TRUE; + /* Check for integer overflow and for unreasonable symbol counts. */ + if (size < obj_raw_syment_count (abfd) + || (bfd_get_file_size (abfd) > 0 + && size > bfd_get_file_size (abfd))) + + { + _bfd_error_handler (_("%pB: corrupt symbol count: %#" PRIx64 ""), + abfd, (uint64_t) obj_raw_syment_count (abfd)); + return FALSE; + } syms = bfd_malloc (size); if (syms == NULL) { /* PR 21013: Provide an error message when the alloc fails. */ - _bfd_error_handler (_("%B: Not enough memory to allocate space for %lu symbols"), - abfd, size); + _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; } @@ -1659,7 +1680,6 @@ _bfd_coff_get_external_symbols (bfd *abfd) } obj_coff_external_syms (abfd) = syms; - return TRUE; } @@ -1709,11 +1729,11 @@ _bfd_coff_read_string_table (bfd *abfd) #endif } - if (strsize < STRING_SIZE_SIZE) + if (strsize < STRING_SIZE_SIZE || strsize > bfd_get_file_size (abfd)) { _bfd_error_handler /* xgettext: c-format */ - (_("%B: bad string table size %lu"), abfd, (unsigned long) strsize); + (_("%pB: bad string table size %" PRIu64), abfd, (uint64_t) strsize); bfd_set_error (bfd_error_bad_value); return NULL; } @@ -1747,12 +1767,16 @@ _bfd_coff_read_string_table (bfd *abfd) bfd_boolean _bfd_coff_free_symbols (bfd *abfd) { + if (! bfd_family_coff (abfd)) + return FALSE; + if (obj_coff_external_syms (abfd) != NULL && ! obj_coff_keep_syms (abfd)) { free (obj_coff_external_syms (abfd)); obj_coff_external_syms (abfd) = NULL; } + if (obj_coff_strings (abfd) != NULL && ! obj_coff_keep_strings (abfd)) { @@ -1760,6 +1784,7 @@ _bfd_coff_free_symbols (bfd *abfd) obj_coff_strings (abfd) = NULL; obj_coff_strings_len (abfd) = 0; } + return TRUE; } @@ -1789,7 +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 > (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; @@ -1816,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, @@ -1847,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); } } @@ -1890,8 +1910,8 @@ coff_get_normalized_symtab (bfd *abfd) else { /* Ordinary short filename, put into memory anyway. The - Microsoft PE tools sometimes store a filename in - multiple AUX entries. */ + Microsoft PE tools sometimes store a filename in + multiple AUX entries. */ if (internal_ptr->u.syment.n_numaux > 1 && coff_data (abfd)->pe) internal_ptr->u.syment._n._n_n._n_offset = @@ -1916,7 +1936,7 @@ coff_get_normalized_symtab (bfd *abfd) char *newstring; /* Find the length of this string without walking into memory - that isn't ours. */ + that isn't ours. */ for (i = 0; i < 8; ++i) if (internal_ptr->u.syment._n._n_name[i] == '\0') break; @@ -1933,7 +1953,7 @@ coff_get_normalized_symtab (bfd *abfd) else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment)) { /* Long name already. Point symbol at the string in the - table. */ + table. */ if (string_table == NULL) { string_table = _bfd_coff_read_string_table (abfd); @@ -1987,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 *); } @@ -2222,13 +2249,13 @@ _bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean coff_find_nearest_line_with_names (bfd *abfd, - asymbol **symbols, - asection *section, - bfd_vma offset, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *line_ptr, - const struct dwarf_debug_section *debug_sections) + asymbol **symbols, + asection *section, + bfd_vma offset, + const char **filename_ptr, + const char **functionname_ptr, + unsigned int *line_ptr, + const struct dwarf_debug_section *debug_sections) { bfd_boolean found; unsigned int i; @@ -2255,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; @@ -2267,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) @@ -2279,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; @@ -2294,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; } @@ -2330,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) @@ -2363,7 +2391,7 @@ coff_find_nearest_line_with_names (bfd *abfd, file_addr += coff_section_from_bfd_index (abfd, p2->u.syment.n_scnum)->vma; /* We use <= MAXDIFF here so that if we get a zero length - file, we actually use the next file entry. */ + file, we actually use the next file entry. */ if (p2 < pend && offset + sec_vma >= file_addr && offset + sec_vma - file_addr <= maxdiff) @@ -2372,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; } } @@ -2503,8 +2534,8 @@ coff_find_nearest_line (bfd *abfd, if (discriminator_ptr) *discriminator_ptr = 0; return coff_find_nearest_line_with_names (abfd, symbols, section, offset, - filename_ptr, functionname_ptr, - line_ptr, dwarf_debug_sections); + filename_ptr, functionname_ptr, + line_ptr, dwarf_debug_sections); } bfd_boolean @@ -2538,9 +2569,9 @@ coff_sizeof_headers (bfd *abfd, struct bfd_link_info *info) /* Change the class of a coff symbol held by BFD. */ bfd_boolean -bfd_coff_set_symbol_class (bfd * abfd, - asymbol * symbol, - unsigned int symbol_class) +bfd_coff_set_symbol_class (bfd * abfd, + asymbol * symbol, + unsigned int symbol_class) { coff_symbol_type * csym; @@ -2611,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; @@ -2619,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) @@ -2777,13 +2811,13 @@ _bfd_coff_gc_mark_hook (asection *sec, if (h != NULL) { switch (h->root.type) - { - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - return h->root.u.def.section; + { + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + return h->root.u.def.section; - case bfd_link_hash_common: - return h->root.u.c.p->section; + case bfd_link_hash_common: + return h->root.u.c.p->section; case bfd_link_hash_undefweak: if (h->symbol_class == C_NT_WEAK && h->numaux == 1) @@ -2801,9 +2835,9 @@ _bfd_coff_gc_mark_hook (asection *sec, break; case bfd_link_hash_undefined: - default: - break; - } + default: + break; + } return NULL; } @@ -2882,19 +2916,19 @@ _bfd_coff_gc_mark (struct bfd_link_info *info, struct coff_reloc_cookie cookie; if (!init_reloc_cookie_for_section (&cookie, info, sec)) - ret = FALSE; + ret = FALSE; else - { - for (; cookie.rel < cookie.relend; cookie.rel++) - { + { + for (; cookie.rel < cookie.relend; cookie.rel++) + { if (!_bfd_coff_gc_mark_reloc (info, sec, gc_mark_hook, &cookie)) { ret = FALSE; break; } } - fini_reloc_cookie_for_section (&cookie, sec); - } + fini_reloc_cookie_for_section (&cookie, sec); + } } return ret; @@ -2982,10 +3016,10 @@ coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) for (o = sub->sections; o != NULL; o = o->next) { /* Keep debug and special sections. */ - if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0 + if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0 || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) o->gc_mark = 1; - else if (CONST_STRNEQ (o->name, ".idata") + else if (CONST_STRNEQ (o->name, ".idata") || CONST_STRNEQ (o->name, ".pdata") || CONST_STRNEQ (o->name, ".xdata") || CONST_STRNEQ (o->name, ".rsrc")) @@ -3004,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 @@ -3081,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 @@ -3094,10 +3128,10 @@ bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) asection *o; if (bfd_get_flavour (sub) != bfd_target_coff_flavour) - continue; + continue; for (o = sub->sections; o != NULL; o = o->next) - { + { if (((o->flags & (SEC_EXCLUDE | SEC_KEEP)) == SEC_KEEP || CONST_STRNEQ (o->name, ".vectors") || CONST_STRNEQ (o->name, ".ctors") @@ -3107,7 +3141,7 @@ bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) if (!_bfd_coff_gc_mark (info, o, _bfd_coff_gc_mark_hook)) return FALSE; } - } + } } /* Allow the backend to mark additional target specific sections. */ @@ -3116,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; +}