* libbfd-in.h (bfd_malloc2, bfd_realloc2, bfd_zmalloc2, bfd_alloc2,

bfd_zalloc2): New prototypes.
	* bfd-in.h (HALF_BFD_SIZE_TYPE): Define.
	* libbfd.c (bfd_malloc2, bfd_realloc2, bfd_zmalloc2): New functions.
	* opncls.c (bfd_alloc2, bfd_zalloc2): New functions.
	* elf.c (bfd_elf_get_elf_syms, setup_group, assign_section_numbers,
	elf_map_symbols, map_sections_to_segments,
	assign_file_positions_for_segments, copy_private_bfd_data,
	swap_out_syms, _bfd_elf_slurp_version_tables): Use bfd_*alloc2
	where appropriate.
	* bfd-in2.h: Rebuilt.
	* libbfd.h: Rebuilt.

	* elf.c (_bfd_elf_print_private_bfd_data): Don't crash on bogus
	verdef or verneed section.
	(_bfd_elf_slurp_version_tables): Handle corrupt verdef and/or
	verneed sections gracefully.
	* elfxx-sparc.c (_bfd_sparc_elf_info_to_howto_ptr): Don't crash on
	bogus relocation values.
	* elf64-ppc.c (ppc64_elf_info_to_howto): Likewise.
	* elf64-s390.c (elf_s390_info_to_howto): Likewise.
	* elf32-s390.c (elf_s390_info_to_howto): Likewise.
	* elf64-x86-64.c (elf64_x86_64_info_to_howto): Likewise.
	* elfxx-ia64.c (lookup_howto): Likewise.
This commit is contained in:
Jakub Jelinek 2005-07-05 09:44:20 +00:00
parent c6c60d09fd
commit d0fb9a8d03
14 changed files with 386 additions and 73 deletions

View File

@ -1,5 +1,30 @@
2005-07-05 Jakub Jelinek <jakub@redhat.com>
* libbfd-in.h (bfd_malloc2, bfd_realloc2, bfd_zmalloc2, bfd_alloc2,
bfd_zalloc2): New prototypes.
* bfd-in.h (HALF_BFD_SIZE_TYPE): Define.
* libbfd.c (bfd_malloc2, bfd_realloc2, bfd_zmalloc2): New functions.
* opncls.c (bfd_alloc2, bfd_zalloc2): New functions.
* elf.c (bfd_elf_get_elf_syms, setup_group, assign_section_numbers,
elf_map_symbols, map_sections_to_segments,
assign_file_positions_for_segments, copy_private_bfd_data,
swap_out_syms, _bfd_elf_slurp_version_tables): Use bfd_*alloc2
where appropriate.
* bfd-in2.h: Rebuilt.
* libbfd.h: Rebuilt.
* elf.c (_bfd_elf_print_private_bfd_data): Don't crash on bogus
verdef or verneed section.
(_bfd_elf_slurp_version_tables): Handle corrupt verdef and/or
verneed sections gracefully.
* elfxx-sparc.c (_bfd_sparc_elf_info_to_howto_ptr): Don't crash on
bogus relocation values.
* elf64-ppc.c (ppc64_elf_info_to_howto): Likewise.
* elf64-s390.c (elf_s390_info_to_howto): Likewise.
* elf32-s390.c (elf_s390_info_to_howto): Likewise.
* elf64-x86-64.c (elf64_x86_64_info_to_howto): Likewise.
* elfxx-ia64.c (lookup_howto): Likewise.
* elf.c (bfd_elf_get_str_section): Allocate an extra byte after
the end of strtab and clear it.
(elf_read): Remove.

View File

