[ARM-FDPIC,01/12,ARM] Add armelf_linux_fdpiceabi and armelfb_linux_fdpiceabi BFD backends

Message ID 20180322143850.1766-2-christophe.lyon@st.com
State New
Headers show
Series
  • FDPIC ABI for ARM
Related show

Commit Message

Christophe Lyon March 22, 2018, 2:38 p.m.
Initial definition of these new backends.

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

	bfd/
	* config.bfd (arm*b-*-linux-*): Add arm_elf32_fdpic_be_vec and
	arm_elf32_fdpic_le_vec to targ_selvecs.
	(arm*-*-linux-*): Likewise.
	* configure.ac: Add support for arm_elf32_fdpic_be_vec and
	arm_elf32_fdpic_le_vec.
	* configure: Regenerate.
	* elf32-arm.c (struct elf32_arm_link_hash_table): Add fdpic_p.
	(elf32_arm_link_hash_table_create): Initialize fdpic_p.
	(TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, TARGET_BIG_SYM)
	(TARGET_BIG_NAME, elf_match_priority): Define for FDPIC targets.
	(elf32_arm_fdpic_link_hash_table_create): New.
	* targets.c (_bfd_target_vector): Add arm_elf32_fdpic_be_vec and
	arm_elf32_fdpic_le_vec.

	ld/
	* Makefile.am (ALL_EMULATION_SOURCES): Add
	earmelf_linux_fdpiceabi.c and earmelfb_linux_fdpiceabi.c.
	(earmelf_linux_fdpiceabi.c, earmelfb_linux_fdpiceabi.c): New rules.
	* Makefile.in: Regenerate.
	* configure.tgt (arm*b-*-linux-*eabi*): Add armelf_linux_fdpiceabi
	and armelfb_linux_fdpiceabi.
	(arm*-*-linux-*eabi*): Likewise.
	* emulparams/armelf_linux_fdpiceabi.sh: New.
	* emulparams/armelfb_linux_fdpiceabi.sh: New.
---
 bfd/config.bfd                           |  4 +--
 bfd/configure                            |  2 ++
 bfd/configure.ac                         |  2 ++
 bfd/elf32-arm.c                          | 44 ++++++++++++++++++++++++++++++++
 bfd/targets.c                            |  4 +++
 ld/Makefile.am                           | 13 ++++++++++
 ld/Makefile.in                           | 15 +++++++++++
 ld/configure.tgt                         |  4 +--
 ld/emulparams/armelf_linux_fdpiceabi.sh  | 13 ++++++++++
 ld/emulparams/armelfb_linux_fdpiceabi.sh |  2 ++
 10 files changed, 99 insertions(+), 4 deletions(-)
 create mode 100644 ld/emulparams/armelf_linux_fdpiceabi.sh
 create mode 100644 ld/emulparams/armelfb_linux_fdpiceabi.sh

-- 
2.6.3

Comments

Christophe Lyon April 19, 2018, 7 a.m. | #1
On 22/03/2018 15:38, Christophe Lyon wrote:
> Initial definition of these new backends.


Hi,
Here is updated version, which uses a new target name as suggested by Joseph: arm-uclinuxfdpiceabi.
The changes in this patch are in bfd/config.bfd and ld/configure.tgt, to account for the new target name.

I'll post a separate patch with the (numerous) testsuite changes such that as many tests pass as with the previous target name.

Is this version OK?

Thanks,

