From 188fd7aea619d9f66a822bad881d8f56892b60aa Mon Sep 17 00:00:00 2001
From: Christophe Lyon <christophe.lyon@st.com>
Date: Tue, 20 Mar 2018 10:54:59 +0100
Subject: [ARM] Add FDPIC relocations definitions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add FDPIC relocation definitions in BFD and gas.
Gas rejects them if the --fdpic option was not specified.

2018-04-25  Christophe Lyon  <christophe.lyon@st.com>
	Mickaël Guêné  <mickael.guene@st.com>

	bfd/
	* bfd-in2.c (BFD_RELOC_ARM_GOTFUNCDESC)
	(BFD_RELOC_ARM_GOTOFFFUNCDESC, BFD_RELOC_ARM_FUNCDESC)
	(BFD_RELOC_ARM_FUNCDESC_VALUE): New.
	* elf32-arm.c (elf32_arm_howto_table_2): Add R_ARM_GOTFUNCDESC,
	R_ARM_GOTOFFFUNCDESC, R_ARM_FUNCDESC, R_ARM_FUNCDESC_VALUE.
	(elf32_arm_howto_from_type): Take new members of
	elf32_arm_howto_table_2 into account.
	(elf32_arm_reloc_map): Add BFD_RELOC_ARM_GOTFUNCDESC,
	BFD_RELOC_ARM_GOTOFFFUNCDESC, BFD_RELOC_ARM_FUNCDESC,
	BFD_RELOC_ARM_FUNCDESC_VALUE.
	* reloc.c: Add BFD_RELOC_ARM_GOTFUNCDESC,
	BFD_RELOC_ARM_GOTOFFFUNCDESC, BFD_RELOC_ARM_FUNCDESC,
	BFD_RELOC_ARM_FUNCDESC_VALUE.

	gas/
	* config/tc-arm.c (reloc_names): Add gotfuncdesc, gotofffuncdesc,
	funcdesc.
	(md_apply_fix): Support the new relocations.
	(tc_gen_reloc): Likewise.
	* testsuite/gas/arm/reloc-fdpic.d: New.
	* testsuite/gas/arm/reloc-fdpic.s: New.

	include/
	* elf/arm.h (R_ARM_GOTFUNCDESC, R_ARM_GOTOFFFUNCDESC)
	(R_ARM_FUNCDESC)
	(R_ARM_FUNCDESC_VALUE): Define new relocations.
---
 bfd/ChangeLog   | 17 ++++++++++++++++
 bfd/bfd-in2.h   |  6 ++++++
 bfd/elf32-arm.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 bfd/reloc.c     | 11 ++++++++++
 4 files changed, 94 insertions(+), 3 deletions(-)

(limited to 'bfd')

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index dd28d04..9b50933 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,6 +1,23 @@
 2018-04-25  Christophe Lyon  <christophe.lyon@st.com>
 	Mickaël Guêné  <mickael.guene@st.com>
 
+	* bfd-in2.c (BFD_RELOC_ARM_GOTFUNCDESC)
+	(BFD_RELOC_ARM_GOTOFFFUNCDESC, BFD_RELOC_ARM_FUNCDESC)
+	(BFD_RELOC_ARM_FUNCDESC_VALUE): New.
+	* elf32-arm.c (elf32_arm_howto_table_2): Add R_ARM_GOTFUNCDESC,
+	R_ARM_GOTOFFFUNCDESC, R_ARM_FUNCDESC, R_ARM_FUNCDESC_VALUE.
+	(elf32_arm_howto_from_type): Take new members of
+	elf32_arm_howto_table_2 into account.
+	(elf32_arm_reloc_map): Add BFD_RELOC_ARM_GOTFUNCDESC,
+	BFD_RELOC_ARM_GOTOFFFUNCDESC, BFD_RELOC_ARM_FUNCDESC,
+	BFD_RELOC_ARM_FUNCDESC_VALUE.
+	* reloc.c: Add BFD_RELOC_ARM_GOTFUNCDESC,
+	BFD_RELOC_ARM_GOTOFFFUNCDESC, BFD_RELOC_ARM_FUNCDESC,
+	BFD_RELOC_ARM_FUNCDESC_VALUE.
+
+2018-04-25  Christophe Lyon  <christophe.lyon@st.com>
+	Mickaël Guêné  <mickael.guene@st.com>
+
 	* elf32-arm.c (elf32_arm_print_private_bfd_data): Support
 	EF_ARM_PIC and ELFOSABI_ARM_FDPIC.
 	(elf32_arm_post_process_headers): Support ELFOSABI_ARM_FDPIC.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 97c37a0..f58c2f7 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -3526,6 +3526,12 @@ pc-relative or some form of GOT-indirect relocation.  */
   BFD_RELOC_ARM_THUMB_MOVW_PCREL,
   BFD_RELOC_ARM_THUMB_MOVT_PCREL,
 
