aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@st.com>2018-03-20 10:54:59 +0100
committerChristophe Lyon <christophe.lyon@linaro.org>2018-03-27 09:13:07 +0000
commitcb19decfbc2dac206e216da07d7c052bfe9a1357 (patch)
treedd33ba1aed517d0e9fba09b851bd5e89dbd7465e
parent3aa7ed2673afb00be420761e238a2fb73f121262 (diff)
downloadgdb-cb19decfbc2dac206e216da07d7c052bfe9a1357.zip
gdb-cb19decfbc2dac206e216da07d7c052bfe9a1357.tar.gz
gdb-cb19decfbc2dac206e216da07d7c052bfe9a1357.tar.bz2
[ARM] Add FDPIC relocations definitions
Add FDPIC relocation definitions in BFD and gas. Gas rejects them if the --fdpic option was not specified. 2018-XX-XX 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.
-rw-r--r--bfd/bfd-in2.h6
-rw-r--r--bfd/elf32-arm.c63
-rw-r--r--bfd/reloc.c11
-rw-r--r--gas/config/tc-arm.c27
-rw-r--r--gas/testsuite/gas/arm/reloc-fdpic.d20
-rw-r--r--gas/testsuite/gas/arm/reloc-fdpic.s9
-rw-r--r--include/elf/arm.h4
7 files changed, 136 insertions, 4 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 9742c1a..0c2279f 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -3565,6 +3565,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 42e35b9..5715317 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -3217,6 +3217,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
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 8a3a282..e869084 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -19320,7 +19320,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
@@ -24024,6 +24030,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:
@@ -24785,6 +24807,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
index 0000000..bedb2ff
--- /dev/null
+++ b/gas/testsuite/gas/arm/reloc-fdpic.d
@@ -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: *-*-uclibceabi
+
+.*: +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
index 0000000..cbb61c5
--- /dev/null
+++ b/gas/testsuite/gas/arm/reloc-fdpic.s
@@ -0,0 +1,9 @@
+ .syntax unified
+
+ .word myfunc(GOTFUNCDESC)
+ .word myfunc(GOTOFFFUNCDESC)
+ .word myfunc(FUNCDESC)
+
+ .type myfunc, %function
+myfunc:
+ bx lr
diff --git a/include/elf/arm.h b/include/elf/arm.h
index fb9c5f6..158f7b1 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -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)