Christophe
commit 44d7362117202b2325a0a1ad3b67455c83e42148
Author: Christophe Lyon <christophe.lyon@st.com>
Date:   Tue Mar 20 10:54:26 2018 +0100

    [ARM] Add armelf_linux_fdpiceabi and armelfb_linux_fdpiceabi BFD backends
    
    Initial definition of these new backends.
    
    2018-XX-XX  Christophe Lyon  <christophe.lyon@st.com>
    	Mickaël Guêné  <mickael.guene@st.com>
    
    	bfd/
    	* config.bfd (arm*-*-linux-*): Add arm_elf32_fdpic_be_vec and
    	arm_elf32_fdpic_le_vec to targ_selvecs. Accept
    	arm*-*-uclinuxfdpiceabi.
    	* configure.ac: Add support for arm_elf32_fdpic_be_vec and
    	arm_elf32_fdpic_le_vec.
    	* configure: Regenerate.
    	* elf32-arm.c (struct elf32_arm_link_hash_table): Add fdpic_p.
    	(elf32_arm_link_hash_table_create): Initialize fdpic_p.
    	(TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, TARGET_BIG_SYM)
    	(TARGET_BIG_NAME, elf_match_priority): Define for FDPIC targets.
    	(elf32_arm_fdpic_link_hash_table_create): New.
    	* targets.c (_bfd_target_vector): Add arm_elf32_fdpic_be_vec and
    	arm_elf32_fdpic_le_vec.
    
    	ld/
    	* Makefile.am (ALL_EMULATION_SOURCES): Add
    	earmelf_linux_fdpiceabi.c and earmelfb_linux_fdpiceabi.c.
    	(earmelf_linux_fdpiceabi.c, earmelfb_linux_fdpiceabi.c): New rules.
    	* Makefile.in: Regenerate.
    	* configure.tgt (arm*-*-uclinuxfdpiceabi): Handle new target.
    	* emulparams/armelf_linux_fdpiceabi.sh: New.
    	* emulparams/armelfb_linux_fdpiceabi.sh: New.

diff --git a/bfd/config.bfd b/bfd/config.bfd
index f04a993..c1b49d7 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -444,9 +444,9 @@ case "${targ}" in
     ;;
   arm-*-elf | arm*-*-freebsd* | arm*-*-linux-* | arm*-*-conix* | \
   arm*-*-uclinux* | arm-*-kfreebsd*-gnu | \
-  arm*-*-eabi* | arm-*-rtems*)
+  arm*-*-eabi* | arm-*-rtems* | arm*-*-uclinuxfdpiceabi)
     targ_defvec=arm_elf32_le_vec
-    targ_selvecs=arm_elf32_be_vec
+    targ_selvecs="arm_elf32_fdpic_le_vec arm_elf32_be_vec arm_elf32_fdpic_be_vec"
     ;;
   arm*-*-vxworks | arm*-*-windiss)
     targ_defvec=arm_elf32_vxworks_le_vec
diff --git a/bfd/configure b/bfd/configure
index d1fe335..a023806 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -14355,6 +14355,8 @@ do
     arm_coff_le_vec)		 tb="$tb coff-arm.lo $coff" ;;
     arm_elf32_be_vec)		 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_le_vec)		 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    arm_elf32_fdpic_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    arm_elf32_fdpic_le_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_nacl_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_nacl_le_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_symbian_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
diff --git a/bfd/configure.ac b/bfd/configure.ac
index 20e2c02..64df7db 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -432,6 +432,8 @@ do
     arm_coff_le_vec)		 tb="$tb coff-arm.lo $coff" ;;
     arm_elf32_be_vec)		 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_le_vec)		 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    arm_elf32_fdpic_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    arm_elf32_fdpic_le_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_nacl_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_nacl_le_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_symbian_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index ce9c2f2..565bb40 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -3228,6 +3228,9 @@ struct elf32_arm_link_hash_table
   unsigned int bfd_count;
   unsigned int top_index;
   asection **input_list;
+
+  /* True if the target system uses FDPIC. */
+  int fdpic_p;
 };
 
 static inline int
@@ -3806,6 +3809,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
 #endif
   ret->use_rel = TRUE;
   ret->obfd = abfd;
+  ret->fdpic_p = 0;
 
   if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
 			    sizeof (struct elf32_arm_stub_hash_entry)))
@@ -19411,6 +19415,46 @@ elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
 #define ELF_COMMONPAGESIZE		0x1000
 
 
