X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcoffcode.h;h=d30cd58c4f32efbc3b61bfb7622c65189fb54d79;hb=92f402a7e03f5d747bc9a09c8da2f61cc539ac33;hp=9e1c20acf38963e4f210ed5299242d5b70b84f3c;hpb=063bb0250defafcc55544474a2961ecbc153882e;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 9e1c20acf3..d30cd58c4f 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-2015 Free Software Foundation, Inc. + Copyright (C) 1990-2017 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -962,10 +962,11 @@ 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 */ + /* PR 17512 file: 078-11867-0.004 */ if (symname == NULL) { - _bfd_error_handler (_("%B: unable to load COMDAT section name"), abfd); + _bfd_error_handler (_("%B: unable to load COMDAT section name"), + abfd); break; } @@ -996,7 +997,13 @@ handle_COMDAT (bfd * abfd, || isym.n_sclass == C_EXT) && BTYPE (isym.n_type) == T_NULL && isym.n_value == 0)) - abort (); + { + /* Malformed input files can trigger this test. + cf PR 21781. */ + _bfd_error_handler (_("%B: error: unexpected symbol '%s' in COMDAT section"), + abfd, symname); + goto breakloop; + } /* FIXME LATER: MSVC generates section names like .text for comdats. Gas generates @@ -1004,11 +1011,22 @@ handle_COMDAT (bfd * abfd, function). See comment above for more. */ if (isym.n_sclass == C_STAT && strcmp (name, symname) != 0) - _bfd_error_handler (_("%B: warning: COMDAT symbol '%s' does not match section name '%s'"), + /* xgettext:c-format */ + _bfd_error_handler (_("%B: warning: COMDAT symbol '%s'" + " does not match section name '%s'"), abfd, symname, name); seen_state = 1; + /* PR 17512: file: e2cfe54f. */ + if (esym + bfd_coff_symesz (abfd) >= esymend) + { + /* xgettext:c-format */ + _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, @@ -1162,7 +1180,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; @@ -1185,7 +1203,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; @@ -1229,7 +1247,9 @@ styp_to_sec_flags (bfd *abfd, /* Generate a warning message rather using the 'unhandled' variable as this will allow some .sys files generate by other toolchains to be processed. See bugzilla issue 196. */ - _bfd_error_handler (_("%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"), + /* xgettext:c-format */ + _bfd_error_handler (_("%B: Warning: Ignoring section flag" + " IMAGE_SCN_MEM_NOT_PAGED in section %s"), abfd, name); break; case IMAGE_SCN_MEM_EXECUTE: @@ -1295,8 +1315,9 @@ styp_to_sec_flags (bfd *abfd, /* If the section flag was not handled, report it here. */ if (unhandled != NULL) { - (*_bfd_error_handler) - (_("%B (%s): Section flag %s (0x%x) ignored"), + _bfd_error_handler + /* xgettext:c-format */ + (_("%B (%s): Section flag %s (%#lx) ignored"), abfd, name, unhandled, flag); result = FALSE; } @@ -1345,6 +1366,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 .{ @@ -1830,10 +1855,6 @@ coff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED, if ((1 << i) >= hdr->s_align) break; #endif -#ifdef TIC80COFF - /* TI tools puts the alignment power in bits 8-11. */ - i = (hdr->s_flags >> 8) & 0xF ; -#endif #ifdef COFF_DECODE_ALIGNMENT i = COFF_DECODE_ALIGNMENT(hdr->s_flags); #endif @@ -1926,9 +1947,9 @@ coff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED, section->rel_filepos += relsz; } else if (hdr->s_nreloc == 0xffff) - (*_bfd_error_handler) - ("%s: warning: claims to have 0xffff relocs, without overflow", - bfd_get_filename (abfd)); + _bfd_error_handler + (_("%B: warning: claims to have 0xffff relocs, without overflow"), + abfd); } #undef ALIGN_SET #undef ELIFALIGN_SET @@ -2073,7 +2094,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); @@ -2278,6 +2303,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) { @@ -2436,7 +2463,7 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) #endif default: arch = bfd_arch_obscure; - (*_bfd_error_handler) + _bfd_error_handler (_("Unrecognized TI COFF target id '0x%x'"), internal_f->f_target_id); break; @@ -2574,23 +2601,15 @@ coff_print_aux (bfd *abfd ATTRIBUTE_UNUSED, if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) != XTY_LD) { BFD_ASSERT (! aux->fix_scnlen); -#ifdef XCOFF64 - fprintf (file, "val %5lld", - (long long) aux->u.auxent.x_csect.x_scnlen.l); -#else - fprintf (file, "val %5ld", (long) aux->u.auxent.x_csect.x_scnlen.l); -#endif + fprintf (file, "val %5" BFD_VMA_FMT "d", + aux->u.auxent.x_csect.x_scnlen.l); } else { fprintf (file, "indx "); if (! aux->fix_scnlen) -#ifdef XCOFF64 - fprintf (file, "%4lld", - (long long) aux->u.auxent.x_csect.x_scnlen.l); -#else - fprintf (file, "%4ld", (long) aux->u.auxent.x_csect.x_scnlen.l); -#endif + fprintf (file, "%4" BFD_VMA_FMT "d", + aux->u.auxent.x_csect.x_scnlen.l); else fprintf (file, "%4ld", (long) (aux->u.auxent.x_csect.x_scnlen.p - table_base)); @@ -2666,10 +2685,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 @@ -2756,7 +2781,9 @@ coff_write_relocs (bfd * abfd, int first_undef) if (n.r_symndx > obj_conv_table_size (abfd)) { bfd_set_error (bfd_error_bad_value); - _bfd_error_handler (_("%B: reloc against a non-existant symbol index: %ld"), + /* xgettext:c-format */ + _bfd_error_handler (_("%B: reloc against a non-existent" + " symbol index: %ld"), abfd, n.r_symndx); return FALSE; } @@ -3151,6 +3178,16 @@ 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 + /* xgettext:c-format */ + (_("%B: page size is too large (0x%x)"), abfd, page_size); + return FALSE; + } } else page_size = PE_DEF_FILE_ALIGNMENT; @@ -3306,7 +3343,8 @@ coff_compute_section_file_positions (bfd * abfd) if (target_index >= bfd_coff_max_nscns (abfd)) { bfd_set_error (bfd_error_file_too_big); - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: too many sections (%d)"), abfd, target_index); return FALSE; } @@ -3716,7 +3754,9 @@ coff_write_object_contents (bfd * abfd) NUL-terminated. We use a temporary buffer so that we can still sprintf all eight chars without splatting a terminating NUL over the first byte of the following member (s_paddr). */ - char s_name_buf[SCNNMLEN + 1]; + /* PR 21096: The +20 is to stop a bogus warning from gcc7 about + a possible buffer overflow. */ + char s_name_buf[SCNNMLEN + 1 + 20]; /* An inherent limitation of the /nnnnnnn notation used to indicate the offset of the long name in the string table is that we @@ -3724,15 +3764,17 @@ coff_write_object_contents (bfd * abfd) if (string_size >= 10000000) { bfd_set_error (bfd_error_file_too_big); - (*_bfd_error_handler) - (_("%B: section %s: string table overflow at offset %ld"), - abfd, current->name, string_size); + _bfd_error_handler + /* xgettext:c-format */ + (_("%B: section %A: string table overflow at offset %ld"), + abfd, current, (unsigned long) string_size); return FALSE; } - /* snprintf not strictly necessary now we've verified the value - has less than eight ASCII digits, but never mind. */ - snprintf (s_name_buf, SCNNMLEN + 1, "/%lu", (unsigned long) string_size); + /* We do not need to use snprintf here as we have already verfied + that string_size is not too big, plus we have an overlarge + buffer, just in case. */ + sprintf (s_name_buf, "/%lu", (unsigned long) string_size); /* Then strncpy takes care of any padding for us. */ strncpy (section.s_name, s_name_buf, SCNNMLEN); string_size += len + 1; @@ -3819,12 +3861,25 @@ coff_write_object_contents (bfd * abfd) ? 1 << current->alignment_power : 0); #endif -#ifdef TIC80COFF - /* TI COFF puts the alignment power in bits 8-11 of the flags. */ - section.s_flags |= (current->alignment_power & 0xF) << 8; -#endif #ifdef COFF_ENCODE_ALIGNMENT COFF_ENCODE_ALIGNMENT(section, current->alignment_power); + if ((unsigned int)COFF_DECODE_ALIGNMENT(section.s_flags) + != current->alignment_power) + { + bfd_boolean warn = coff_data (abfd)->link_info + && !bfd_link_relocatable (coff_data (abfd)->link_info); + + _bfd_error_handler + /* xgettext:c-format */ + (_("%B:%s section %s: alignment 2**%u not representable"), + abfd, warn ? " warning:" : "", current->name, + current->alignment_power); + if (!warn) + { + bfd_set_error (bfd_error_nonrepresentable_section); + return FALSE; + } + } #endif #ifdef COFF_IMAGE_WITH_PE @@ -4044,6 +4099,8 @@ coff_write_object_contents (bfd * abfd) internal_f.f_flags |= F_DYNLOAD; #endif + memset (&internal_a, 0, sizeof internal_a); + /* Set up architecture-dependent stuff. */ { unsigned int magic = 0; @@ -4526,9 +4583,18 @@ coff_slurp_line_table (bfd *abfd, asection *asect) unsigned int nbr_func; LINENO *src; bfd_boolean have_func; + bfd_boolean ret = TRUE; BFD_ASSERT (asect->lineno == NULL); + if (asect->lineno_count > asect->size) + { + _bfd_error_handler + (_("%B: warning: line number count (%#lx) exceeds section size (%#lx)"), + abfd, (unsigned long) asect->lineno_count, (unsigned long) asect->size); + return FALSE; + } + amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent); lineno_cache = (alent *) bfd_alloc (abfd, amt); if (lineno_cache == NULL) @@ -4538,7 +4604,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos, amt); if (native_lineno == NULL) { - (*_bfd_error_handler) + _bfd_error_handler (_("%B: warning: line number table read failed"), abfd); bfd_release (abfd, lineno_cache); return FALSE; @@ -4564,17 +4630,19 @@ coff_slurp_line_table (bfd *abfd, asection *asect) if (cache_ptr->line_number == 0) { combined_entry_type * ent; - bfd_vma symndx; + unsigned long symndx; coff_symbol_type *sym; have_func = FALSE; symndx = dst.l_addr.l_symndx; if (symndx >= obj_raw_syment_count (abfd)) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), - abfd, (long) symndx, counter); + abfd, symndx, counter); cache_ptr->line_number = -1; + ret = FALSE; continue; } @@ -4583,10 +4651,12 @@ coff_slurp_line_table (bfd *abfd, asection *asect) pointers like this. */ if (! ent->is_sym) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), - abfd, (long) symndx, counter); + abfd, symndx, counter); cache_ptr->line_number = -1; + ret = FALSE; continue; } sym = (coff_symbol_type *) (ent->u.syment._n._n_n._n_zeroes); @@ -4595,10 +4665,12 @@ coff_slurp_line_table (bfd *abfd, asection *asect) if (sym < obj_symbols (abfd) || sym >= obj_symbols (abfd) + bfd_get_symcount (abfd)) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: warning: illegal symbol in line number entry %d"), abfd, counter); cache_ptr->line_number = -1; + ret = FALSE; continue; } @@ -4606,7 +4678,8 @@ coff_slurp_line_table (bfd *abfd, asection *asect) nbr_func++; cache_ptr->u.sym = (asymbol *) sym; if (sym->lineno != NULL) - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: warning: duplicate line number information for `%s'"), abfd, bfd_asymbol_name (&sym->symbol)); @@ -4648,7 +4721,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) *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); @@ -4678,11 +4751,15 @@ coff_slurp_line_table (bfd *abfd, asection *asect) 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 @@ -4697,6 +4774,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; @@ -4756,6 +4834,9 @@ coff_slurp_symbol_table (bfd * abfd) #endif #ifdef RS6000COFF_C case C_HIDEXT: +#if ! defined _AIX52 && ! defined AIX_WEAK_SUPPORT + case C_AIX_WEAKEXT: +#endif #endif #ifdef C_SYSTEM case C_SYSTEM: /* System Wide variable. */ @@ -4828,7 +4909,11 @@ coff_slurp_symbol_table (bfd * abfd) && src->u.syment.n_scnum > 0) dst->symbol.flags = BSF_LOCAL; #endif - if (src->u.syment.n_sclass == C_WEAKEXT) + if (src->u.syment.n_sclass == C_WEAKEXT +#ifdef RS6000COFF_C + || src->u.syment.n_sclass == C_AIX_WEAKEXT +#endif + ) dst->symbol.flags |= BSF_WEAK; break; @@ -5012,13 +5097,18 @@ 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. */ default: - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: Unrecognized storage class %d for %s symbol `%s'"), abfd, src->u.syment.n_sclass, dst->symbol.section->name, dst->symbol.name); - case C_EXTLAB: /* External load time label. */ + ret = FALSE; + /* Fall through. */ case C_HIDDEN: /* Ext symbol in dmert public lib. */ + /* PR 20722: These symbols can also be generated by + building DLLs with --gc-sections enabled. */ dst->symbol.flags = BSF_DEBUGGING; dst->symbol.value = (src->u.syment.n_value); break; @@ -5052,7 +5142,7 @@ coff_slurp_symbol_table (bfd * abfd) } } - return TRUE; + return ret; } /* Classify a COFF symbol. A couple of targets have globally visible @@ -5113,7 +5203,7 @@ coff_classify_symbol (bfd *abfd, asection *sec; char * name; char buf[SYMNMLEN + 1]; - + name = _bfd_coff_internal_syment_name (abfd, syment, buf) sec = coff_section_from_bfd_index (abfd, syment->n_scnum); if (sec != NULL && name != NULL @@ -5142,7 +5232,8 @@ coff_classify_symbol (bfd *abfd, { char buf[SYMNMLEN + 1]; - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("warning: %B: local symbol `%s' has no section"), abfd, _bfd_coff_internal_syment_name (abfd, syment, buf)); } @@ -5244,13 +5335,14 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols) #else cache_ptr->address = dst.r_vaddr; - if (dst.r_symndx != -1) + if (dst.r_symndx != -1 && symbols != NULL) { if (dst.r_symndx < 0 || dst.r_symndx >= obj_conv_table_size (abfd)) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: warning: illegal symbol index %ld in relocs"), - abfd, (long) dst.r_symndx); + abfd, dst.r_symndx); cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; ptr = NULL; } @@ -5287,9 +5379,10 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols) if (cache_ptr->howto == NULL) { - (*_bfd_error_handler) - (_("%B: illegal relocation type %d at address 0x%lx"), - abfd, dst.r_type, (long) dst.r_vaddr); + _bfd_error_handler + /* xgettext:c-format */ + (_("%B: illegal relocation type %d at address %#Lx"), + abfd, dst.r_type, dst.r_vaddr); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -5368,6 +5461,10 @@ coff_canonicalize_reloc (bfd * abfd, return section->reloc_count; } +#ifndef coff_set_reloc +#define coff_set_reloc _bfd_generic_set_reloc +#endif + #ifndef coff_reloc16_estimate #define coff_reloc16_estimate dummy_reloc16_estimate @@ -5436,6 +5533,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 @@ -5717,6 +5816,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); @@ -5955,7 +6055,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 @@ -5983,6 +6083,10 @@ static bfd_coff_backend_data bigobj_swap_table = #define coff_bfd_define_common_symbol bfd_generic_define_common_symbol #endif +#ifndef coff_bfd_define_start_stop +#define coff_bfd_define_start_stop bfd_generic_define_start_stop +#endif + #define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE) \ const bfd_target VAR = \ { \