From 72f3b6aae734d8cdcded38aca94e379848bec7ef Mon Sep 17 00:00:00 2001 From: Claudiu Zissulescu Date: Tue, 8 Mar 2016 14:19:52 +0100 Subject: [PATCH] [ARC] Allow non-instruction relocations within .text sections bfd/ 2016-03-08 Cupertino Miranda Andrew Burgess * elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32. (arc_bfd_put_32): Becomes an alias for bfd_put_32. (arc_elf_howto_init): Added assert to validate relocations. (get_middle_endian_relocation): Delete. (middle_endian_convert): New function. (ME): Redefine, now does nothing. (IS_ME): New define. (arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO' definition to call middle_endian_convert. Add a new local variable and make use of this throughout. Added call to arc_bfd_get_8 and arc_bfd_put_8 for 8 bit relocations. gas/ 2016-03-08 Andrew Burgess * testsuite/gas/arc/inline-data-1.d: New file. * testsuite/gas/arc/inline-data-1.s: New file. include/ 2016-03-08 Cupertino Miranda Andrew Burgess * elf/arc-reloc.def: Add a call to ME within the formula for each relocation that requires middle-endian correction. --- bfd/ChangeLog | 15 ++++ bfd/elf32-arc.c | 84 ++++++++++---------- gas/ChangeLog | 5 ++ gas/testsuite/gas/arc/inline-data-1.d | 7 ++ gas/testsuite/gas/arc/inline-data-1.s | 4 + include/ChangeLog | 6 ++ include/elf/arc-reloc.def | 108 ++++++++++++++++---------- include/opcode/arc-func.h | 4 +- 8 files changed, 147 insertions(+), 86 deletions(-) create mode 100644 gas/testsuite/gas/arc/inline-data-1.d create mode 100644 gas/testsuite/gas/arc/inline-data-1.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8c2da68af34..2b6cf15aaef 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2016-03-08 Cupertino Miranda + Andrew Burgess + + * elf32-arc.c (arc_bfd_get_32): Becomes an alias for bfd_get_32. + (arc_bfd_put_32): Becomes an alias for bfd_put_32. + (arc_elf_howto_init): Added assert to validate relocations. + (get_middle_endian_relocation): Delete. + (middle_endian_convert): New function. + (ME): Redefine, now does nothing. + (IS_ME): New define. + (arc_do_relocation): Extend the attached 'ARC_RELOC_HOWTO' + definition to call middle_endian_convert. Add a new local + variable and make use of this throughout. Added call to + arc_bfd_get_8 and arc_bfd_put_8 for 8 bit relocations. + 2016-03-07 Nick Clifton PR binutils/19775 diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index ab2512d11d0..4090b7a7717 100644 --- a/bfd/elf32-arc.c +++ b/bfd/elf32-arc.c @@ -252,32 +252,11 @@ is_reloc_for_TLS (reloc_howto_type *howto) #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B) #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B) +#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B) #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C) #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C) +#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C) -static long -arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section) -{ - long insn = bfd_get_32 (abfd, loc); - - if (!bfd_big_endian (abfd) - && input_section - && (input_section->flags & SEC_CODE)) - insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16); - - return insn; -} - -static void -arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section) -{ - if (!bfd_big_endian (abfd) - && input_section - && (input_section->flags & SEC_CODE)) - insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16); - - bfd_put_32 (abfd, insn, loc); -} static bfd_reloc_status_type arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED, @@ -344,9 +323,15 @@ static void arc_elf_howto_init (void) #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \ elf_arc_howto_table[TYPE].pc_relative = \ (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \ - elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); + elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \ + /* Only 32 bit data relocations should be marked as ME. */ \ + if (strstr (#FORMULA, " ME ") != NULL) \ + { \ + BFD_ASSERT (SIZE == 2); \ + } #include "elf/arc-reloc.def" + } #undef ARC_RELOC_HOWTO @@ -771,14 +756,23 @@ debug_arc_reloc (struct arc_relocation_data reloc_data) } } -static ATTRIBUTE_UNUSED bfd_vma -get_middle_endian_relocation (bfd_vma reloc) +static bfd_vma +middle_endian_convert (bfd_vma insn, bfd_boolean do_it) { - bfd_vma ret = ((reloc & 0xffff0000) >> 16) | - ((reloc & 0xffff) << 16); - return ret; + if (do_it) + { + insn = + ((insn & 0xffff0000) >> 16) | + ((insn & 0xffff) << 16); + } + return insn; } +#define ME(reloc) (reloc) + +#define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \ + && (!bfd_big_endian (BFD))) + #define S (reloc_data.sym_value \ + (reloc_data.sym_section->output_section != NULL ? \ (reloc_data.sym_section->output_offset \ @@ -818,8 +812,6 @@ get_middle_endian_relocation (bfd_vma reloc) #define TLS_TBSS (8) #define TCB_SIZE (8) -#define NON_ME(VALUE) (reverse_me (reloc_data, VALUE)) - #define none (0) #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \ @@ -870,20 +862,13 @@ get_middle_endian_relocation (bfd_vma reloc) bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \ relocation = FORMULA ; \ PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \ + insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \ insn = RELOC_FUNCTION (insn, relocation); \ + insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \ PRINT_DEBUG_RELOC_INFO_AFTER \ } \ break; -static bfd_vma -reverse_me (struct arc_relocation_data reloc_data, bfd_vma reloc) -{ - if (reloc_data.input_section && reloc_data.input_section->flags & SEC_CODE) - return ((0x0000fffff & reloc) << 16) | ((0xffff0000 & reloc) >> 16); - else - return reloc; -} - static bfd_reloc_status_type arc_do_relocation (bfd_byte * contents, struct arc_relocation_data reloc_data, @@ -892,6 +877,7 @@ arc_do_relocation (bfd_byte * contents, bfd_vma relocation = 0; bfd_vma insn; bfd_vma orig_insn ATTRIBUTE_UNUSED; + bfd * abfd = reloc_data.input_section->owner; struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info); if (reloc_data.should_relocate == FALSE) @@ -900,13 +886,17 @@ arc_do_relocation (bfd_byte * contents, switch (reloc_data.howto->size) { case 2: - insn = arc_bfd_get_32 (reloc_data.input_section->owner, + insn = arc_bfd_get_32 (abfd, contents + reloc_data.reloc_offset, reloc_data.input_section); break; case 1: + insn = arc_bfd_get_16 (abfd, + contents + reloc_data.reloc_offset, + reloc_data.input_section); + break; case 0: - insn = arc_bfd_get_16 (reloc_data.input_section->owner, + insn = arc_bfd_get_8 (abfd, contents + reloc_data.reloc_offset, reloc_data.input_section); break; @@ -934,7 +924,7 @@ arc_do_relocation (bfd_byte * contents, flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow, reloc_data.howto->bitsize, reloc_data.howto->rightshift, - bfd_arch_bits_per_address (reloc_data.input_section->owner), + bfd_arch_bits_per_address (abfd), relocation); #undef DEBUG_ARC_RELOC @@ -960,13 +950,17 @@ arc_do_relocation (bfd_byte * contents, switch (reloc_data.howto->size) { case 2: - arc_bfd_put_32 (reloc_data.input_section->owner, insn, + arc_bfd_put_32 (abfd, insn, contents + reloc_data.reloc_offset, reloc_data.input_section); break; case 1: + arc_bfd_put_16 (abfd, insn, + contents + reloc_data.reloc_offset, + reloc_data.input_section); + break; case 0: - arc_bfd_put_16 (reloc_data.input_section->owner, insn, + arc_bfd_put_8 (abfd, insn, contents + reloc_data.reloc_offset, reloc_data.input_section); break; diff --git a/gas/ChangeLog b/gas/ChangeLog index ca58d4dc2fd..58b520d41e1 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2016-03-08 Andrew Burgess + + * testsuite/gas/arc/inline-data-1.d: New file. + * testsuite/gas/arc/inline-data-1.s: New file. + 2016-03-07 Andre Vieira * config/tc-arm.c (arm_cpus): Add cortex-r8. diff --git a/gas/testsuite/gas/arc/inline-data-1.d b/gas/testsuite/gas/arc/inline-data-1.d new file mode 100644 index 00000000000..ce5c272a6fe --- /dev/null +++ b/gas/testsuite/gas/arc/inline-data-1.d @@ -0,0 +1,7 @@ +#as: -mcpu=arc700 +#objdump: -sj .text + +.*: +file format .*arc.* + +Contents of section .text: + [0-9a-f]+ ddccbbaa ffee .* diff --git a/gas/testsuite/gas/arc/inline-data-1.s b/gas/testsuite/gas/arc/inline-data-1.s new file mode 100644 index 00000000000..e63bf0627b0 --- /dev/null +++ b/gas/testsuite/gas/arc/inline-data-1.s @@ -0,0 +1,4 @@ + .text + + .word 0xaabbccdd + .short 0xeeff diff --git a/include/ChangeLog b/include/ChangeLog index 0e2c2bda221..7e01b279bd9 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2016-03-08 Cupertino Miranda + Andrew Burgess + + * elf/arc-reloc.def: Add a call to ME within the formula for each + relocation that requires middle-endian correction. + 2016-03-07 Trevor Saunders * opcode/dlx.h (struct dlx_opcode): Add const qualifiers. diff --git a/include/elf/arc-reloc.def b/include/elf/arc-reloc.def index 96123de4976..36a3516808f 100644 --- a/include/elf/arc-reloc.def +++ b/include/elf/arc-reloc.def @@ -1,3 +1,34 @@ +/* ARC relocation types + Copyright (C) 2015-2016 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + GAS/GDB is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GAS/GDB is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS or GDB; see the file COPYING3. If not, write to + the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + + ARC_RELOC_HOWTO(ARC_NONE, 0, \ 2, \ 32, \ @@ -31,7 +62,7 @@ ARC_RELOC_HOWTO(ARC_32, 4, \ 32, \ replace_word32, \ bitfield, \ - (NON_ME ( S + A ) )) + ( S + A )) ARC_RELOC_HOWTO(ARC_N8, 8, \ 0, \ @@ -80,84 +111,84 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL, 14, \ 20, \ replace_disp21h, \ signed, \ - ( ( ( S + A ) - P ) >> 1 )) + ( ME ( ( ( ( S + A ) - P ) >> 1 ) ) )) ARC_RELOC_HOWTO(ARC_S21W_PCREL, 15, \ 2, \ 19, \ replace_disp21w, \ signed, \ - ( ( ( S + A ) - P ) >> 2 )) + ( ME ( ( ( ( S + A ) - P ) >> 2 ) ) )) ARC_RELOC_HOWTO(ARC_S25H_PCREL, 16, \ 2, \ 24, \ replace_disp25h, \ signed, \ - ( ( ( S + A ) - P ) >> 1 )) + ( ME ( ( ( ( S + A ) - P ) >> 1 ) ) )) ARC_RELOC_HOWTO(ARC_S25W_PCREL, 17, \ 2, \ 23, \ replace_disp25w, \ signed, \ - ( ( ( S + A ) - P ) >> 2 )) + ( ME ( ( ( ( S + A ) - P ) >> 2 ) ) )) ARC_RELOC_HOWTO(ARC_SDA32, 18, \ 2, \ 32, \ replace_word32, \ signed, \ - ( ( S + A ) - _SDA_BASE_ )) + ( ME ( ( ( S + A ) - _SDA_BASE_ ) ) )) ARC_RELOC_HOWTO(ARC_SDA_LDST, 19, \ 2, \ 9, \ replace_disp9ls, \ signed, \ - ( ( S + A ) - _SDA_BASE_ )) + ( ME ( ( ( S + A ) - _SDA_BASE_ ) ) )) ARC_RELOC_HOWTO(ARC_SDA_LDST1, 20, \ 2, \ 9, \ replace_disp9ls, \ signed, \ - ( ( ( S + A ) - _SDA_BASE_ ) >> 1 )) + ( ME ( ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ) ) )) ARC_RELOC_HOWTO(ARC_SDA_LDST2, 21, \ 2, \ 9, \ replace_disp9ls, \ signed, \ - ( ( ( S + A ) - _SDA_BASE_ ) >> 2 )) + ( ME ( ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ) ) )) ARC_RELOC_HOWTO(ARC_SDA16_LD, 22, \ 1, \ 9, \ replace_disp9s, \ signed, \ - ( ( S + A ) - _SDA_BASE_ )) + ( ( ( S + A ) - _SDA_BASE_ ) )) ARC_RELOC_HOWTO(ARC_SDA16_LD1, 23, \ 1, \ 9, \ replace_disp9s, \ signed, \ - ( ( ( S + A ) - _SDA_BASE_ ) >> 1 )) + ( ( ( ( S + A ) - _SDA_BASE_ ) >> 1 ) )) ARC_RELOC_HOWTO(ARC_SDA16_LD2, 24, \ 1, \ 9, \ replace_disp9s, \ signed, \ - ( ( ( S + A ) - _SDA_BASE_ ) >> 2 )) + ( ( ( ( S + A ) - _SDA_BASE_ ) >> 2 ) )) ARC_RELOC_HOWTO(ARC_S13_PCREL, 25, \ 1, \ 11, \ replace_disp13s, \ signed, \ - ( ( ( S + A ) - P ) >> 2 )) + ( ( ( ( S + A ) - P ) >> 2 ) )) ARC_RELOC_HOWTO(ARC_W, 26, \ 2, \ @@ -171,42 +202,42 @@ ARC_RELOC_HOWTO(ARC_32_ME, 27, \ 32, \ replace_limm, \ signed, \ - ( S + A )) + ( ME ( ( S + A ) ) )) ARC_RELOC_HOWTO(ARC_32_ME_S, 105, \ 2, \ 32, \ replace_limms, \ signed, \ - ( S + A )) + ( ME ( ( S + A ) ) )) ARC_RELOC_HOWTO(ARC_N32_ME, 28, \ 2, \ 32, \ replace_word32, \ bitfield, \ - ( S - A )) + ( ME ( ( S - A ) ) )) ARC_RELOC_HOWTO(ARC_SECTOFF_ME, 29, \ 2, \ 32, \ replace_word32, \ bitfield, \ - ( ( S - SECTSTART ) + A )) + ( ME ( ( ( S - SECTSTART ) + A ) ) )) ARC_RELOC_HOWTO(ARC_SDA32_ME, 30, \ 2, \ 32, \ replace_limm, \ signed, \ - ( ( S + A ) - _SDA_BASE_ )) + ( ME ( ( ( S + A ) - _SDA_BASE_ ) ) )) ARC_RELOC_HOWTO(ARC_W_ME, 31, \ 2, \ 32, \ replace_word32, \ bitfield, \ - ( S + A )) + ( ME ( ( ( S + A ) & ( ~3 ) ) ) )) ARC_RELOC_HOWTO(AC_SECTOFF_U8, 35, \ 2, \ @@ -255,14 +286,14 @@ ARC_RELOC_HOWTO(ARC_SECTOFF_ME_1, 41, \ 32, \ replace_word32, \ bitfield, \ - ( ( ( S - SECTSTART ) + A ) >> 1 )) + ( ME ( ( ( ( S - SECTSTART ) + A ) >> 1 ) ) )) ARC_RELOC_HOWTO(ARC_SECTOFF_ME_2, 42, \ 2, \ 32, \ replace_word32, \ bitfield, \ - ( ( ( S - SECTSTART ) + A ) >> 2 )) + ( ME ( ( ( ( S - SECTSTART ) + A ) >> 2 ) ) )) ARC_RELOC_HOWTO(ARC_SECTOFF_1, 43, \ 2, \ @@ -297,7 +328,7 @@ ARC_RELOC_HOWTO(ARC_PC32, 50, \ 32, \ replace_word32, \ signed, \ - ( ( S + A ) - P )) + ( ME ( ( ( S + A ) - P ) ) )) ARC_RELOC_HOWTO(ARC_GOT32, 59, \ 2, \ @@ -311,14 +342,14 @@ ARC_RELOC_HOWTO(ARC_GOTPC32, 51, \ 32, \ replace_word32, \ signed, \ - ( ( ( GOT + G ) + A ) - P )) + ( ME ( ( ( ( GOT + G ) + A ) - P ) ) )) ARC_RELOC_HOWTO(ARC_PLT32, 52, \ 2, \ 32, \ replace_word32, \ signed, \ - ( ( L + A ) - P )) + ( ME ( ( ( L + A ) - P ) ) )) ARC_RELOC_HOWTO(ARC_COPY, 53, \ 2, \ @@ -339,42 +370,42 @@ ARC_RELOC_HOWTO(ARC_JMP_SLOT, 55, \ 32, \ replace_word32, \ signed, \ - S) + ( ME ( S ) )) ARC_RELOC_HOWTO(ARC_RELATIVE, 56, \ 2, \ 32, \ replace_word32, \ signed, \ - ( B + A )) + ( ME ( ( B + A ) ) )) ARC_RELOC_HOWTO(ARC_GOTOFF, 57, \ 2, \ 32, \ replace_word32, \ signed, \ - ( ( S + A ) - GOT )) + ( ME ( ( ( S + A ) - GOT ) ) )) ARC_RELOC_HOWTO(ARC_GOTPC, 58, \ 2, \ 32, \ replace_word32, \ signed, \ - ( GOT_BEGIN - P )) + ( ME ( ( GOT_BEGIN - P ) ) )) ARC_RELOC_HOWTO(ARC_S21W_PCREL_PLT, 60, \ 2, \ 19, \ replace_disp21w, \ signed, \ - ( ( ( L + A ) - P ) >> 2 )) + ( ME ( ( ( ( L + A ) - P ) >> 2 ) ) )) ARC_RELOC_HOWTO(ARC_S25H_PCREL_PLT, 61, \ 2, \ 24, \ replace_disp25h, \ signed, \ - ( ( ( L + A ) - P ) >> 1 )) + ( ME ( ( ( ( L + A ) - P ) >> 1 ) ) )) ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \ 2, \ @@ -395,7 +426,7 @@ ARC_RELOC_HOWTO(ARC_TLS_GD_GOT, 69, \ 32, \ replace_word32, \ dont, \ - ( G + GOT - P)) + ( ME ( ( ( G + GOT ) - P ) ) )) ARC_RELOC_HOWTO(ARC_TLS_GD_LD, 70, \ 2, \ @@ -416,47 +447,46 @@ ARC_RELOC_HOWTO(ARC_TLS_IE_GOT, 72, \ 32, \ replace_word32, \ dont, \ - ( G + GOT - P)) + ( ME ( ( ( G + GOT ) - P ) ) )) ARC_RELOC_HOWTO(ARC_TLS_DTPOFF, 67, \ 2, \ 32, \ replace_word32, \ dont, \ - ( S - TLS_REL )) + ( ME ( ( S - TLS_REL ) ) )) ARC_RELOC_HOWTO(ARC_TLS_DTPOFF_S9, 73, \ 2, \ 32, \ replace_word32, \ dont, \ - ( S - TLS_REL )) + ( ME ( ( S - TLS_REL ) ) )) ARC_RELOC_HOWTO(ARC_TLS_LE_S9, 74, \ 2, \ 32, \ replace_word32, \ dont, \ - ( ( S + TCB_SIZE ) - TLS_REL )) + ( ME ( ( ( S + TCB_SIZE ) - TLS_REL ) ) )) ARC_RELOC_HOWTO(ARC_TLS_LE_32, 75, \ 2, \ 32, \ replace_word32, \ dont, \ - ( ( S + A + TCB_SIZE ) - TLS_REL )) + ( ME ( ( ( ( S + A ) + TCB_SIZE ) - TLS_REL ) ) )) ARC_RELOC_HOWTO(ARC_S25W_PCREL_PLT, 76, \ 2, \ 23, \ replace_disp25w, \ signed, \ - ( ( ( L + A ) - P ) >> 2 )) + ( ME ( ( ( ( L + A ) - P ) >> 2 ) ) )) ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \ 2, \ 20, \ replace_disp21h, \ signed, \ - ( ( ( L + A ) - P ) >> 1 )) - + ( ME ( ( ( ( L + A ) - P ) >> 1 ) ) )) diff --git a/include/opcode/arc-func.h b/include/opcode/arc-func.h index 96ffcffe8a2..47451a6af3b 100644 --- a/include/opcode/arc-func.h +++ b/include/opcode/arc-func.h @@ -66,8 +66,8 @@ replace_bits16 (unsigned insn, int value ATTRIBUTE_UNUSED) ATTRIBUTE_UNUSED static unsigned replace_bits24 (unsigned insn, int value ATTRIBUTE_UNUSED) { - insn = insn & ~0xffffff; - insn |= ((value >> 0) & 0xffffff) << 0; + insn = insn & ~0xffffff00; + insn |= ((value >> 0) & 0xffffff) << 8; return insn; } -- 2.30.2