+/* FDPIC Targets.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM		arm_elf32_fdpic_le_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME		"elf32-littlearm-fdpic"
+#undef  TARGET_BIG_SYM
+#define TARGET_BIG_SYM			arm_elf32_fdpic_be_vec
+#undef  TARGET_BIG_NAME
+#define TARGET_BIG_NAME			"elf32-bigarm-fdpic"
+#undef elf_match_priority
+#define elf_match_priority		128
+
+/* Like elf32_arm_link_hash_table_create -- but overrides
+   appropriately for FDPIC.  */
+
+static struct bfd_link_hash_table *
+elf32_arm_fdpic_link_hash_table_create (bfd *abfd)
+{
+  struct bfd_link_hash_table *ret;
+
+  ret = elf32_arm_link_hash_table_create (abfd);
+  if (ret)
+    {
+      struct elf32_arm_link_hash_table *htab = (struct elf32_arm_link_hash_table *) ret;
+
+      htab->fdpic_p = 1;
+    }
+  return ret;
+}
+
+#undef  elf32_bed
+#define elf32_bed				elf32_arm_fdpic_bed
+
+#undef  bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create 	elf32_arm_fdpic_link_hash_table_create
+
+#include "elf32-target.h"
+#undef elf_match_priority
+
 /* VxWorks Targets.  */
 
 #undef	TARGET_LITTLE_SYM
diff --git a/bfd/targets.c b/bfd/targets.c
index 43102d4..79e3309 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -612,6 +612,8 @@ extern const bfd_target arm_coff_be_vec;
 extern const bfd_target arm_coff_le_vec;
 extern const bfd_target arm_elf32_be_vec;
 extern const bfd_target arm_elf32_le_vec;
+extern const bfd_target arm_elf32_fdpic_be_vec;
+extern const bfd_target arm_elf32_fdpic_le_vec;
 extern const bfd_target arm_elf32_nacl_be_vec;
 extern const bfd_target arm_elf32_nacl_le_vec;
 extern const bfd_target arm_elf32_symbian_be_vec;
@@ -1021,6 +1023,8 @@ static const bfd_target * const _bfd_target_vector[] =
 	&arm_coff_le_vec,
 	&arm_elf32_be_vec,
 	&arm_elf32_le_vec,
+	&arm_elf32_fdpic_be_vec,
+	&arm_elf32_fdpic_le_vec,
 	&arm_elf32_symbian_be_vec,
 	&arm_elf32_symbian_le_vec,
 	&arm_elf32_vxworks_be_vec,
diff --git a/ld/Makefile.am b/ld/Makefile.am
index d94fce7..31ac592 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -176,6 +176,7 @@ ALL_EMULATION_SOURCES = \
 	earmelf_fuchsia.c \
 	earmelf_linux.c \
 	earmelf_linux_eabi.c \
+	earmelf_linux_fdpiceabi.c \
 	earmelf_nacl.c \
 	earmelf_nbsd.c \
 	earmelf_phoenix.c \
@@ -185,6 +186,7 @@ ALL_EMULATION_SOURCES = \
 	earmelfb_fuchsia.c \
 	earmelfb_linux.c \
 	earmelfb_linux_eabi.c \
+	earmelfb_linux_fdpiceabi.c \
 	earmelfb_nacl.c \
 	earmelfb_nbsd.c \
 	earmnbsd.c \
@@ -780,6 +782,11 @@ earmelf_linux_eabi.c: $(srcdir)/emulparams/armelf_linux_eabi.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+earmelf_linux_fdpiceabi.c: $(srcdir)/emulparams/armelf_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux.sh \
+  $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 earmelf_nacl.c: $(srcdir)/emulparams/armelf_nacl.sh \
   $(srcdir)/emulparams/armelf_linux_eabi.sh \
   $(srcdir)/emulparams/armelf_linux.sh \
@@ -826,6 +833,12 @@ earmelfb_linux_eabi.c: $(srcdir)/emulparams/armelfb_linux_eabi.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+earmelfb_linux_fdpiceabi.c: $(srcdir)/emulparams/armelfb_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelfb_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux.sh \
+  $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 earmelfb_nacl.c: $(srcdir)/emulparams/armelfb_nacl.sh \
   $(srcdir)/emulparams/armelf_nacl.sh \
   $(srcdir)/emulparams/armelf_linux_eabi.sh \
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 704694b..897a2fb 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -545,6 +545,7 @@ ALL_EMULATION_SOURCES = \
 	earmelf_fuchsia.c \
 	earmelf_linux.c \
 	earmelf_linux_eabi.c \
