diff options
author | Claudiu Zissulescu <claziss@synopsys.com> | 2016-03-08 14:19:52 +0100 |
---|---|---|
committer | Claudiu Zissulescu <claziss@synopsys.com> | 2016-03-08 14:19:52 +0100 |
commit | 72f3b6aae734d8cdcded38aca94e379848bec7ef (patch) | |
tree | af7ba7ac67dab430d88682b2e7f6805e60e80829 /bfd | |
parent | 8e460aa0a4fbd535ebe383ba2748bb78bbf2a92d (diff) | |
download | gdb-72f3b6aae734d8cdcded38aca94e379848bec7ef.zip gdb-72f3b6aae734d8cdcded38aca94e379848bec7ef.tar.gz gdb-72f3b6aae734d8cdcded38aca94e379848bec7ef.tar.bz2 |
[ARC] Allow non-instruction relocations within .text sections
bfd/
2016-03-08 Cupertino Miranda <Cupertino.Miranda@synopsys.com>
Andrew Burgess <andrew.burgess@embecosm.com>
* 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 <andrew.burgess@embecosm.com>
* testsuite/gas/arc/inline-data-1.d: New file.
* testsuite/gas/arc/inline-data-1.s: New file.
include/
2016-03-08 Cupertino Miranda <Cupertino.Miranda@synopsys.com>
Andrew Burgess <andrew.burgess@embecosm.com>
* elf/arc-reloc.def: Add a call to ME within the formula for each
relocation that requires middle-endian correction.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 15 | ||||
-rw-r--r-- | bfd/elf32-arc.c | 84 |
2 files changed, 54 insertions, 45 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8c2da68..2b6cf15 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2016-03-08 Cupertino Miranda <Cupertino.Miranda@synopsys.com> + Andrew Burgess <andrew.burgess@embecosm.com> + + * 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 <nickc@redhat.com> PR binutils/19775 diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index ab2512d..4090b7a 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; |