@ -136,6 +136,9 @@ typedef unsigned long bfd_size_type;
#endif /* not BFD64 */
#define HALF_BFD_SIZE_TYPE \
(((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
#ifndef BFD_HOST_64_BIT
/* Fall back on a 32 bit type. The idea is to make these types always
available for function return types, but in the case that

View File

@ -143,6 +143,9 @@ typedef unsigned long bfd_size_type;
#endif /* not BFD64 */
#define HALF_BFD_SIZE_TYPE \
(((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
#ifndef BFD_HOST_64_BIT
/* Fall back on a 32 bit type. The idea is to make these types always
available for function return types, but in the case that

174
bfd/elf.c
View File

@ -340,7 +340,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
pos = symtab_hdr->sh_offset + symoffset * extsym_size;
if (extsym_buf == NULL)
{
alloc_ext = bfd_malloc (amt);
alloc_ext = bfd_malloc2 (symcount, extsym_size);
extsym_buf = alloc_ext;
}
if (extsym_buf == NULL
@ -359,7 +359,8 @@ bfd_elf_get_elf_syms (bfd *ibfd,
pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
if (extshndx_buf == NULL)
{
alloc_extshndx = bfd_malloc (amt);
alloc_extshndx = bfd_malloc2 (symcount,
sizeof (Elf_External_Sym_Shndx));
extshndx_buf = alloc_extshndx;
}
if (extshndx_buf == NULL
@ -373,8 +374,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
if (intsym_buf == NULL)
{
bfd_size_type amt = symcount * sizeof (Elf_Internal_Sym);
intsym_buf = bfd_malloc (amt);
intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
if (intsym_buf == NULL)
goto out;
}
@ -496,8 +496,8 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
bfd_size_type amt;
elf_tdata (abfd)->num_group = num_group;
amt = num_group * sizeof (Elf_Internal_Shdr *);
elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, amt);
elf_tdata (abfd)->group_sect_ptr
= bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
if (elf_tdata (abfd)->group_sect_ptr == NULL)
return FALSE;
@ -517,7 +517,8 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
/* Read the raw contents. */
BFD_ASSERT (sizeof (*dest) >= 4);
amt = shdr->sh_size * sizeof (*dest) / 4;
shdr->contents = bfd_alloc (abfd, amt);
shdr->contents = bfd_alloc2 (abfd, shdr->sh_size,
sizeof (*dest) / 4);
if (shdr->contents == NULL
|| bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
|| (bfd_bread (shdr->contents, shdr->sh_size, abfd)
@ -1219,8 +1220,9 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
{
fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
t->vd_flags, t->vd_hash, t->vd_nodename);
if (t->vd_auxptr->vda_nextptr != NULL)
t->vd_flags, t->vd_hash,
t->vd_nodename ? t->vd_nodename : "<corrupt>");
if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL)
{
Elf_Internal_Verdaux *a;
@ -1228,7 +1230,8 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
for (a = t->vd_auxptr->vda_nextptr;
a != NULL;
a = a->vda_nextptr)
fprintf (f, "%s ", a->vda_nodename);
fprintf (f, "%s ",
a->vda_nodename ? a->vda_nodename : "<corrupt>");
fprintf (f, "\n");
}
}
@ -1243,10 +1246,12 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
{
Elf_Internal_Vernaux *a;
fprintf (f, _(" required from %s:\n"), t->vn_filename);
fprintf (f, _(" required from %s:\n"),
t->vn_filename ? t->vn_filename : "<corrupt>");
for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
a->vna_flags, a->vna_other, a->vna_nodename);
a->vna_flags, a->vna_other,
a->vna_nodename ? a->vna_nodename : "<corrupt>");
}
}
@ -2883,7 +2888,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
asection *sec;
unsigned int section_number, secn;
Elf_Internal_Shdr **i_shdrp;
bfd_size_type amt;
struct bfd_elf_section_data *d;
section_number = 1;
@ -2987,13 +2991,11 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
/* Set up the list of section header pointers, in agreement with the
indices. */
amt = section_number * sizeof (Elf_Internal_Shdr *);
i_shdrp = bfd_zalloc (abfd, amt);
i_shdrp = bfd_zalloc2 (abfd, section_number, sizeof (Elf_Internal_Shdr *));
if (i_shdrp == NULL)
return FALSE;
amt = sizeof (Elf_Internal_Shdr);
i_shdrp[0] = bfd_zalloc (abfd, amt);
i_shdrp[0] = bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr));
if (i_shdrp[0] == NULL)
{
bfd_release (abfd, i_shdrp);
@ -3244,7 +3246,6 @@ elf_map_symbols (bfd *abfd)
unsigned int idx;
asection *asect;
asymbol **new_syms;
bfd_size_type amt;
#ifdef DEBUG
fprintf (stderr, "elf_map_symbols\n");
@ -3258,8 +3259,7 @@ elf_map_symbols (bfd *abfd)
}
max_index++;
amt = max_index * sizeof (asymbol *);
sect_syms = bfd_zalloc (abfd, amt);
sect_syms = bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
if (sect_syms == NULL)
return FALSE;
elf_section_syms (abfd) = sect_syms;
@ -3332,8 +3332,7 @@ elf_map_symbols (bfd *abfd)
}
/* Now sort the symbols so the local symbols are first. */
amt = (num_locals + num_globals) * sizeof (asymbol *);
new_syms = bfd_alloc (abfd, amt);
new_syms = bfd_alloc2 (abfd, num_locals + num_globals, sizeof (asymbol *));
if (new_syms == NULL)
return FALSE;
@ -3592,8 +3591,7 @@ map_sections_to_segments (bfd *abfd)
/* Select the allocated sections, and sort them. */
amt = bfd_count_sections (abfd) * sizeof (asection *);
sections = bfd_malloc (amt);
sections = bfd_malloc2 (bfd_count_sections (abfd), sizeof (asection *));
if (sections == NULL)
goto error_return;
@ -4025,7 +4023,6 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
bfd_vma filehdr_vaddr, filehdr_paddr;
bfd_vma phdrs_vaddr, phdrs_paddr;
Elf_Internal_Phdr *p;
bfd_size_type amt;
if (elf_tdata (abfd)->segment_map == NULL)
{
@ -4100,8 +4097,7 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
if (alloc == 0)
alloc = count;
amt = alloc * sizeof (Elf_Internal_Phdr);
phdrs = bfd_alloc (abfd, amt);
phdrs = bfd_alloc2 (abfd, alloc, sizeof (Elf_Internal_Phdr));
if (phdrs == NULL)
return FALSE;
@ -5361,8 +5357,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
/* Gcc 2.96 miscompiles this code on mips. Don't do casting here
to work around this long long bug. */
amt = section_count * sizeof (asection *);
sections = bfd_malloc (amt);
sections = bfd_malloc2 (section_count, sizeof (asection *));
if (sections == NULL)
return FALSE;
@ -5784,8 +5779,7 @@ swap_out_syms (bfd *abfd,
symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
symstrtab_hdr->sh_type = SHT_STRTAB;
amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym;
outbound_syms = bfd_alloc (abfd, amt);
outbound_syms = bfd_alloc2 (abfd, 1 + symcount, bed->s->sizeof_sym);
if (outbound_syms == NULL)
{
_bfd_stringtab_free (stt);
@ -5798,7 +5792,8 @@ swap_out_syms (bfd *abfd,
if (symtab_shndx_hdr->sh_name != 0)
{
amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
outbound_shndx = bfd_zalloc (abfd, amt);
outbound_shndx = bfd_zalloc2 (abfd, 1 + symcount,
sizeof (Elf_External_Sym_Shndx));
if (outbound_shndx == NULL)
{
_bfd_stringtab_free (stt);
@ -6211,7 +6206,6 @@ bfd_boolean
_bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
{
bfd_byte *contents = NULL;
bfd_size_type amt;
unsigned int freeidx = 0;
if (elf_dynverref (abfd) != 0)
@ -6220,11 +6214,12 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
Elf_External_Verneed *everneed;
Elf_Internal_Verneed *iverneed;
unsigned int i;
bfd_byte *contents_end;
hdr = &elf_tdata (abfd)->dynverref_hdr;
amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed);
elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt);
elf_tdata (abfd)->verref = bfd_zalloc2 (abfd, hdr->sh_info,
sizeof (Elf_Internal_Verneed));
if (elf_tdata (abfd)->verref == NULL)
goto error_return;
@ -6232,11 +6227,22 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
contents = bfd_malloc (hdr->sh_size);
if (contents == NULL)
goto error_return;
{
error_return_verref:
elf_tdata (abfd)->verref = NULL;
elf_tdata (abfd)->cverrefs = 0;
goto error_return;
}
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
goto error_return;
goto error_return_verref;
if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed))
goto error_return_verref;
BFD_ASSERT (sizeof (Elf_External_Verneed)
== sizeof (Elf_External_Vernaux));
contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed);
everneed = (Elf_External_Verneed *) contents;
iverneed = elf_tdata (abfd)->verref;
for (i = 0; i < hdr->sh_info; i++, iverneed++)
@ -6253,11 +6259,21 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
iverneed->vn_file);
if (iverneed->vn_filename == NULL)
goto error_return;
goto error_return_verref;
amt = iverneed->vn_cnt;
amt *= sizeof (Elf_Internal_Vernaux);
iverneed->vn_auxptr = bfd_alloc (abfd, amt);
if (iverneed->vn_cnt == 0)
iverneed->vn_auxptr = NULL;
else
{
iverneed->vn_auxptr = bfd_alloc2 (abfd, iverneed->vn_cnt,
sizeof (Elf_Internal_Vernaux));
if (iverneed->vn_auxptr == NULL)
goto error_return_verref;
}
if (iverneed->vn_aux
> (size_t) (contents_end - (bfd_byte *) everneed))
goto error_return_verref;
evernaux = ((Elf_External_Vernaux *)
((bfd_byte *) everneed + iverneed->vn_aux));
@ -6270,13 +6286,17 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
ivernaux->vna_name);
if (ivernaux->vna_nodename == NULL)
goto error_return;
goto error_return_verref;
if (j + 1 < iverneed->vn_cnt)
ivernaux->vna_nextptr = ivernaux + 1;
else
ivernaux->vna_nextptr = NULL;
if (ivernaux->vna_next
> (size_t) (contents_end - (bfd_byte *) evernaux))
goto error_return_verref;
evernaux = ((Elf_External_Vernaux *)
((bfd_byte *) evernaux + ivernaux->vna_next));
@ -6289,6 +6309,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
else
iverneed->vn_nextref = NULL;
if (iverneed->vn_next
> (size_t) (contents_end - (bfd_byte *) everneed))
goto error_return_verref;
everneed = ((Elf_External_Verneed *)
((bfd_byte *) everneed + iverneed->vn_next));
}
@ -6306,6 +6330,7 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
Elf_Internal_Verdef iverdefmem;
unsigned int i;
unsigned int maxidx;
bfd_byte *contents_end_def, *contents_end_aux;
hdr = &elf_tdata (abfd)->dynverdef_hdr;
@ -6316,6 +6341,16 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
|| bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
goto error_return;
if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef))
goto error_return;
BFD_ASSERT (sizeof (Elf_External_Verdef)
>= sizeof (Elf_External_Verdaux));
contents_end_def = contents + hdr->sh_size
- sizeof (Elf_External_Verdef);
contents_end_aux = contents + hdr->sh_size
- sizeof (Elf_External_Verdaux);
/* We know the number of entries in the section but not the maximum
index. Therefore we have to run through all entries and find
the maximum. */
@ -6328,6 +6363,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
if (iverdefmem.vd_next
> (size_t) (contents_end_def - (bfd_byte *) everdef))
goto error_return;
everdef = ((Elf_External_Verdef *)
((bfd_byte *) everdef + iverdefmem.vd_next));
}
@ -6339,8 +6378,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
else
freeidx = ++maxidx;
}
amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef);
elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt);
elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, maxidx,
sizeof (Elf_Internal_Verdef));
if (elf_tdata (abfd)->verdef == NULL)
goto error_return;
@ -6356,15 +6395,32 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
_bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
{
error_return_verdef:
elf_tdata (abfd)->verdef = NULL;
elf_tdata (abfd)->cverdefs = 0;
goto error_return;
}
iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
iverdef->vd_bfd = abfd;
amt = (bfd_size_type) iverdef->vd_cnt * sizeof (Elf_Internal_Verdaux);
iverdef->vd_auxptr = bfd_alloc (abfd, amt);
if (iverdef->vd_auxptr == NULL)
goto error_return;
if (iverdef->vd_cnt == 0)
iverdef->vd_auxptr = NULL;
else
{
iverdef->vd_auxptr = bfd_alloc2 (abfd, iverdef->vd_cnt,
sizeof (Elf_Internal_Verdaux));
if (iverdef->vd_auxptr == NULL)
goto error_return_verdef;
}
if (iverdef->vd_aux
> (size_t) (contents_end_aux - (bfd_byte *) everdef))
goto error_return_verdef;
everdaux = ((Elf_External_Verdaux *)
((bfd_byte *) everdef + iverdef->vd_aux));
@ -6377,20 +6433,25 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
iverdaux->vda_name);
if (iverdaux->vda_nodename == NULL)
goto error_return;
goto error_return_verdef;
if (j + 1 < iverdef->vd_cnt)
iverdaux->vda_nextptr = iverdaux + 1;
else
iverdaux->vda_nextptr = NULL;
if (iverdaux->vda_next
> (size_t) (contents_end_aux - (bfd_byte *) everdaux))
goto error_return_verdef;
everdaux = ((Elf_External_Verdaux *)
((bfd_byte *) everdaux + iverdaux->vda_next));
}
iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
if (iverdef->vd_cnt)
iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
if (i + 1 < hdr->sh_info)
if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
iverdef->vd_nextdef = iverdef + 1;
else
iverdef->vd_nextdef = NULL;
@ -6409,8 +6470,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
else
freeidx++;
amt = (bfd_size_type) freeidx * sizeof (Elf_Internal_Verdef);
elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt);
elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, freeidx,
sizeof (Elf_Internal_Verdef));
if (elf_tdata (abfd)->verdef == NULL)
goto error_return;
@ -6434,10 +6495,11 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
if (iverdef->vd_nodename == NULL)
goto error_return;
goto error_return_verdef;
iverdef->vd_nextdef = NULL;
amt = (bfd_size_type) sizeof (Elf_Internal_Verdaux);
iverdef->vd_auxptr = bfd_alloc (abfd, amt);
iverdef->vd_auxptr = bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
if (iverdef->vd_auxptr == NULL)
goto error_return_verdef;
iverdaux = iverdef->vd_auxptr;
iverdaux->vda_nodename = iverdef->vd_nodename;