+	earmelf_linux_fdpiceabi.c \
 	earmelf_nacl.c \
 	earmelf_nbsd.c \
 	earmelf_phoenix.c \
@@ -554,6 +555,7 @@ ALL_EMULATION_SOURCES = \
 	earmelfb_fuchsia.c \
 	earmelfb_linux.c \
 	earmelfb_linux_eabi.c \
+	earmelfb_linux_fdpiceabi.c \
 	earmelfb_nacl.c \
 	earmelfb_nbsd.c \
 	earmnbsd.c \
@@ -1155,6 +1157,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fuchsia.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_eabi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_fdpiceabi.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nacl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nbsd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_phoenix.Po@am__quote@
@@ -1164,6 +1167,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fuchsia.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_eabi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nacl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nbsd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmnbsd.Po@am__quote@
@@ -2344,6 +2348,11 @@ earmelf_linux_eabi.c: $(srcdir)/emulparams/armelf_linux_eabi.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+earmelf_linux_fdpiceabi.c: $(srcdir)/emulparams/armelf_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux.sh \
+  $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 earmelf_nacl.c: $(srcdir)/emulparams/armelf_nacl.sh \
   $(srcdir)/emulparams/armelf_linux_eabi.sh \
   $(srcdir)/emulparams/armelf_linux.sh \
@@ -2390,6 +2399,12 @@ earmelfb_linux_eabi.c: $(srcdir)/emulparams/armelfb_linux_eabi.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+earmelfb_linux_fdpiceabi.c: $(srcdir)/emulparams/armelfb_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux.sh \
+  $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 earmelfb_nacl.c: $(srcdir)/emulparams/armelfb_nacl.sh \
   $(srcdir)/emulparams/armelf_nacl.sh \
   $(srcdir)/emulparams/armelf_linux_eabi.sh \
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 7897448..4bb9398 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -137,7 +137,12 @@ arm*b-*-linux-*)	targ_emul=armelfb_linux
 			targ_extra_libpath="armelf_linux"
 			;;
 arm*-*-linux-*eabi*)	targ_emul=armelf_linux_eabi
-			targ_extra_emuls=armelfb_linux_eabi
+			targ_extra_emuls="armelfb_linux_eabi"
+			targ_extra_libpath=$targ_extra_emuls
+			;;
+arm*-*-uclinuxfdpiceabi)
+			targ_emul=armelf_linux_eabi
+			targ_extra_emuls="armelfb_linux_eabi armelf_linux_fdpiceabi armelfb_linux_fdpiceabi"
 			targ_extra_libpath=$targ_extra_emuls
 			;;
 arm*-*-linux-*)		targ_emul=armelf_linux
diff --git a/ld/emulparams/armelf_linux_fdpiceabi.sh b/ld/emulparams/armelf_linux_fdpiceabi.sh
new file mode 100644
index 0000000..104cf38
--- /dev/null
+++ b/ld/emulparams/armelf_linux_fdpiceabi.sh
@@ -0,0 +1,13 @@
+. ${srcdir}/emulparams/armelf_linux.sh
+
+OUTPUT_FORMAT="elf32-littlearm-fdpic"
+BIG_OUTPUT_FORMAT="elf32-bigarm-fdpic"
+LITTLE_OUTPUT_FORMAT="elf32-littlearm-fdpic"
+
+# Use the ARM ABI-compliant exception-handling sections.
+OTHER_READONLY_SECTIONS="
+  .ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+* .gnu.linkonce.armextab.*}) }
+  ${RELOCATING+ PROVIDE_HIDDEN (__exidx_start = .); }
+  .ARM.exidx ${RELOCATING-0} : { *(.ARM.exidx${RELOCATING+* .gnu.linkonce.armexidx.*}) }
+  ${RELOCATING+ PROVIDE_HIDDEN (__exidx_end = .); }"
+
diff --git a/ld/emulparams/armelfb_linux_fdpiceabi.sh b/ld/emulparams/armelfb_linux_fdpiceabi.sh
new file mode 100644
index 0000000..988ea7a
--- /dev/null
+++ b/ld/emulparams/armelfb_linux_fdpiceabi.sh
@@ -0,0 +1,2 @@
+. ${srcdir}/emulparams/armelf_linux_fdpiceabi.sh
+OUTPUT_FORMAT="elf32-bigarm-fdpic"

