obj_coff_sym_hashes sanity checks
Checks
Commit Message
Various places in cofflink.c and coffgen.c assume the r_symndx
indexing sym_hashes is sane. Add some checks.
* cofflink.c (_bfd_coff_link_input_bfd): Sanity check r_symndx
against obj_raw_syment_count before using it to index sym_hashes,
rather than just checking for the special -1 value.
(_bfd_coff_generic_relocate_section): Delete unnecessary check.
Sanity check weak symndx2 against obj_raw_syment_count.
* coffgen.c (_bfd_coff_gc_mark_hook): Sanity check weak symndx2
against obj_raw_syment_count.
(_bfd_coff_gc_mark_rsec): Sanity check r_symndx.
@@ -2953,9 +2953,10 @@ _bfd_coff_gc_mark_hook (asection *sec,
/* PE weak externals. A weak symbol may include an auxiliary
record indicating that if the weak symbol is not resolved,
another external symbol is used instead. */
- struct coff_link_hash_entry *h2 =
- h->auxbfd->tdata.coff_obj_data->sym_hashes
- [h->aux->x_sym.x_tagndx.u32];
+ struct coff_link_hash_entry *h2 = NULL;
+ unsigned long symndx2 = h->aux->x_sym.x_tagndx.u32;
+ if (symndx2 < obj_raw_syment_count (h->auxbfd))
+ h2 = obj_coff_sym_hashes (h->auxbfd)[symndx2];
if (h2 && h2->root.type != bfd_link_hash_undefined)
return h2->root.u.def.section;
@@ -2982,8 +2983,11 @@ _bfd_coff_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
struct coff_reloc_cookie *cookie)
{
struct coff_link_hash_entry *h;
+ unsigned long rsym = cookie->rel->r_symndx;
- h = cookie->sym_hashes[cookie->rel->r_symndx];
+ if (rsym >= obj_raw_syment_count (cookie->abfd))
+ return NULL;
+ h = cookie->sym_hashes[rsym];
if (h != NULL)
{
while (h->root.type == bfd_link_hash_indirect
@@ -2995,7 +2999,7 @@ _bfd_coff_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
return (*gc_mark_hook) (sec, info, cookie->rel, NULL,
&(cookie->symbols
- + obj_convert (sec->owner)[cookie->rel->r_symndx])->native->u.syment);
+ + obj_convert (sec->owner)[rsym])->native->u.syment);
}
static bool _bfd_coff_gc_mark
@@ -2409,8 +2409,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
{
struct coff_link_hash_entry *h;
asection *ps = NULL;
- long symndx = irel->r_symndx;
- if (symndx < 0)
+ unsigned long symndx = irel->r_symndx;
+ if (symndx >= obj_raw_syment_count (input_bfd))
continue;
h = obj_coff_sym_hashes (input_bfd)[symndx];
if (h == NULL)
@@ -2463,7 +2463,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
/* Adjust the reloc address and symbol index. */
irel->r_vaddr += offset;
- if (irel->r_symndx == -1)
+ if ((unsigned long) irel->r_symndx
+ >= obj_raw_syment_count (input_bfd))
continue;
if (adjust_symndx)
@@ -2971,8 +2972,7 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
h = NULL;
sym = NULL;
}
- else if (symndx < 0
- || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
+ else if ((unsigned long) symndx >= obj_raw_syment_count (input_bfd))
{
_bfd_error_handler
/* xgettext: c-format */
@@ -3065,9 +3065,10 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
will resolve a weak external only if a normal
external causes the library member to be linked.
See also linker.c: generic_link_check_archive_element. */
- struct coff_link_hash_entry *h2 =
- h->auxbfd->tdata.coff_obj_data->sym_hashes
- [h->aux->x_sym.x_tagndx.u32];
+ struct coff_link_hash_entry *h2 = NULL;
+ unsigned long symndx2 = h->aux->x_sym.x_tagndx.u32;
+ if (symndx2 < obj_raw_syment_count (h->auxbfd))
+ h2 = obj_coff_sym_hashes (h->auxbfd)[symndx2];
if (!h2 || h2->root.type == bfd_link_hash_undefined)
{