[ARM] Add FDPIC relocations definitions
authorChristophe Lyon <christophe.lyon@st.com>
Tue, 20 Mar 2018 09:54:59 +0000 (10:54 +0100)
committerChristophe Lyon <christophe.lyon@linaro.org>
Wed, 25 Apr 2018 20:51:53 +0000 (20:51 +0000)
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
bfd/bfd-in2.h
bfd/elf32-arm.c
bfd/reloc.c
gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/gas/arm/reloc-fdpic.d [new file with mode: 0644]
gas/testsuite/gas/arm/reloc-fdpic.s [new file with mode: 0644]
include/ChangeLog
include/elf/arm.h

index dd28d04fccf263607c525e19aa35f733dc5acf79..9b509333a140b017b97cb085b69613f0d42b5b2f 100644 (file)
@@ -1,3 +1,20 @@
+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>
 
index 97c37a07af9c2b8d8cb7470aed25951b2bc6fefc..f58c2f73396278a6c2fef310e1ecca62f37cebd8 100644 (file)
@@ -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,
index a0b0be3f16078db8da092708d464ea6d578fe4e2..3805f713f80bf4e35ca3c26f7a9b189a3b080d78 100644 (file)
@@ -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},
index 80db0c93902cd5c81fa79c13aad24b3a92f8a16a..e78e582c1f301b579bb0dde3d7d910d69619c02a 100644 (file)
@@ -3207,6 +3207,17 @@ ENUMX
 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
index 5db76c97706317c2320e960c5b3323ee9ad9adee..122daaaf0c851e98db15adf47ef443e51e653e65 100644 (file)
@@ -1,3 +1,13 @@
+2018-04-25  Christophe Lyon  <christophe.lyon@st.com>
+       Mickaël Guêné  <mickael.guene@st.com>
+
+       * 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.
+
 2018-04-25  Christophe Lyon  <christophe.lyon@st.com>
        Mickaël Guêné  <mickael.guene@st.com>
 
index d735609eca5c1960b2ba95420620584536ebada5..33a88bb3145cd414badc21839fc459c21fa008a4 100644 (file)
@@ -19303,7 +19303,13 @@ static struct reloc_entry reloc_names[] =
   { "tlscall", BFD_RELOC_ARM_TLS_CALL},
        { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
   { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
-       { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ}
+       { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
+  { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
+       { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
+  { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
+       { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
+  { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
+       { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC }
 };
 #endif
 
@@ -23992,6 +23998,22 @@ md_apply_fix (fixS *   fixP,
       if (fixP->fx_done || !seg->use_rela_p)
        md_number_to_chars (buf, fixP->fx_offset, 4);
       break;
+
+      /* Relocations for FDPIC.  */
+    case BFD_RELOC_ARM_GOTFUNCDESC:
+    case BFD_RELOC_ARM_GOTOFFFUNCDESC:
+    case BFD_RELOC_ARM_FUNCDESC:
+      if (arm_fdpic)
+       {
+         if (fixP->fx_done || !seg->use_rela_p)
+           md_number_to_chars (buf, 0, 4);
+       }
+      else
+       {
+         as_bad_where (fixP->fx_file, fixP->fx_line,
+                       _("Relocation supported only in FDPIC mode"));
+      }
+      break;
 #endif
 
     case BFD_RELOC_RVA:
@@ -24753,6 +24775,9 @@ tc_gen_reloc (asection *section, fixS *fixp)
     case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
     case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
     case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
+    case BFD_RELOC_ARM_GOTFUNCDESC:
+    case BFD_RELOC_ARM_GOTOFFFUNCDESC:
+    case BFD_RELOC_ARM_FUNCDESC:
       code = fixp->fx_r_type;
       break;
 
diff --git a/gas/testsuite/gas/arm/reloc-fdpic.d b/gas/testsuite/gas/arm/reloc-fdpic.d
new file mode 100644 (file)
index 0000000..c25aa80
--- /dev/null
@@ -0,0 +1,20 @@
+#as: --fdpic
+#objdump: -dr --show-raw-insn
+#name: FDPIC relocations
+# This test is only valid on ELF based ports.
+#not-skip: arm*-*-uclinuxfdpiceabi
+
+.*: +file format .*arm.*
+
+
+Disassembly of section .text:
+
+00000000 <myfunc-0xc>:
+.*
+                       0: R_ARM_GOTFUNCDESC    myfunc
+                       4: R_ARM_GOTOFFFUNCDESC myfunc
+                       8: R_ARM_FUNCDESC       myfunc
+
+0000000c <myfunc>:
+   c:  e12fff1e        bx      lr
+.*
\ No newline at end of file
diff --git a/gas/testsuite/gas/arm/reloc-fdpic.s b/gas/testsuite/gas/arm/reloc-fdpic.s
new file mode 100644 (file)
index 0000000..cbb61c5
--- /dev/null
@@ -0,0 +1,9 @@
+       .syntax unified
+
+       .word myfunc(GOTFUNCDESC)
+       .word myfunc(GOTOFFFUNCDESC)
+       .word myfunc(FUNCDESC)
+
+       .type myfunc, %function
+myfunc:
+       bx      lr
index d159a25c0566ca0c64b1340f5b32e9a3e5fee543..6b52420fa4004bae4c84ed61eb1e0bca10a2d775 100644 (file)
@@ -1,3 +1,10 @@
+2018-04-25  Christophe Lyon  <christophe.lyon@st.com>
+       Mickaël Guêné  <mickael.guene@st.com>
+
+       * elf/arm.h (R_ARM_GOTFUNCDESC, R_ARM_GOTOFFFUNCDESC)
+       (R_ARM_FUNCDESC)
+       (R_ARM_FUNCDESC_VALUE): Define new relocations.
+
 2018-04-25  Christophe Lyon  <christophe.lyon@st.com>
        Mickaël Guêné  <mickael.guene@st.com>
 
index fb9c5f684cca1be94a1dac726116d5386a86bf27..158f7b1652ce4da5a473634c105907159947bfc3 100644 (file)
@@ -240,6 +240,10 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
   RELOC_NUMBER (R_ARM_THM_ALU_ABS_G3_NC,135)
 
   RELOC_NUMBER (R_ARM_IRELATIVE,       160)
+  RELOC_NUMBER (R_ARM_GOTFUNCDESC,     161)
+  RELOC_NUMBER (R_ARM_GOTOFFFUNCDESC,  162)
+  RELOC_NUMBER (R_ARM_FUNCDESC,        163)
+  RELOC_NUMBER (R_ARM_FUNCDESC_VALUE,  164)
 
   /* Extensions?  R=read-only?  */
   RELOC_NUMBER (R_ARM_RXPC25,          249)