/* Support for the generic parts of most COFF variants, for BFD.
- Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Copyright (C) 1990-2018 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
.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
. 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
. 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;
.
.
#define COFFLONGSECTIONCATHELPER(x,y) x ## y
/* If the input macro Y is blank or '1', return an odd number; if it is
'0', return an even number. Result undefined in all other cases. */
-#define BLANKOR1TOODD(y) COFFLONGSECTIONCATHELPER(1,y)
+#define BLANKOR1TOODD(y) COFFLONGSECTIONCATHELPER(1,y)
/* Defined to numerical 0 or 1 according to whether generation of long
section names is disabled or enabled by default. */
#define COFF_ENABLE_LONG_SECTION_NAMES (BLANKOR1TOODD(COFF_LONG_SECTION_NAMES) & 1)
#endif /* _LIT */
}
else if (CONST_STRNEQ (sec_name, DOT_DEBUG)
- || CONST_STRNEQ (sec_name, DOT_ZDEBUG))
+ || CONST_STRNEQ (sec_name, DOT_ZDEBUG))
{
/* Handle the XCOFF debug section and DWARF2 debug sections. */
if (!sec_name[6])
}
#ifdef COFF_LONG_SECTION_NAMES
else if (CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)
- || CONST_STRNEQ (sec_name, GNU_LINKONCE_WT))
+ || CONST_STRNEQ (sec_name, GNU_LINKONCE_WT))
{
styp_flags = STYP_DEBUG_INFO;
}
int i;
for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
- if (!strcmp (sec_name, xcoff_dwsect_names[i].name))
- {
- styp_flags = STYP_DWARF | xcoff_dwsect_names[i].flag;
- break;
- }
+ if (!strcmp (sec_name, xcoff_dwsect_names[i].name))
+ {
+ styp_flags = STYP_DWARF | xcoff_dwsect_names[i].flag;
+ break;
+ }
}
#endif
/* Try and figure out what it should be */
if (is_dbg)
{
sec_flags &= (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
- | SEC_LINK_DUPLICATES_SAME_CONTENTS
- | SEC_LINK_DUPLICATES_SAME_SIZE);
+ | SEC_LINK_DUPLICATES_SAME_CONTENTS
+ | SEC_LINK_DUPLICATES_SAME_SIZE);
sec_flags |= SEC_DEBUGGING | SEC_READONLY;
}
styp_flags |= IMAGE_SCN_LNK_COMDAT;
if ((sec_flags
& (SEC_LINK_DUPLICATES_DISCARD | SEC_LINK_DUPLICATES_SAME_CONTENTS
- | SEC_LINK_DUPLICATES_SAME_SIZE)) != 0)
+ | SEC_LINK_DUPLICATES_SAME_SIZE)) != 0)
styp_flags |= IMAGE_SCN_LNK_COMDAT;
/* skip LINKER_CREATED */
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)
{
/* 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)
{
|| 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
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,
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;
/* 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;
/* 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:
/* 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;
}
. 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
.{
.
. bfd_boolean (*_bfd_coff_pointerize_aux_hook)
. (bfd *, combined_entry_type *, combined_entry_type *,
-. unsigned int, combined_entry_type *);
+. unsigned int, combined_entry_type *);
.
. bfd_boolean (*_bfd_coff_print_aux)
. (bfd *, FILE *, combined_entry_type *, combined_entry_type *,
-. combined_entry_type *, unsigned int);
+. combined_entry_type *, unsigned int);
.
. void (*_bfd_coff_reloc16_extra_cases)
. (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
-. bfd_byte *, unsigned int *, unsigned int *);
+. bfd_byte *, unsigned int *, unsigned int *);
.
. int (*_bfd_coff_reloc16_estimate)
. (bfd *, asection *, arelent *, unsigned int,
-. struct bfd_link_info *);
+. struct bfd_link_info *);
.
. enum coff_symbol_classification (*_bfd_coff_classify_symbol)
. (bfd *, struct internal_syment *);
.
. bfd_boolean (*_bfd_coff_relocate_section)
. (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
-. struct internal_reloc *, struct internal_syment *, asection **);
+. struct internal_reloc *, struct internal_syment *, asection **);
.
. reloc_howto_type *(*_bfd_coff_rtype_to_howto)
. (bfd *, asection *, struct internal_reloc *,
-. struct coff_link_hash_entry *, struct internal_syment *,
-. bfd_vma *);
+. struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *);
.
. bfd_boolean (*_bfd_coff_adjust_symndx)
. (bfd *, struct bfd_link_info *, bfd *, asection *,
-. struct internal_reloc *, bfd_boolean *);
+. struct internal_reloc *, bfd_boolean *);
.
. bfd_boolean (*_bfd_coff_link_add_one_symbol)
. (struct bfd_link_info *, bfd *, const char *, flagword,
-. asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
-. struct bfd_link_hash_entry **);
+. asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
+. struct bfd_link_hash_entry **);
.
. bfd_boolean (*_bfd_coff_link_output_has_begun)
. (bfd *, struct coff_final_link_info *);
. (abfd, file, base, symbol, aux, indaux))
.
.#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order,\
-. reloc, data, src_ptr, dst_ptr)\
+. reloc, data, src_ptr, dst_ptr)\
. ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\
. (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr))
.
. ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
. (obfd, info, ibfd, sec, rel, adjustedp))
.#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\
-. value, string, cp, coll, hashp)\
+. value, string, cp, coll, hashp)\
. ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\
. (info, abfd, name, flags, section, value, string, cp, coll, hashp))
.
int i;
for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
- if (strcmp (bfd_get_section_name (abfd, section),
- xcoff_dwsect_names[i].name) == 0)
- {
- section->alignment_power = 0;
- sclass = C_DWARF;
- break;
- }
+ if (strcmp (bfd_get_section_name (abfd, section),
+ xcoff_dwsect_names[i].name) == 0)
+ {
+ section->alignment_power = 0;
+ sclass = C_DWARF;
+ break;
+ }
}
#endif
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;
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
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
#else /* ! RS6000COFF_C */
-#define coff_set_alignment_hook \
- ((void (*) (bfd *, asection *, void *)) bfd_void)
+static void
+coff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ void *scnhdr ATTRIBUTE_UNUSED)
+{
+}
#endif /* ! RS6000COFF_C */
#endif /* ! COFF_WITH_PE */
#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);
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)
{
#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;
return TRUE;
}
-#ifdef SYMNAME_IN_DEBUG
-
static bfd_boolean
-symname_in_debug_hook (bfd * abfd ATTRIBUTE_UNUSED, struct internal_syment *sym)
+symname_in_debug_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED)
{
+#ifdef SYMNAME_IN_DEBUG
return SYMNAME_IN_DEBUG (sym) != 0;
-}
-
#else
-
-#define symname_in_debug_hook \
- (bfd_boolean (*) (bfd *, struct internal_syment *)) bfd_false
-
+ return FALSE;
#endif
+}
#ifdef RS6000COFF_C
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 =
/* 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));
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)
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));
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
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;
}
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;
{
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;
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;
}
and the native linker doesn't try to align the text sections.
For example:
- 0 .text 000054cc 10000128 10000128 00000128 2**5
- CONTENTS, ALLOC, LOAD, CODE
+ 0 .text 000054cc 10000128 10000128 00000128 2**5
+ CONTENTS, ALLOC, LOAD, CODE
*/
if (!strcmp (current->name, _TEXT)
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
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;
? 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
/* 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)
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:
- a (four byte) word holding the length of this record, in words,
- a word that always seems to be set to "2",
- the path to a shared library, null-terminated and then padded
- to a whole word boundary.
+ to a whole word boundary.
bfd_assert calls have been added to alert if an attempt is made
to write a section which doesn't follow these assumptions. The
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;
}
/*
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)
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);
+ 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)
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;
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_boolean warned;
- bfd_signed_vma symndx;
+ combined_entry_type * ent;
+ unsigned long symndx;
coff_symbol_type *sym;
- nbr_func++;
- warned = FALSE;
+ 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 %ld in line numbers"),
- abfd, (long) symndx);
- symndx = 0;
- warned = TRUE;
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
+ abfd, 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
+ /* xgettext:c-format */
+ (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
+ abfd, 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
+ /* xgettext:c-format */
+ (_("%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 && ! warned)
- (*_bfd_error_handler)
+ if (sym->lineno != NULL)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: warning: duplicate line number information for `%s'"),
abfd, bfd_asymbol_name (&sym->symbol));
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. */
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)
{
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
unsigned int *table_ptr;
bfd_size_type amt;
unsigned int number_of_symbols = 0;
+ bfd_boolean ret = TRUE;
if (obj_symbols (abfd))
return TRUE;
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;
{
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)
#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. */
&& 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;
case C_THUMBSTATFUNC:/* Thumb static function. */
#endif
#ifdef RS6000COFF_C
- case C_DWARF: /* A label in a dwarf section. */
- case C_INFO: /* A label in a comment section. */
+ case C_DWARF: /* A label in a dwarf section. */
+ case C_INFO: /* A label in a comment section. */
#endif
case C_LABEL: /* Label. */
if (src->u.syment.n_scnum == N_DEBUG)
&& src->u.syment.n_scnum == 0)
break;
#ifdef RS6000COFF_C
- /* XCOFF specific: deleted entry. */
- if (src->u.syment.n_value == C_NULL_VALUE)
- break;
+ /* XCOFF specific: deleted entry. */
+ if (src->u.syment.n_value == C_NULL_VALUE)
+ break;
#endif
/* Fall through. */
case C_EXTDEF: /* External definition. */
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)
+ _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);
+ 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;
}
dst->native = src;
-
dst->symbol.udata.i = 0;
dst->lineno = NULL;
+
this_index += (src->u.syment.n_numaux) + 1;
dst++;
number_of_symbols++;
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
if (syment->n_value == 0)
{
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
- && (strcmp (bfd_get_section_name (abfd, sec),
- _bfd_coff_internal_syment_name (abfd, syment, buf))
- == 0))
+ if (sec != NULL && name != NULL
+ && (strcmp (bfd_get_section_name (abfd, sec), name) == 0))
return COFF_SYMBOL_PE_SECTION;
}
#endif
{
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));
}
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 \
#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;
}
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;
}
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)
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
_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
#endif
#ifdef COFF_WITH_PE_BIGOBJ
-/* The UUID for bigobj files. */
+/* The UID for bigobj files. */
static const char header_bigobj_classid[16] =
{
}
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);
#endif
#ifndef coff_bfd_is_target_special_symbol
-#define coff_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define coff_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
#endif
#ifndef coff_read_minisymbols
#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
#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 = \
{ \
bfd_getb32, bfd_getb_signed_32, bfd_putb32, \
bfd_getb16, bfd_getb_signed_16, bfd_putb16, \
\
- /* bfd_check_format. */ \
- { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p, \
- _bfd_dummy_target }, \
- /* bfd_set_format. */ \
- { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false }, \
- /* bfd_write_contents. */ \
- { bfd_false, coff_write_object_contents, _bfd_write_archive_contents, \
- bfd_false }, \
+ { /* bfd_check_format. */ \
+ _bfd_dummy_target, \
+ coff_object_p, \
+ bfd_generic_archive_p, \
+ _bfd_dummy_target \
+ }, \
+ { /* bfd_set_format. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_mkobject, \
+ _bfd_generic_mkarchive, \
+ _bfd_bool_bfd_false_error \
+ }, \
+ { /* bfd_write_contents. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_write_object_contents, \
+ _bfd_write_archive_contents, \
+ _bfd_bool_bfd_false_error \
+ }, \
\
BFD_JUMP_TABLE_GENERIC (coff), \
BFD_JUMP_TABLE_COPY (coff), \
bfd_getb32, bfd_getb_signed_32, bfd_putb32, \
bfd_getb16, bfd_getb_signed_16, bfd_putb16, \
\
- /* bfd_check_format. */ \
- { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p, \
- _bfd_dummy_target }, \
- /* bfd_set_format. */ \
- { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false }, \
- /* bfd_write_contents. */ \
- { bfd_false, coff_write_object_contents, _bfd_write_archive_contents, \
- bfd_false }, \
+ { /* bfd_check_format. */ \
+ _bfd_dummy_target, \
+ coff_object_p, \
+ bfd_generic_archive_p, \
+ _bfd_dummy_target \
+ }, \
+ { /* bfd_set_format. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_mkobject, \
+ _bfd_generic_mkarchive, \
+ _bfd_bool_bfd_false_error \
+ }, \
+ { /* bfd_write_contents. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_write_object_contents, \
+ _bfd_write_archive_contents, \
+ _bfd_bool_bfd_false_error \
+ }, \
\
BFD_JUMP_TABLE_GENERIC (coff), \
BFD_JUMP_TABLE_COPY (coff), \
bfd_getl64, bfd_getl_signed_64, bfd_putl64, \
bfd_getl32, bfd_getl_signed_32, bfd_putl32, \
bfd_getl16, bfd_getl_signed_16, bfd_putl16, \
- /* bfd_check_format. */ \
- { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p, \
- _bfd_dummy_target }, \
- /* bfd_set_format. */ \
- { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false }, \
- /* bfd_write_contents. */ \
- { bfd_false, coff_write_object_contents, _bfd_write_archive_contents, \
- bfd_false }, \
+ \
+ { /* bfd_check_format. */ \
+ _bfd_dummy_target, \
+ coff_object_p, \
+ bfd_generic_archive_p, \
+ _bfd_dummy_target \
+ }, \
+ { /* bfd_set_format. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_mkobject, \
+ _bfd_generic_mkarchive, \
+ _bfd_bool_bfd_false_error \
+ }, \
+ { /* bfd_write_contents. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_write_object_contents, \
+ _bfd_write_archive_contents, \
+ _bfd_bool_bfd_false_error \
+ }, \
\
BFD_JUMP_TABLE_GENERIC (coff), \
BFD_JUMP_TABLE_COPY (coff), \