diff options
author | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2019-04-15 11:37:51 +0100 |
---|---|---|
committer | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2019-04-15 12:30:33 +0100 |
commit | 1caf72a5849abf9a717ed3e0232abf591ff933e7 (patch) | |
tree | 195d651a5012a54933d6cb2d1793ebc659db4fc8 /bfd | |
parent | f1c7f42126274d48f6b0a929e4e15a32193997c6 (diff) | |
download | gdb-1caf72a5849abf9a717ed3e0232abf591ff933e7.zip gdb-1caf72a5849abf9a717ed3e0232abf591ff933e7.tar.gz gdb-1caf72a5849abf9a717ed3e0232abf591ff933e7.tar.bz2 |
[binutils, ARM, 8/16] BFL infrastructure with new global reloc R_ARM_THM_BF18
This patch is part of a series of patches to add support for Armv8.1-M Mainline instructions to binutils.
This adds infrastructure for the BFL instructions which is one of the first instructions in Arm that have more than one relocations in them.
This adds a new relocation R_ARM_THM_BF18.
The inconsistency between external R_ARM_THM_BF18 and internal
BFD_RELOC_ARM_THUMB_BF19 is because internally we count the static bit-0 of the immediate and we don't externally.
ChangeLog entries are as follows :
*** bfd/ChangeLog ***
2019-04-15 Sudakshina Das <sudi.das@arm.com>
* reloc.c (BFD_RELOC_ARM_THUMB_BF19): New
* libbfd.h: Regenerated.
* bfd-in2.h: Regenerated.
* bfd-elf32-arm.c (elf32_arm_howto_table_1): New entry for R_ARM_THM_BF18.
(elf32_arm_reloc_map elf32_arm_reloc_map): Map BFD_RELOC_ARM_THUMB_BF19
and R_ARM_THM_BF18 together.
(elf32_arm_final_link_relocate): New switch case for R_ARM_THM_BF19.
*** elfcpp/ChangeLog ***
2019-04-15 Sudakshina Das <sudi.das@arm.com>
* arm.h (R_ARM_THM_BF18): New relocation code.
*** gas/ChangeLog ***
2019-04-15 Sudakshina Das <sudi.das@arm.com>
* config/tc-arm.c (md_pcrel_from_section): New switch case for
BFD_RELOC_ARM_THUMB_BF19.
(md_appdy_fix): Likewise.
(tc_gen_reloc): Likewise.
*** include/ChangeLog ***
2019-04-15 Sudakshina Das <sudi.das@arm.com>
* elf/arm.h (START_RELOC_NUMBERS): New entry for R_ARM_THM_BF18.
*** opcodes/ChangeLog ***
2019-04-15 Sudakshina Das <sudi.das@arm.com>
* arm-dis.c (print_insn_thumb32): Updated to accept new %Y pattern.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 3 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 62 | ||||
-rw-r--r-- | bfd/libbfd.h | 1 | ||||
-rw-r--r-- | bfd/reloc.c | 5 |
5 files changed, 80 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 992e570..59bb64d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,15 @@ 2019-04-15 Sudakshina Das <sudi.das@arm.com> + * reloc.c (BFD_RELOC_ARM_THUMB_BF19): New + * libbfd.h: Regenerated. + * bfd-in2.h: Regenerated. + * bfd-elf32-arm.c (elf32_arm_howto_table_1): New entry for R_ARM_THM_BF18. + (elf32_arm_reloc_map elf32_arm_reloc_map): Map BFD_RELOC_ARM_THUMB_BF19 + and R_ARM_THM_BF18 together. + (elf32_arm_final_link_relocate): New switch case for R_ARM_THM_BF19. + +2019-04-15 Sudakshina Das <sudi.das@arm.com> + * reloc.c (BFD_RELOC_ARM_THUMB_BF17): New enum. * bfd-in2.h: Regenerated. * libbfd.h: Regenerated. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index b5922ff..99b0db4 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -3570,6 +3570,9 @@ field in the instruction. */ /* ARM 17-bit pc-relative branch for Branch Future instructions. */ BFD_RELOC_ARM_THUMB_BF17, +/* ARM 19-bit pc-relative branch for Branch Future Link instruction. */ + BFD_RELOC_ARM_THUMB_BF19, + /* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. The lowest bit must be zero and is not stored in the instruction. Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 2a209da..456dc9d 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -1756,6 +1756,20 @@ static reloc_howto_type elf32_arm_howto_table_1[] = 0x001f0ffe, /* src_mask. */ 0x001f0ffe, /* dst_mask. */ TRUE), /* pcrel_offset. */ + EMPTY_HOWTO (137), + HOWTO (R_ARM_THM_BF18, /* type. */ + 0, /* rightshift. */ + 1, /* size (0 = byte, 1 = short, 2 = long). */ + 18, /* bitsize. */ + TRUE, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_dont,/* do not complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_ARM_THM_BF18", /* name. */ + FALSE, /* partial_inplace. */ + 0x007f0ffe, /* src_mask. */ + 0x007f0ffe, /* dst_mask. */ + TRUE), /* pcrel_offset. */ }; /* 160 onwards: */ @@ -2068,7 +2082,8 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] = {BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC, R_ARM_THM_ALU_ABS_G2_NC}, {BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC, R_ARM_THM_ALU_ABS_G1_NC}, {BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC}, - {BFD_RELOC_ARM_THUMB_BF17, R_ARM_THM_BF16} + {BFD_RELOC_ARM_THUMB_BF17, R_ARM_THM_BF16}, + {BFD_RELOC_ARM_THUMB_BF19, R_ARM_THM_BF18} }; static reloc_howto_type * @@ -12969,6 +12984,51 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, return bfd_reloc_ok; } + case R_ARM_THM_BF18: + { + bfd_vma relocation; + bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data); + bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2); + + if (globals->use_rel) + { + bfd_vma immA = (upper_insn & 0x007f); + bfd_vma immB = (lower_insn & 0x07fe) >> 1; + bfd_vma immC = (lower_insn & 0x0800) >> 11; + addend = (immA << 12); + addend |= (immB << 2); + addend |= (immC << 1); + addend |= 1; + /* Sign extend. */ + addend = (addend & 0x40000) ? addend - (1 << 19) : addend; + } + + value = get_value_helper (plt_offset, splt, input_section, sym_sec, h, + info, input_bfd, rel, sym_name, st_type, + globals, unresolved_reloc_p); + + relocation = value + addend; + relocation -= (input_section->output_section->vma + + input_section->output_offset + + rel->r_offset); + + /* Put RELOCATION back into the insn. */ + { + bfd_vma immA = (relocation & 0x0007f000) >> 12; + bfd_vma immB = (relocation & 0x00000ffc) >> 2; + bfd_vma immC = (relocation & 0x00000002) >> 1; + + upper_insn = (upper_insn & 0xff80) | immA; + lower_insn = (lower_insn & 0xf001) | (immC << 11) | (immB << 1); + } + + /* Put the relocated value back in the object file: */ + bfd_put_16 (input_bfd, upper_insn, hit_data); + bfd_put_16 (input_bfd, lower_insn, hit_data + 2); + + return bfd_reloc_ok; + } + default: return bfd_reloc_notsupported; } diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 4a3fa14..7f775ac 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1531,6 +1531,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_PCREL_JUMP", "BFD_RELOC_THUMB_PCREL_BRANCH5", "BFD_RELOC_ARM_THUMB_BF17", + "BFD_RELOC_ARM_THUMB_BF19", "BFD_RELOC_THUMB_PCREL_BRANCH7", "BFD_RELOC_THUMB_PCREL_BRANCH9", "BFD_RELOC_THUMB_PCREL_BRANCH12", diff --git a/bfd/reloc.c b/bfd/reloc.c index b351d12..9e3899a 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -3025,6 +3025,11 @@ ENUMDOC ARM 17-bit pc-relative branch for Branch Future instructions. ENUM + BFD_RELOC_ARM_THUMB_BF19 +ENUMDOC + ARM 19-bit pc-relative branch for Branch Future Link instruction. + +ENUM BFD_RELOC_THUMB_PCREL_BRANCH7 ENUMX BFD_RELOC_THUMB_PCREL_BRANCH9 |