View File

@ -351,7 +351,8 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
arelent *cache_ptr;
Elf_Internal_Rela *dst;
{
switch (ELF32_R_TYPE(dst->r_info))
unsigned int r_type = ELF32_R_TYPE(dst->r_info);
switch (r_type)
{
case R_390_GNU_VTINHERIT:
cache_ptr->howto = &elf32_s390_vtinherit_howto;
@ -362,8 +363,13 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
break;
default:
BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_390_max);
cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)];
if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
{
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
abfd, (int) r_type);
r_type = R_390_NONE;
}
cache_ptr->howto = &elf_howto_table[r_type];
}
}

View File

@ -2117,8 +2117,13 @@ ppc64_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
ppc_howto_init ();
type = ELF64_R_TYPE (dst->r_info);
BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table)
/ sizeof (ppc64_elf_howto_table[0])));
if (type >= (sizeof (ppc64_elf_howto_table)
/ sizeof (ppc64_elf_howto_table[0])))
{
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
abfd, (int) r_type);
r_type = R_PPC64_NONE;
}
cache_ptr->howto = ppc64_elf_howto_table[type];
}

View File

@ -373,7 +373,8 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
arelent *cache_ptr;
Elf_Internal_Rela *dst;
{
switch (ELF64_R_TYPE(dst->r_info))
unsigned int r_type = ELF64_R_TYPE(dst->r_info);
switch (r_type)
{
case R_390_GNU_VTINHERIT:
cache_ptr->howto = &elf64_s390_vtinherit_howto;
@ -384,8 +385,13 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
break;
default:
BFD_ASSERT (ELF64_R_TYPE(dst->r_info) < (unsigned int) R_390_max);
cache_ptr->howto = &elf_howto_table[ELF64_R_TYPE(dst->r_info)];
if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
{
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
abfd, (int) r_type);
r_type = R_390_NONE;
}
cache_ptr->howto = &elf_howto_table[r_type];
}
}

