/* Support for the generic parts of COFF, for BFD.
- Copyright (C) 1990-2018 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.
coff_data (abfd). */
#include "sysdep.h"
+#include <limits.h>
#include "bfd.h"
#include "libbfd.h"
#include "coff/internal.h"
break;
}
if (new_name != NULL)
- bfd_rename_section (abfd, return_section, new_name);
+ bfd_rename_section (return_section, new_name);
}
return result;
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. */
fail2:
abfd->tdata.any = tdata_save;
abfd->flags = oflags;
- bfd_get_start_address (abfd) = ostart;
+ abfd->start_address = ostart;
return (const bfd_target *) NULL;
}
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;
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 ((unsigned long) auxent->u.auxent.x_sym.x_tagndx.l
- < obj_raw_syment_count (abfd))
+ < 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;
&& size > bfd_get_file_size (abfd)))
{
- _bfd_error_handler (_("%pB: 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;
}
if (syms == NULL)
{
/* PR 21013: Provide an error message when the alloc fails. */
- _bfd_error_handler (_("%pB: 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;
}
{
_bfd_error_handler
/* xgettext: c-format */
- (_("%pB: 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;
}
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;
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,
internal_ptr->is_sym = FALSE;
coff_pointerize_aux (abfd, internal, symbol_ptr, i,
- internal_ptr);
+ internal_ptr, internal_end);
}
}
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 *);
}
/* 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;
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)
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;
&& _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;
}
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)
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;
}
}
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;
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)
if (info->print_gc_sections && o->size != 0)
/* xgettext: c-format */
- _bfd_error_handler (_("Removing unused section '%pA' in file '%pB'"),
+ _bfd_error_handler (_("removing unused section '%pA' in file '%pB'"),
o, sub);
#if 0
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
/* ... 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;
+}