Patch

diff --git a/bfd/config.bfd b/bfd/config.bfd
index f04a993..2fe22eb 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -436,7 +436,7 @@  case "${targ}" in
     ;;
   armeb-*-elf | arm*b-*-freebsd* | arm*b-*-linux-* | armeb-*-eabi*)
     targ_defvec=arm_elf32_be_vec
-    targ_selvecs=arm_elf32_le_vec
+    targ_selvecs="arm_elf32_fdpic_be_vec arm_elf32_le_vec arm_elf32_fdpic_le_vec"
     ;;
   arm-*-kaos*)
     targ_defvec=arm_elf32_le_vec
@@ -446,7 +446,7 @@  case "${targ}" in
   arm*-*-uclinux* | arm-*-kfreebsd*-gnu | \
   arm*-*-eabi* | arm-*-rtems*)
     targ_defvec=arm_elf32_le_vec
-    targ_selvecs=arm_elf32_be_vec
+    targ_selvecs="arm_elf32_fdpic_le_vec arm_elf32_be_vec arm_elf32_fdpic_be_vec"
     ;;
   arm*-*-vxworks | arm*-*-windiss)
     targ_defvec=arm_elf32_vxworks_le_vec
diff --git a/bfd/configure b/bfd/configure
index d1fe335..a023806 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -14355,6 +14355,8 @@  do
     arm_coff_le_vec)		 tb="$tb coff-arm.lo $coff" ;;
     arm_elf32_be_vec)		 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_le_vec)		 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    arm_elf32_fdpic_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    arm_elf32_fdpic_le_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_nacl_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_nacl_le_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_symbian_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
diff --git a/bfd/configure.ac b/bfd/configure.ac
index 20e2c02..64df7db 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -432,6 +432,8 @@  do
     arm_coff_le_vec)		 tb="$tb coff-arm.lo $coff" ;;
     arm_elf32_be_vec)		 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_le_vec)		 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    arm_elf32_fdpic_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+    arm_elf32_fdpic_le_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_nacl_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_nacl_le_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
     arm_elf32_symbian_be_vec)	 tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index ce9c2f2..565bb40 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -3228,6 +3228,9 @@  struct elf32_arm_link_hash_table
   unsigned int bfd_count;
   unsigned int top_index;
   asection **input_list;
+
+  /* True if the target system uses FDPIC. */
+  int fdpic_p;
 };
 
 static inline int
@@ -3806,6 +3809,7 @@  elf32_arm_link_hash_table_create (bfd *abfd)
 #endif
   ret->use_rel = TRUE;
   ret->obfd = abfd;
+  ret->fdpic_p = 0;
 
   if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
 			    sizeof (struct elf32_arm_stub_hash_entry)))
@@ -19411,6 +19415,46 @@  elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
 #define ELF_COMMONPAGESIZE		0x1000
 
 
+/* FDPIC Targets.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM		arm_elf32_fdpic_le_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME		"elf32-littlearm-fdpic"
+#undef  TARGET_BIG_SYM
+#define TARGET_BIG_SYM			arm_elf32_fdpic_be_vec
+#undef  TARGET_BIG_NAME
+#define TARGET_BIG_NAME			"elf32-bigarm-fdpic"
+#undef elf_match_priority
+#define elf_match_priority		128
+
+/* Like elf32_arm_link_hash_table_create -- but overrides
+   appropriately for FDPIC.  */
+
+static struct bfd_link_hash_table *
+elf32_arm_fdpic_link_hash_table_create (bfd *abfd)
+{
+  struct bfd_link_hash_table *ret;
+
+  ret = elf32_arm_link_hash_table_create (abfd);
+  if (ret)
+    {
+      struct elf32_arm_link_hash_table *htab = (struct elf32_arm_link_hash_table *) ret;
+
+      htab->fdpic_p = 1;
+    }
+  return ret;
+}
+
+#undef  elf32_bed
+#define elf32_bed				elf32_arm_fdpic_bed
+
+#undef  bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create 	elf32_arm_fdpic_link_hash_table_create
+
+#include "elf32-target.h"
+#undef elf_match_priority
+
 /* VxWorks Targets.  */
 
 #undef	TARGET_LITTLE_SYM