View File

@ -189,16 +189,19 @@ elf64_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
unsigned r_type, i;
r_type = ELF64_R_TYPE (dst->r_info);
if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT)
if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
|| r_type >= (unsigned int) R_X86_64_max)
{
BFD_ASSERT (r_type <= (unsigned int) R_X86_64_GOTPC32);
if (r_type > (unsigned int) R_X86_64_GOTPC32)
{
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
abfd, (int) r_type);
r_type = R_X86_64_NONE;
}
i = r_type;
}
else
{
BFD_ASSERT (r_type < (unsigned int) R_X86_64_max);
i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_GOTPC32 - 1);
}
i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_GOTPC32 - 1);
cache_ptr->howto = &x86_64_elf_howto_table[i];
BFD_ASSERT (r_type == cache_ptr->howto->type);
}

View File

@ -487,7 +487,8 @@ lookup_howto (rtype)
elf_code_to_howto_index[ia64_howto_table[i].type] = i;
}
BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
if (rtype > R_IA64_MAX_RELOC_CODE)
return 0;
i = elf_code_to_howto_index[rtype];
if (i >= NELEMS (ia64_howto_table))
return 0;

View File

@ -397,7 +397,12 @@ _bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type)
return &sparc_rev32_howto;
default:
BFD_ASSERT (r_type < (unsigned int) R_SPARC_max_std);
if (r_type >= (unsigned int) R_SPARC_max_std)
{
(*_bfd_error_handler) (_("invalid relocation type %d"),
(int) r_type);
r_type = R_SPARC_NONE;
}
return &_bfd_sparc_elf_howto_table[r_type];
}
}

