#endif
#define IS_AARCH64_TLS_RELOC(R_TYPE) \
- ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
+ ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
|| IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
#define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
- ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
+ ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
|| (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
- || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC)
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
#define ELIMINATE_COPY_RELOCS 0
0xffc, /* dst_mask */
FALSE), /* pcrel_offset */
+ /* LD64: GOT offset for the symbol. */
+ HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15), /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (LD64_GOTOFF_LO15), /* name */
+ FALSE, /* partial_inplace */
+ 0x7ff8, /* src_mask */
+ 0x7ff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
/* LD32: GOT offset to the page address of GOT table.
(G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc. */
HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14), /* type */
0x1ffffc, /* dst_mask */
FALSE), /* pcrel_offset */
+ HOWTO (AARCH64_R (TLSLD_ADR_PREL21), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSLD_ADR_PREL21), /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2), /* type */
32, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
{
case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
+ case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
return GOT_TLS_GD;
case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
howto, value);
case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
value = aarch64_calculate_got_entry_vma (h, globals, info,
value, output_bfd,
unresolved_reloc_p);
- if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+ if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
+ || bfd_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
addend = (globals->root.sgot->output_section->vma
+ globals->root.sgot->output_offset);
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
value = aarch64_calculate_got_entry_vma (h, globals, info, value,
output_bfd,
unresolved_reloc_p);
- if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+ if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
+ || bfd_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
addend = (globals->root.sgot->output_section->vma
+ globals->root.sgot->output_offset);
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
the direct data access into indirect data access through GOT. */
value = got_entry_addr;
- if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+ if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
+ || bfd_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
addend = base_got->output_section->vma + base_got->output_offset;
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
+ case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
if (globals->root.sgot == NULL)
return bfd_reloc_notsupported;
case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
+ case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
{
bfd_boolean need_relocs = FALSE;
* RELOC_SIZE (htab);
bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
- if (indx == 0)
+ if (elfNN_aarch64_bfd_reloc_from_type (r_type)
+ == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21)
+ {
+ /* For local dynamic, don't generate DTPREL in any case.
+ Initialize the DTPREL slot into zero, so we get module
+ base address when invoke runtime TLS resolver. */
+ bfd_put_NN (output_bfd, 0,
+ globals->root.sgot->contents + off
+ + GOT_ENTRY_SIZE);
+ }
+ else if (indx == 0)
{
bfd_put_NN (output_bfd,
relocation - dtpoff_base (info),
{
case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
+ case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
case BFD_RELOC_AARCH64_CALL26:
case BFD_RELOC_AARCH64_GOT_LD_PREL19:
case BFD_RELOC_AARCH64_JUMP26:
+ case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
there are no dangling GOT_PAGE relocs. */
case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
+ case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf);
}
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+aarch64_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
+{
+ struct elf_aarch64_link_hash_entry * eh;
+ struct elf_dyn_relocs * p;
+
+ eh = (struct elf_aarch64_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
/* This is the most important function of all . Innocuosly named
though ! */
static bfd_boolean
/* If any dynamic relocs apply to a read-only section,
then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (& htab->root, aarch64_readonly_dynrelocs,
+ info);
+
if ((info->flags & DF_TEXTREL) != 0)
{
if (!add_dynamic_entry (DT_TEXTREL, 0))