diff --git a/bfd/targets.c b/bfd/targets.c
index 43102d4..79e3309 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -612,6 +612,8 @@  extern const bfd_target arm_coff_be_vec;
 extern const bfd_target arm_coff_le_vec;
 extern const bfd_target arm_elf32_be_vec;
 extern const bfd_target arm_elf32_le_vec;
+extern const bfd_target arm_elf32_fdpic_be_vec;
+extern const bfd_target arm_elf32_fdpic_le_vec;
 extern const bfd_target arm_elf32_nacl_be_vec;
 extern const bfd_target arm_elf32_nacl_le_vec;
 extern const bfd_target arm_elf32_symbian_be_vec;
@@ -1021,6 +1023,8 @@  static const bfd_target * const _bfd_target_vector[] =
 	&arm_coff_le_vec,
 	&arm_elf32_be_vec,
 	&arm_elf32_le_vec,
+	&arm_elf32_fdpic_be_vec,
+	&arm_elf32_fdpic_le_vec,
 	&arm_elf32_symbian_be_vec,
 	&arm_elf32_symbian_le_vec,
 	&arm_elf32_vxworks_be_vec,
diff --git a/ld/Makefile.am b/ld/Makefile.am
index d94fce7..31ac592 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -176,6 +176,7 @@  ALL_EMULATION_SOURCES = \
 	earmelf_fuchsia.c \
 	earmelf_linux.c \
 	earmelf_linux_eabi.c \
+	earmelf_linux_fdpiceabi.c \
 	earmelf_nacl.c \
 	earmelf_nbsd.c \
 	earmelf_phoenix.c \
@@ -185,6 +186,7 @@  ALL_EMULATION_SOURCES = \
 	earmelfb_fuchsia.c \
 	earmelfb_linux.c \
 	earmelfb_linux_eabi.c \
+	earmelfb_linux_fdpiceabi.c \
 	earmelfb_nacl.c \
 	earmelfb_nbsd.c \
 	earmnbsd.c \
@@ -780,6 +782,11 @@  earmelf_linux_eabi.c: $(srcdir)/emulparams/armelf_linux_eabi.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+earmelf_linux_fdpiceabi.c: $(srcdir)/emulparams/armelf_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux.sh \
+  $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 earmelf_nacl.c: $(srcdir)/emulparams/armelf_nacl.sh \
   $(srcdir)/emulparams/armelf_linux_eabi.sh \
   $(srcdir)/emulparams/armelf_linux.sh \
@@ -826,6 +833,12 @@  earmelfb_linux_eabi.c: $(srcdir)/emulparams/armelfb_linux_eabi.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+earmelfb_linux_fdpiceabi.c: $(srcdir)/emulparams/armelfb_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelfb_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux.sh \
+  $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 earmelfb_nacl.c: $(srcdir)/emulparams/armelfb_nacl.sh \
   $(srcdir)/emulparams/armelf_nacl.sh \
   $(srcdir)/emulparams/armelf_linux_eabi.sh \
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 704694b..897a2fb 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -545,6 +545,7 @@  ALL_EMULATION_SOURCES = \
 	earmelf_fuchsia.c \
 	earmelf_linux.c \
 	earmelf_linux_eabi.c \
+	earmelf_linux_fdpiceabi.c \
 	earmelf_nacl.c \
 	earmelf_nbsd.c \
 	earmelf_phoenix.c \
@@ -554,6 +555,7 @@  ALL_EMULATION_SOURCES = \
 	earmelfb_fuchsia.c \
 	earmelfb_linux.c \
 	earmelfb_linux_eabi.c \
+	earmelfb_linux_fdpiceabi.c \
 	earmelfb_nacl.c \
 	earmelfb_nbsd.c \
 	earmnbsd.c \
