static int
tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
- int newtag, int secondary_compat)
+ int newtag, int secondary_compat, const char* name_table[])
{
#define T(X) TAG_CPU_ARCH_##X
int tagl, tagh, result;
if (result == -1)
{
- _bfd_error_handler (_("error: %pB: conflicting CPU architectures %d/%d"),
- ibfd, oldtag, newtag);
+ _bfd_error_handler (_("error: conflicting CPU architectures %s vs %s in %pB"),
+ name_table[oldtag], name_table[newtag], ibfd);
return -1;
}
arch_attr = tag_cpu_arch_combine (ibfd, out_attr[i].i,
&secondary_compat_out,
in_attr[i].i,
- secondary_compat);
+ secondary_compat,
+ name_table);
/* Return with error if failed to merge. */
if (arch_attr == -1)
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])
if (!elf32_arm_size_info.slurp_reloc_table (abfd, relplt, dynsyms, true))
return -1;
- data = plt->contents;
- if (data == NULL)
- {
- if (!bfd_get_full_section_contents (abfd, plt, &data)
- || data == NULL)
- return -1;
- plt->contents = data;
- plt->flags |= SEC_IN_MEMORY;
- }
+ data = NULL;
+ if (!bfd_get_full_section_contents (abfd, plt, &data))
+ return -1;
count = NUM_SHDR_ENTRIES (hdr);
size = count * sizeof (asymbol);
size += sizeof ("+0x") - 1 + 8;
}
- s = *ret = (asymbol *) bfd_malloc (size);
- if (s == NULL)
- return -1;
-
- offset = elf32_arm_plt0_size (abfd, data);
- if (offset == (bfd_vma) -1)
- return -1;
+ offset = elf32_arm_plt0_size (abfd, data, plt->size);
+ if (offset == (bfd_vma) -1
+ || (s = *ret = (asymbol *) bfd_malloc (size)) == NULL)
+ {
+ free (data);
+ return -1;
+ }
names = (char *) (s + count);
p = relplt->relocation;
{
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;
offset += plt_size;
}
+ free (data);
return n;
}