View File

@ -93,6 +93,12 @@ extern void *bfd_realloc
(void *, bfd_size_type);
extern void *bfd_zmalloc
(bfd_size_type);
extern void *bfd_malloc2
(bfd_size_type, bfd_size_type);
extern void *bfd_realloc2
(void *, bfd_size_type, bfd_size_type);
extern void *bfd_zmalloc2
(bfd_size_type, bfd_size_type);
extern void _bfd_default_error_handler (const char *s, ...);
extern bfd_error_handler_type _bfd_error_handler;
@ -103,6 +109,10 @@ extern void *bfd_alloc
(bfd *, bfd_size_type);
extern void *bfd_zalloc
(bfd *, bfd_size_type);
extern void *bfd_alloc2
(bfd *, bfd_size_type, bfd_size_type);
extern void *bfd_zalloc2
(bfd *, bfd_size_type, bfd_size_type);
extern void bfd_release
(bfd *, void *);

View File

@ -156,6 +156,36 @@ bfd_malloc (bfd_size_type size)
return ptr;
}
/* Allocate memory using malloc, nmemb * size with overflow checking. */
void *
bfd_malloc2 (bfd_size_type nmemb, bfd_size_type size)
{
void *ptr;
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
size *= nmemb;
if (size != (size_t) size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
ptr = malloc ((size_t) size);
if (ptr == NULL && (size_t) size != 0)
bfd_set_error (bfd_error_no_memory);
return ptr;
}
/* Reallocate memory using realloc. */
void *
@ -180,6 +210,40 @@ bfd_realloc (void *ptr, bfd_size_type size)
return ret;
}
/* Reallocate memory using realloc, nmemb * size with overflow checking. */
void *
bfd_realloc2 (void *ptr, bfd_size_type nmemb, bfd_size_type size)
{
void *ret;
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
size *= nmemb;
if (size != (size_t) size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
if (ptr == NULL)
ret = malloc ((size_t) size);
else
ret = realloc (ptr, (size_t) size);
if (ret == NULL && (size_t) size != 0)
bfd_set_error (bfd_error_no_memory);
return ret;
}
/* Allocate memory using malloc and clear it. */
void *
@ -205,6 +269,44 @@ bfd_zmalloc (bfd_size_type size)
return ptr;
}
/* Allocate memory using malloc (nmemb * size) with overflow checking
and clear it. */
void *
bfd_zmalloc2 (bfd_size_type nmemb, bfd_size_type size)
{
void *ptr;
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
size *= nmemb;
if (size != (size_t) size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
ptr = malloc ((size_t) size);
if ((size_t) size != 0)
{
if (ptr == NULL)
bfd_set_error (bfd_error_no_memory);
else
memset (ptr, 0, (size_t) size);
}
return ptr;
}
/*
INTERNAL_FUNCTION
bfd_write_bigendian_4byte_int

View File

@ -98,6 +98,12 @@ extern void *bfd_realloc
(void *, bfd_size_type);
extern void *bfd_zmalloc
(bfd_size_type);
extern void *bfd_malloc2
(bfd_size_type, bfd_size_type);
extern void *bfd_realloc2
(void *, bfd_size_type, bfd_size_type);
extern void *bfd_zmalloc2
(bfd_size_type, bfd_size_type);
extern void _bfd_default_error_handler (const char *s, ...);
extern bfd_error_handler_type _bfd_error_handler;
@ -108,6 +114,10 @@ extern void *bfd_alloc
(bfd *, bfd_size_type);
extern void *bfd_zalloc
(bfd *, bfd_size_type);
extern void *bfd_alloc2
(bfd *, bfd_size_type, bfd_size_type);
extern void *bfd_zalloc2
(bfd *, bfd_size_type, bfd_size_type);
extern void bfd_release
(bfd *, void *);

View File

@ -856,6 +856,45 @@ bfd_alloc (bfd *abfd, bfd_size_type size)
return ret;
}
/*
INTERNAL_FUNCTION
bfd_alloc2
SYNOPSIS
void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
DESCRIPTION
Allocate a block of @var{nmemb} elements of @var{size} bytes each
of memory attached to <<abfd>> and return a pointer to it.
*/
void *
bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
{
void *ret;
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
size *= nmemb;
if (size != (unsigned long) size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
ret = objalloc_alloc (abfd->memory, (unsigned long) size);
if (ret == NULL)
bfd_set_error (bfd_error_no_memory);
return ret;
}
/*
INTERNAL_FUNCTION
bfd_zalloc
@ -879,6 +918,39 @@ bfd_zalloc (bfd *abfd, bfd_size_type size)
return res;
}
/*
INTERNAL_FUNCTION
bfd_zalloc2
SYNOPSIS
void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
DESCRIPTION
Allocate a block of @var{nmemb} elements of @var{size} bytes each
of zeroed memory attached to <<abfd>> and return a pointer to it.
*/
void *
bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
{
void *res;
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
size *= nmemb;
res = bfd_alloc (abfd, size);
if (res)
memset (res, 0, (size_t) size);
return res;
}
/* Free a block allocated for a BFD.
Note: Also frees all more recently allocated blocks! */