@@ -1155,6 +1157,7 @@  distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fuchsia.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_eabi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_fdpiceabi.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nacl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nbsd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_phoenix.Po@am__quote@
@@ -1164,6 +1167,7 @@  distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fuchsia.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_eabi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nacl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nbsd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmnbsd.Po@am__quote@
@@ -2344,6 +2348,11 @@  earmelf_linux_eabi.c: $(srcdir)/emulparams/armelf_linux_eabi.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+earmelf_linux_fdpiceabi.c: $(srcdir)/emulparams/armelf_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux.sh \
+  $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 earmelf_nacl.c: $(srcdir)/emulparams/armelf_nacl.sh \
   $(srcdir)/emulparams/armelf_linux_eabi.sh \
   $(srcdir)/emulparams/armelf_linux.sh \
@@ -2390,6 +2399,12 @@  earmelfb_linux_eabi.c: $(srcdir)/emulparams/armelfb_linux_eabi.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+earmelfb_linux_fdpiceabi.c: $(srcdir)/emulparams/armelfb_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux_fdpiceabi.sh \
+  $(srcdir)/emulparams/armelf_linux.sh \
+  $(ELF_DEPS) $(srcdir)/emultempl/armelf.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 earmelfb_nacl.c: $(srcdir)/emulparams/armelfb_nacl.sh \
   $(srcdir)/emulparams/armelf_nacl.sh \
   $(srcdir)/emulparams/armelf_linux_eabi.sh \
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 7897448..ea2aff8 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -129,7 +129,7 @@  arm*-*-symbianelf*)	targ_emul=armsymbian;;
 arm-*-kaos*)		targ_emul=armelf ;;
 arm9e-*-elf)		targ_emul=armelf ;;
 arm*b-*-linux-*eabi*)	targ_emul=armelfb_linux_eabi
-			targ_extra_emuls=armelf_linux_eabi
+			targ_extra_emuls="armelf_linux_eabi armelf_linux_fdpiceabi armelfb_linux_fdpiceabi"
 			targ_extra_libpath=$targ_extra_emuls
 			;;
 arm*b-*-linux-*)	targ_emul=armelfb_linux
@@ -137,7 +137,7 @@  arm*b-*-linux-*)	targ_emul=armelfb_linux
 			targ_extra_libpath="armelf_linux"
 			;;
 arm*-*-linux-*eabi*)	targ_emul=armelf_linux_eabi
-			targ_extra_emuls=armelfb_linux_eabi
+			targ_extra_emuls="armelfb_linux_eabi armelf_linux_fdpiceabi armelfb_linux_fdpiceabi"
 			targ_extra_libpath=$targ_extra_emuls
 			;;
 arm*-*-linux-*)		targ_emul=armelf_linux
diff --git a/ld/emulparams/armelf_linux_fdpiceabi.sh b/ld/emulparams/armelf_linux_fdpiceabi.sh
new file mode 100644
index 0000000..104cf38
--- /dev/null
+++ b/ld/emulparams/armelf_linux_fdpiceabi.sh
@@ -0,0 +1,13 @@ 
+. ${srcdir}/emulparams/armelf_linux.sh
+
+OUTPUT_FORMAT="elf32-littlearm-fdpic"
+BIG_OUTPUT_FORMAT="elf32-bigarm-fdpic"
+LITTLE_OUTPUT_FORMAT="elf32-littlearm-fdpic"
+
+# Use the ARM ABI-compliant exception-handling sections.
+OTHER_READONLY_SECTIONS="
+  .ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+* .gnu.linkonce.armextab.*}) }
+  ${RELOCATING+ PROVIDE_HIDDEN (__exidx_start = .); }
+  .ARM.exidx ${RELOCATING-0} : { *(.ARM.exidx${RELOCATING+* .gnu.linkonce.armexidx.*}) }
+  ${RELOCATING+ PROVIDE_HIDDEN (__exidx_end = .); }"
+
diff --git a/ld/emulparams/armelfb_linux_fdpiceabi.sh b/ld/emulparams/armelfb_linux_fdpiceabi.sh
new file mode 100644
index 0000000..988ea7a
--- /dev/null
+++ b/ld/emulparams/armelfb_linux_fdpiceabi.sh
@@ -0,0 +1,2 @@ 
+. ${srcdir}/emulparams/armelf_linux_fdpiceabi.sh
+OUTPUT_FORMAT="elf32-bigarm-fdpic"