or (bfd_vma) -1 if size can not be determined. */
static bfd_vma
-elf32_arm_plt0_size (const bfd *abfd, const bfd_byte *addr)
+elf32_arm_plt0_size (const bfd *abfd, const bfd_byte *addr,
+ bfd_size_type data_size)
{
bfd_vma first_word;
bfd_vma plt0_size;
+ if (data_size < 4)
+ return (bfd_vma) -1;
+
first_word = read_code32 (abfd, addr);
if (first_word == elf32_arm_plt0_entry[0])
or (bfd_vma) -1 if size can not be determined. */
static bfd_vma
-elf32_arm_plt_size (const bfd *abfd, const bfd_byte *start, bfd_vma offset)
+elf32_arm_plt_size (const bfd *abfd, const bfd_byte *start, bfd_vma offset,
+ bfd_size_type data_size)
{
bfd_vma first_insn;
bfd_vma plt_size = 0;
- const bfd_byte *addr = start + offset;
/* PLT entry size if fixed on Thumb-only platforms. */
if (read_code32 (abfd, start) == elf32_thumb2_plt0_entry[0])
- return 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
+ return 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
/* Respect Thumb stub if necessary. */
- if (read_code16 (abfd, addr) == elf32_arm_plt_thumb_stub[0])
+ if (offset + 2 > data_size)
+ return (bfd_vma) -1;
+ if (read_code16 (abfd, start + offset) == elf32_arm_plt_thumb_stub[0])
{
plt_size += 2 * ARRAY_SIZE (elf32_arm_plt_thumb_stub);
}
/* Strip immediate from first add. */
- first_insn = read_code32 (abfd, addr + plt_size) & 0xffffff00;
+ if (offset + plt_size + 4 > data_size)
+ return (bfd_vma) -1;
+ first_insn = read_code32 (abfd, start + offset + plt_size) & 0xffffff00;
#ifdef FOUR_WORD_PLT
if (first_insn == elf32_arm_plt_entry[0])
size += sizeof ("+0x") - 1 + 8;
}
- offset = elf32_arm_plt0_size (abfd, data);
+ offset = elf32_arm_plt0_size (abfd, data, plt->size);
if (offset == (bfd_vma) -1
|| (s = *ret = (asymbol *) bfd_malloc (size)) == NULL)
{
{
size_t len;
- bfd_vma plt_size = elf32_arm_plt_size (abfd, data, offset);
+ bfd_vma plt_size = elf32_arm_plt_size (abfd, data, offset, plt->size);
if (plt_size == (bfd_vma) -1)
break;