From 188fd7aea619d9f66a822bad881d8f56892b60aa Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 20 Mar 2018 10:54:59 +0100 Subject: [PATCH] [ARM] Add FDPIC relocations definitions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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 Mickaël Guêné 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 +++++ gas/ChangeLog | 10 +++++ gas/config/tc-arm.c | 27 ++++++++++++- gas/testsuite/gas/arm/reloc-fdpic.d | 20 +++++++++ gas/testsuite/gas/arm/reloc-fdpic.s | 9 +++++ include/ChangeLog | 7 ++++ include/elf/arm.h | 4 ++ 10 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 gas/testsuite/gas/arm/reloc-fdpic.d create mode 100644 gas/testsuite/gas/arm/reloc-fdpic.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index dd28d04fccf..9b509333a14 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,20 @@ +2018-04-25 Christophe Lyon + Mickaël Guêné + + * 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 Mickaël Guêné diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 97c37a07af9..f58c2f73396 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 a0b0be3f160..3805f713f80 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 80db0c93902..e78e582c1f3 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -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 diff --git a/gas/ChangeLog b/gas/ChangeLog index 5db76c97706..122daaaf0c8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2018-04-25 Christophe Lyon + Mickaël Guêné + + * 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 Mickaël Guêné diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index d735609eca5..33a88bb3145 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -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 index 00000000000..c25aa805535 --- /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: arm*-*-uclinuxfdpiceabi + +.*: +file format .*arm.* + + +Disassembly of section .text: + +00000000 : +.* + 0: R_ARM_GOTFUNCDESC myfunc + 4: R_ARM_GOTOFFFUNCDESC myfunc + 8: R_ARM_FUNCDESC myfunc + +0000000c : + 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 00000000000..cbb61c5bc19 --- /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/ChangeLog b/include/ChangeLog index d159a25c056..6b52420fa40 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,10 @@ +2018-04-25 Christophe Lyon + Mickaël Guêné + + * elf/arm.h (R_ARM_GOTFUNCDESC, R_ARM_GOTOFFFUNCDESC) + (R_ARM_FUNCDESC) + (R_ARM_FUNCDESC_VALUE): Define new relocations. + 2018-04-25 Christophe Lyon Mickaël Guêné diff --git a/include/elf/arm.h b/include/elf/arm.h index fb9c5f684cc..158f7b1652c 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) -- 2.30.2