/* 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.
.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;
.
.
/* 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);
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,
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;
. 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
.{
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;
#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)
{
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)
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
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;
{
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;
/* 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:
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;
}
/*
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);
asect->lineno = lineno_cache;
src = native_lineno;
nbr_func = 0;
+ have_func = FALSE;
for (counter = 0; counter < asect->lineno_count; counter++, src++)
{
if (cache_ptr->line_number == 0)
{
+ combined_entry_type * ent;
bfd_vma symndx;
coff_symbol_type *sym;
+ have_func = FALSE;
symndx = dst.l_addr.l_symndx;
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) + obj_raw_syment_count (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)
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));
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);
/* 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);
}
+ 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;
table_ptr[this_index] = number_of_symbols;
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)
#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++;
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 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
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 \
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)
#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_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