case NT_PRPSINFO:
{
- char data[124];
+ char data[124] ATTRIBUTE_NONSTRING;
va_list ap;
va_start (ap, note_type);
memset (data, 0, sizeof (data));
strncpy (data + 28, va_arg (ap, const char *), 16);
+#if GCC_VERSION == 8001
+ DIAGNOSTIC_PUSH;
+ /* GCC 8.1 warns about 80 equals destination size with
+ -Wstringop-truncation:
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85643
+ */
+ DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION;
+#endif
strncpy (data + 44, va_arg (ap, const char *), 80);
+#if GCC_VERSION == 8001
+ DIAGNOSTIC_POP;
+#endif
va_end (ap);
return elfcore_write_note (abfd, buf, bufsiz,
0xe599f000, /* ldr pc, [r9] */
};
+/* Thumb FDPIC PLT entry. */
+/* The last 5 words contain PLT lazy fragment code and data. */
+static const bfd_vma elf32_arm_fdpic_thumb_plt_entry [] =
+ {
+ 0xc00cf8df, /* ldr.w r12, .L1 */
+ 0x0c09eb0c, /* add.w r12, r12, r9 */
+ 0x9004f8dc, /* ldr.w r9, [r12, #4] */
+ 0xf000f8dc, /* ldr.w pc, [r12] */
+ 0x00000000, /* .L1 .word foo(GOTOFFFUNCDESC) */
+ 0x00000000, /* .L2 .word foo(funcdesc_value_reloc_offset) */
+ 0xc008f85f, /* ldr.w r12, .L2 */
+ 0xcd04f84d, /* push {r12} */
+ 0xc004f8d9, /* ldr.w r12, [r9, #4] */
+ 0xf000f8d9, /* ldr.w pc, [r9] */
+ };
+
#ifdef FOUR_WORD_PLT
/* The first entry in a procedure linkage table looks like
return TRUE;
}
+static bfd_boolean using_thumb_only (struct elf32_arm_link_hash_table *globals);
+
/* Return true if the PLT described by ARM_PLT requires a Thumb stub
before it. */
struct elf32_arm_link_hash_table *htab;
htab = elf32_arm_hash_table (info);
- return (arm_plt->thumb_refcount != 0
- || (!htab->use_blx && arm_plt->maybe_thumb_refcount != 0));
+
+ return (!using_thumb_only(htab) && (arm_plt->thumb_refcount != 0
+ || (!htab->use_blx && arm_plt->maybe_thumb_refcount != 0)));
}
/* Return a pointer to the head of the dynamic reloc list that should
return;
globals->target1_is_rel = params->target1_is_rel;
- if (strcmp (params->target2_type, "rel") == 0)
+ if (globals->fdpic_p)
+ globals->target2_reloc = R_ARM_GOT32;
+ else if (strcmp (params->target2_type, "rel") == 0)
globals->target2_reloc = R_ARM_REL32;
else if (strcmp (params->target2_type, "abs") == 0)
globals->target2_reloc = R_ARM_ABS32;
}
else if (htab->fdpic_p)
{
+ const bfd_vma *plt_entry = using_thumb_only(htab)
+ ? elf32_arm_fdpic_thumb_plt_entry
+ : elf32_arm_fdpic_plt_entry;
+
/* Fill-up Thumb stub if needed. */
if (elf32_arm_plt_needs_thumb_stub_p (info, arm_plt))
{
put_thumb_insn (htab, output_bfd,
elf32_arm_plt_thumb_stub[1], ptr - 2);
}
- put_arm_insn(htab, output_bfd,
- elf32_arm_fdpic_plt_entry[0], ptr + 0);
- put_arm_insn(htab, output_bfd,
- elf32_arm_fdpic_plt_entry[1], ptr + 4);
- put_arm_insn(htab, output_bfd,
- elf32_arm_fdpic_plt_entry[2], ptr + 8);
- put_arm_insn(htab, output_bfd,
- elf32_arm_fdpic_plt_entry[3], ptr + 12);
+ /* As we are using 32 bit instructions even for the Thumb
+ version, we have to use 'put_arm_insn' instead of
+ 'put_thumb_insn'. */
+ put_arm_insn(htab, output_bfd, plt_entry[0], ptr + 0);
+ put_arm_insn(htab, output_bfd, plt_entry[1], ptr + 4);
+ put_arm_insn(htab, output_bfd, plt_entry[2], ptr + 8);
+ put_arm_insn(htab, output_bfd, plt_entry[3], ptr + 12);
bfd_put_32 (output_bfd, got_offset, ptr + 16);
if (!(info->flags & DF_BIND_NOW))
bfd_put_32 (output_bfd,
htab->root.srelplt->reloc_count * RELOC_SIZE (htab),
ptr + 20);
- put_arm_insn(htab, output_bfd,
- elf32_arm_fdpic_plt_entry[6], ptr + 24);
- put_arm_insn(htab, output_bfd,
- elf32_arm_fdpic_plt_entry[7], ptr + 28);
- put_arm_insn(htab, output_bfd,
- elf32_arm_fdpic_plt_entry[8], ptr + 32);
- put_arm_insn(htab, output_bfd,
- elf32_arm_fdpic_plt_entry[9], ptr + 36);
+ put_arm_insn(htab, output_bfd, plt_entry[6], ptr + 24);
+ put_arm_insn(htab, output_bfd, plt_entry[7], ptr + 28);
+ put_arm_insn(htab, output_bfd, plt_entry[8], ptr + 32);
+ put_arm_insn(htab, output_bfd, plt_entry[9], ptr + 36);
}
}
else if (using_thumb_only (htab))
switch (arch)
{
+ case TAG_CPU_ARCH_PRE_V4: return bfd_mach_arm_3M;
case TAG_CPU_ARCH_V4: return bfd_mach_arm_4;
case TAG_CPU_ARCH_V4T: return bfd_mach_arm_4T;
case TAG_CPU_ARCH_V5T: return bfd_mach_arm_5T;
return bfd_mach_arm_5TE;
}
+ case TAG_CPU_ARCH_V5TEJ:
+ return bfd_mach_arm_5TEJ;
+ case TAG_CPU_ARCH_V6:
+ return bfd_mach_arm_6;
+ case TAG_CPU_ARCH_V6KZ:
+ return bfd_mach_arm_6KZ;
+ case TAG_CPU_ARCH_V6T2:
+ return bfd_mach_arm_6T2;
+ case TAG_CPU_ARCH_V6K:
+ return bfd_mach_arm_6K;
+ case TAG_CPU_ARCH_V7:
+ return bfd_mach_arm_7;
+ case TAG_CPU_ARCH_V6_M:
+ return bfd_mach_arm_6M;
+ case TAG_CPU_ARCH_V6S_M:
+ return bfd_mach_arm_6SM;
+ case TAG_CPU_ARCH_V7E_M:
+ return bfd_mach_arm_7EM;
+ case TAG_CPU_ARCH_V8:
+ return bfd_mach_arm_8;
+ case TAG_CPU_ARCH_V8R:
+ return bfd_mach_arm_8R;
+ case TAG_CPU_ARCH_V8M_BASE:
+ return bfd_mach_arm_8M_BASE;
+ case TAG_CPU_ARCH_V8M_MAIN:
+ return bfd_mach_arm_8M_MAIN;
+
default:
+ /* Force entry to be added for any new known Tag_CPU_arch value. */
+ BFD_ASSERT (arch > MAX_TAG_CPU_ARCH);
+
+ /* Unknown Tag_CPU_arch value. */
return bfd_mach_arm_unknown;
}
}
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. On VxWorks,
- the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it is relative
- to the ".got" section. */
+ and for FDPIC, the _GLOBAL_OFFSET_TABLE_ symbol is not absolute:
+ it is relative to the ".got" section. */
if (h == htab->root.hdynamic
- || (!htab->vxworks_p && h == htab->root.hgot))
+ || (!htab->fdpic_p && !htab->vxworks_p && h == htab->root.hgot))
sym->st_shndx = SHN_ABS;
return TRUE;
}
else if (htab->fdpic_p)
{
+ enum map_symbol_type type = using_thumb_only(htab)
+ ? ARM_MAP_THUMB
+ : ARM_MAP_ARM;
+
if (elf32_arm_plt_needs_thumb_stub_p (osi->info, arm_plt))
if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4))
return FALSE;
- if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+ if (!elf32_arm_output_map_sym (osi, type, addr))
return FALSE;
if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16))
return FALSE;
if (htab->plt_entry_size == 4 * ARRAY_SIZE(elf32_arm_fdpic_plt_entry))
- if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 24))
+ if (!elf32_arm_output_map_sym (osi, type, addr + 24))
return FALSE;
}
else if (using_thumb_only (htab))
if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
return FALSE;
}
- else if (using_thumb_only (htab))
+ else if (using_thumb_only (htab) && !htab->fdpic_p)
{
if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 0))
return FALSE;
Elf_Internal_Sym *sym, const char **namep,
flagword *flagsp, asection **secp, bfd_vma *valp)
{
- if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
- && (abfd->flags & DYNAMIC) == 0
- && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
- elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
-
if (elf32_arm_hash_table (info) == NULL)
return FALSE;