aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog19
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/elf32-arm.c79
-rw-r--r--bfd/reloc.c6
4 files changed, 95 insertions, 12 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 11c4297..3e5415e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,6 +1,25 @@
2018-04-25 Christophe Lyon <christophe.lyon@st.com>
Mickaël Guêné <mickael.guene@st.com>
+ * bfd-in2.h (BFD_RELOC_ARM_TLS_GD32_FDPIC)
+ (BFD_RELOC_ARM_TLS_LDM32_FDPIC, BFD_RELOC_ARM_TLS_IE32_FDPIC): New
+ relocations.
+ * elf32-arm.c (elf32_arm_howto_table_2): Add R_ARM_TLS_GD32_FDPIC,
+ R_ARM_TLS_LDM32_FDPIC, R_ARM_TLS_IE32_FDPIC relocations.
+ (elf32_arm_reloc_map): Add R_ARM_TLS_GD32_FDPIC,
+ R_ARM_TLS_LDM32_FDPIC, R_ARM_TLS_IE32_FDPIC.
+ (struct elf32_arm_link_hash_table): Update comment.
+ (elf32_arm_final_link_relocate): Handle TLS FDPIC relocations.
+ (IS_ARM_TLS_RELOC): Likewise.
+ (elf32_arm_check_relocs): Likewise.
+ (allocate_dynrelocs_for_symbol): Likewise.
+ (elf32_arm_size_dynamic_sections): Update comment.
+ * reloc.c: Add BFD_RELOC_ARM_TLS_GD32_FDPIC,
+ BFD_RELOC_ARM_TLS_LDM32_FDPIC, BFD_RELOC_ARM_TLS_IE32_FDPIC.
+
+2018-04-25 Christophe Lyon <christophe.lyon@st.com>
+ Mickaël Guêné <mickael.guene@st.com>
+
* elf32-arm.c (elf32_arm_fdpic_plt_entry): New.
(elf32_arm_create_dynamic_sections): Handle FDPIC.
(elf32_arm_allocate_plt_entry): Likewise.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index f58c2f7..927dc9d 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -3531,6 +3531,9 @@ pc-relative or some form of GOT-indirect relocation. */
BFD_RELOC_ARM_GOTOFFFUNCDESC,
BFD_RELOC_ARM_FUNCDESC,
BFD_RELOC_ARM_FUNCDESC_VALUE,
+ BFD_RELOC_ARM_TLS_GD32_FDPIC,
+ BFD_RELOC_ARM_TLS_LDM32_FDPIC,
+ BFD_RELOC_ARM_TLS_IE32_FDPIC,
/* Relocations for setting up GOTs and PLTs for shared libraries. */
BFD_RELOC_ARM_JUMP_SLOT,
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 9eb12e2..fb29c0c 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -1746,7 +1746,7 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
};
/* 160 onwards: */
-static reloc_howto_type elf32_arm_howto_table_2[5] =
+static reloc_howto_type elf32_arm_howto_table_2[8] =
{
HOWTO (R_ARM_IRELATIVE, /* type */
0, /* rightshift */
@@ -1813,6 +1813,45 @@ static reloc_howto_type elf32_arm_howto_table_2[5] =
0, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
+ HOWTO (R_ARM_TLS_GD32_FDPIC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TLS_GD32_FDPIC",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_ARM_TLS_LDM32_FDPIC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TLS_LDM32_FDPIC",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_ARM_TLS_IE32_FDPIC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TLS_IE32_FDPIC",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
};
/* 249-255 extended, currently unused, relocations: */
@@ -1970,6 +2009,9 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
{BFD_RELOC_ARM_GOTOFFFUNCDESC, R_ARM_GOTOFFFUNCDESC},
{BFD_RELOC_ARM_FUNCDESC, R_ARM_FUNCDESC},
{BFD_RELOC_ARM_FUNCDESC_VALUE, R_ARM_FUNCDESC_VALUE},
+ {BFD_RELOC_ARM_TLS_GD32_FDPIC, R_ARM_TLS_GD32_FDPIC},
+ {BFD_RELOC_ARM_TLS_LDM32_FDPIC, R_ARM_TLS_LDM32_FDPIC},
+ {BFD_RELOC_ARM_TLS_IE32_FDPIC, R_ARM_TLS_IE32_FDPIC},
{BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT},
{BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY},
{BFD_RELOC_ARM_MOVW, R_ARM_MOVW_ABS_NC},
@@ -3280,7 +3322,7 @@ struct elf32_arm_link_hash_table
/* Offset in .plt section of tls_arm_trampoline. */
bfd_vma tls_trampoline;
- /* Data for R_ARM_TLS_LDM32 relocations. */
+ /* Data for R_ARM_TLS_LDM32/R_ARM_TLS_LDM32_FDPIC relocations. */
union
{
bfd_signed_vma refcount;
@@ -11523,6 +11565,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
rel->r_addend);
case R_ARM_TLS_LDM32:
+ case R_ARM_TLS_LDM32_FDPIC:
{
bfd_vma off;
@@ -11561,7 +11604,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
globals->tls_ldm_got.offset |= 1;
}
- if (globals->fdpic_p)
+ if (r_type == R_ARM_TLS_LDM32_FDPIC)
{
bfd_put_32(output_bfd,
globals->root.sgot->output_offset + off,
@@ -11584,7 +11627,9 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
case R_ARM_TLS_CALL:
case R_ARM_THM_TLS_CALL:
case R_ARM_TLS_GD32:
+ case R_ARM_TLS_GD32_FDPIC:
case R_ARM_TLS_IE32:
+ case R_ARM_TLS_IE32_FDPIC:
case R_ARM_TLS_GOTDESC:
case R_ARM_TLS_DESCSEQ:
case R_ARM_THM_TLS_DESCSEQ:
@@ -11772,7 +11817,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
local_got_offsets[r_symndx] |= 1;
}
- if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32)
+ if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32 && r_type != R_ARM_TLS_GD32_FDPIC)
off += 8;
else if (tls_type & GOT_TLS_GDESC)
off = offplt;
@@ -11931,8 +11976,8 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
- (input_section->output_section->vma
+ input_section->output_offset + rel->r_offset));
- if (globals->fdpic_p && (r_type == R_ARM_TLS_GD32 ||
- r_type == R_ARM_TLS_IE32))
+ if (globals->fdpic_p && (r_type == R_ARM_TLS_GD32_FDPIC ||
+ r_type == R_ARM_TLS_IE32_FDPIC))
{
/* For FDPIC relocations, resolve to the offset of the GOT
entry from the start of GOT. */
@@ -12845,13 +12890,16 @@ arm_add_to_rel (bfd * abfd,
#define IS_ARM_TLS_RELOC(R_TYPE) \
((R_TYPE) == R_ARM_TLS_GD32 \
+ || (R_TYPE) == R_ARM_TLS_GD32_FDPIC \
|| (R_TYPE) == R_ARM_TLS_LDO32 \
|| (R_TYPE) == R_ARM_TLS_LDM32 \
+ || (R_TYPE) == R_ARM_TLS_LDM32_FDPIC \
|| (R_TYPE) == R_ARM_TLS_DTPOFF32 \
|| (R_TYPE) == R_ARM_TLS_DTPMOD32 \
|| (R_TYPE) == R_ARM_TLS_TPOFF32 \
|| (R_TYPE) == R_ARM_TLS_LE32 \
|| (R_TYPE) == R_ARM_TLS_IE32 \
+ || (R_TYPE) == R_ARM_TLS_IE32_FDPIC \
|| IS_ARM_TLS_GNU_RELOC (R_TYPE))
/* Specific set of relocations for the gnu tls dialect. */
@@ -15077,7 +15125,9 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_ARM_GOT32:
case R_ARM_GOT_PREL:
case R_ARM_TLS_GD32:
+ case R_ARM_TLS_GD32_FDPIC:
case R_ARM_TLS_IE32:
+ case R_ARM_TLS_IE32_FDPIC:
case R_ARM_TLS_GOTDESC:
case R_ARM_TLS_DESCSEQ:
case R_ARM_THM_TLS_DESCSEQ:
@@ -15090,8 +15140,10 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
switch (r_type)
{
case R_ARM_TLS_GD32: tls_type = GOT_TLS_GD; break;
+ case R_ARM_TLS_GD32_FDPIC: tls_type = GOT_TLS_GD; break;
case R_ARM_TLS_IE32: tls_type = GOT_TLS_IE; break;
+ case R_ARM_TLS_IE32_FDPIC: tls_type = GOT_TLS_IE; break;
case R_ARM_TLS_GOTDESC:
case R_ARM_TLS_CALL: case R_ARM_THM_TLS_CALL:
@@ -15149,7 +15201,8 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
/* Fall through. */
case R_ARM_TLS_LDM32:
- if (r_type == R_ARM_TLS_LDM32)
+ case R_ARM_TLS_LDM32_FDPIC:
+ if (r_type == R_ARM_TLS_LDM32 || r_type == R_ARM_TLS_LDM32_FDPIC)
htab->tls_ldm_got.refcount++;
/* Fall through. */
@@ -16078,15 +16131,17 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
if (tls_type & GOT_TLS_GD)
{
- /* R_ARM_TLS_GD32 needs 2 consecutive GOT slots. If
- the symbol is both GD and GDESC, got.offset may
- have been overwritten. */
+ /* R_ARM_TLS_GD32 and R_ARM_TLS_GD32_FDPIC need two
+ consecutive GOT slots. If the symbol is both GD
+ and GDESC, got.offset may have been
+ overwritten. */
h->got.offset = s->size;
s->size += 8;
}
if (tls_type & GOT_TLS_IE)
- /* R_ARM_TLS_IE32 needs one GOT slot. */
+ /* R_ARM_TLS_IE32/R_ARM_TLS_IE32_FDPIC need one GOT
+ slot. */
s->size += 4;
}
@@ -16689,7 +16744,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
if (htab->tls_ldm_got.refcount > 0)
{
/* Allocate two GOT entries and one dynamic relocation (if necessary)
- for R_ARM_TLS_LDM32 relocations. */
+ for R_ARM_TLS_LDM32/R_ARM_TLS_LDM32_FDPIC relocations. */
htab->tls_ldm_got.offset = htab->root.sgot->size;
htab->root.sgot->size += 8;
if (bfd_link_pic (info))
diff --git a/bfd/reloc.c b/bfd/reloc.c
index e78e582..f7e34a9 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -3215,6 +3215,12 @@ ENUMX
BFD_RELOC_ARM_FUNCDESC
ENUMX
BFD_RELOC_ARM_FUNCDESC_VALUE
+ENUMX
+ BFD_RELOC_ARM_TLS_GD32_FDPIC
+ENUMX
+ BFD_RELOC_ARM_TLS_LDM32_FDPIC
+ENUMX
+ BFD_RELOC_ARM_TLS_IE32_FDPIC
ENUMDOC
ARM FDPIC specific relocations.