+/* ARM FDPIC specific relocations. */
+  BFD_RELOC_ARM_GOTFUNCDESC,
+  BFD_RELOC_ARM_GOTOFFFUNCDESC,
+  BFD_RELOC_ARM_FUNCDESC,
+  BFD_RELOC_ARM_FUNCDESC_VALUE,
+
 /* Relocations for setting up GOTs and PLTs for shared libraries.  */
   BFD_RELOC_ARM_JUMP_SLOT,
   BFD_RELOC_ARM_GLOB_DAT,
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index a0b0be3..3805f71 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[1] =
+static reloc_howto_type elf32_arm_howto_table_2[5] =
 {
   HOWTO (R_ARM_IRELATIVE,	/* type */
 	 0,			/* rightshift */
@@ -1760,7 +1760,59 @@ static reloc_howto_type elf32_arm_howto_table_2[1] =
 	 TRUE,			/* partial_inplace */
 	 0xffffffff,		/* src_mask */
 	 0xffffffff,		/* dst_mask */
-	 FALSE)			/* pcrel_offset */
+	 FALSE),		/* pcrel_offset */
+  HOWTO (R_ARM_GOTFUNCDESC,	/* 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_GOTFUNCDESC",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+  HOWTO (R_ARM_GOTOFFFUNCDESC, /* 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_GOTOFFFUNCDESC",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+  HOWTO (R_ARM_FUNCDESC,	/* 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_FUNCDESC",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+  HOWTO (R_ARM_FUNCDESC_VALUE,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 64,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_ARM_FUNCDESC_VALUE",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
 };
 
 /* 249-255 extended, currently unused, relocations:  */
@@ -1829,7 +1881,8 @@ elf32_arm_howto_from_type (unsigned int r_type)
   if (r_type < ARRAY_SIZE (elf32_arm_howto_table_1))
     return &elf32_arm_howto_table_1[r_type];
 
-  if (r_type == R_ARM_IRELATIVE)
+  if (r_type >= R_ARM_IRELATIVE
+      && r_type < R_ARM_IRELATIVE + ARRAY_SIZE (elf32_arm_howto_table_2))
     return &elf32_arm_howto_table_2[r_type - R_ARM_IRELATIVE];
 
   if (r_type >= R_ARM_RREL32
@@ -1913,6 +1966,10 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
     {BFD_RELOC_ARM_TLS_IE32,	     R_ARM_TLS_IE32},
     {BFD_RELOC_ARM_TLS_LE32,	     R_ARM_TLS_LE32},
     {BFD_RELOC_ARM_IRELATIVE,	     R_ARM_IRELATIVE},
+    {BFD_RELOC_ARM_GOTFUNCDESC,      R_ARM_GOTFUNCDESC},
+    {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_VTABLE_INHERIT,	     R_ARM_GNU_VTINHERIT},
     {BFD_RELOC_VTABLE_ENTRY,	     R_ARM_GNU_VTENTRY},
     {BFD_RELOC_ARM_MOVW,	     R_ARM_MOVW_ABS_NC},
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 80db0c9..e78e582 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -3208,6 +3208,17 @@ ENUMDOC
   Low and High halfword relocations for MOVW and MOVT instructions.
 
 ENUM
+  BFD_RELOC_ARM_GOTFUNCDESC
+ENUMX
+  BFD_RELOC_ARM_GOTOFFFUNCDESC
+ENUMX
+  BFD_RELOC_ARM_FUNCDESC
+ENUMX
+  BFD_RELOC_ARM_FUNCDESC_VALUE
+ENUMDOC
+  ARM FDPIC specific relocations.
+
+ENUM
   BFD_RELOC_ARM_JUMP_SLOT
 ENUMX
   BFD_RELOC_ARM_GLOB_DAT
-- 
cgit v1.1