aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/elf32-arm.c115
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c5
-rw-r--r--elfcpp/ChangeLog4
-rw-r--r--elfcpp/arm.h5
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-arm.c35
-rw-r--r--include/ChangeLog4
-rw-r--r--include/elf/arm.h1
-rw-r--r--opcodes/ChangeLog4
-rw-r--r--opcodes/arm-dis.c18
13 files changed, 211 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index bbb251a..992e570 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,16 @@
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.
+ * bfd-elf32-arm.c (elf32_arm_howto_table_1): New entry for R_ARM_THM_BF16.
+ (elf32_arm_reloc_map elf32_arm_reloc_map): Map BFD_RELOC_ARM_THUMB_BF17
+ and R_ARM_THM_BF16 together.
+ (get_value_helper): New reloc helper.
+ (elf32_arm_final_link_relocate): New switch case for R_ARM_THM_BF16.
+
+2019-04-15 Sudakshina Das <sudi.das@arm.com>
+
* reloc.c (BFD_RELOC_THUMB_PCREL_BRANCH5): New enum.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 3493d4f..b5922ff 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -3567,6 +3567,9 @@ field in the instruction. */
/* ARM 5-bit pc-relative branch for Branch Future instructions. */
BFD_RELOC_THUMB_PCREL_BRANCH5,
+/* ARM 17-bit pc-relative branch for Branch Future instructions. */
+ BFD_RELOC_ARM_THUMB_BF17,
+
/* 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 23bfbcb..2a209da 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -1742,6 +1742,20 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
0x00000000, /* src_mask. */
0x00000000, /* dst_mask. */
FALSE), /* pcrel_offset. */
+ /* Relocations for Armv8.1-M Mainline. */
+ HOWTO (R_ARM_THM_BF16, /* type. */
+ 0, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 16, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont,/* do not complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_ARM_THM_BF16", /* name. */
+ FALSE, /* partial_inplace. */
+ 0x001f0ffe, /* src_mask. */
+ 0x001f0ffe, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
};
/* 160 onwards: */
@@ -2053,7 +2067,8 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
{BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC, R_ARM_THM_ALU_ABS_G3_NC},
{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_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC},
+ {BFD_RELOC_ARM_THUMB_BF17, R_ARM_THM_BF16}
};
static reloc_howto_type *
@@ -10250,6 +10265,59 @@ identify_add_or_sub (bfd_vma insn)
return 0;
}
+/* Helper function to compute the Addend for Armv8.1-M Mainline relocations. */
+static bfd_vma
+get_value_helper (bfd_vma plt_offset,
+ asection *splt,
+ asection *input_section,
+ asection *sym_sec,
+ struct elf_link_hash_entry * h,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ Elf_Internal_Rela *rel,
+ const char *sym_name,
+ unsigned char st_type,
+ struct elf32_arm_link_hash_table *globals,
+ bfd_boolean *unresolved_reloc_p)
+{
+ bfd_vma value = 0;
+ enum arm_st_branch_type branch_type;
+ enum elf32_arm_stub_type stub_type = arm_stub_none;
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ struct elf32_arm_link_hash_entry *hash
+ = (struct elf32_arm_link_hash_entry *)h;
+
+
+ if (plt_offset != (bfd_vma) -1)
+ {
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + plt_offset);
+ value -= PLT_THUMB_STUB_SIZE;
+ *unresolved_reloc_p = FALSE;
+ }
+
+ stub_type = arm_type_of_stub (info, input_section, rel,
+ st_type, &branch_type,
+ hash, value, sym_sec,
+ input_bfd, sym_name);
+
+ if (stub_type != arm_stub_none)
+ {
+ stub_entry = elf32_arm_get_stub_entry (input_section,
+ sym_sec, h,
+ rel, globals,
+ stub_type);
+ if (stub_entry != NULL)
+ {
+ value = (stub_entry->stub_offset
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+ }
+ }
+ return value;
+}
+
/* Perform a relocation as part of a final link. */
static bfd_reloc_status_type
@@ -12856,6 +12924,51 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
*unresolved_reloc_p = FALSE;
return bfd_reloc_ok;
+ case R_ARM_THM_BF16:
+ {
+ 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 & 0x001f);
+ 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 & 0x10000) ? addend - (1 << 17) : 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 & 0x0001f000) >> 12;
+ bfd_vma immB = (relocation & 0x00000ffc) >> 2;
+ bfd_vma immC = (relocation & 0x00000002) >> 1;
+
+ upper_insn = (upper_insn & 0xffe0) | 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 02daa29..4a3fa14 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1530,6 +1530,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ARM_PCREL_CALL",
"BFD_RELOC_ARM_PCREL_JUMP",
"BFD_RELOC_THUMB_PCREL_BRANCH5",
+ "BFD_RELOC_ARM_THUMB_BF17",
"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 a071dc7..b351d12 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -3020,6 +3020,11 @@ ENUMDOC
ARM 5-bit pc-relative branch for Branch Future instructions.
ENUM
+ BFD_RELOC_ARM_THUMB_BF17
+ENUMDOC
+ ARM 17-bit pc-relative branch for Branch Future instructions.
+
+ENUM
BFD_RELOC_THUMB_PCREL_BRANCH7
ENUMX
BFD_RELOC_THUMB_PCREL_BRANCH9
diff --git a/elfcpp/ChangeLog b/elfcpp/ChangeLog
index eb1baa9..7770f7e 100644
--- a/elfcpp/ChangeLog
+++ b/elfcpp/ChangeLog
@@ -1,3 +1,7 @@
+2019-04-15 Sudakshina Das <sudi.das@arm.com>
+
+ * arm.h (R_ARM_THM_BF16): New relocation code.
+
2018-06-24 Nick Clifton <nickc@redhat.com>
2.32 branch created.
diff --git a/elfcpp/arm.h b/elfcpp/arm.h
index fb5cc25..b4cd67f 100644
--- a/elfcpp/arm.h
+++ b/elfcpp/arm.h
@@ -194,7 +194,10 @@ enum
R_ARM_ME_TOO = 128, // Obsolete
R_ARM_THM_TLS_DESCSEQ16 = 129,// Static Thumb16
R_ARM_THM_TLS_DESCSEQ32 = 130,// Static Thumb32
- // 131 - 139 Unallocated
+ // 131 - 135 Unallocated
+ // Relocations for Armv8.1-M Mainline (BF/BFL)
+ R_ARM_THM_BF16 = 136, // Static Thumb32 ((S + A) | T) – P
+ // 139 Unallocated
// 140 - 159 Dynamic Reserved for future allocation
R_ARM_IRELATIVE = 160, // Dynamic
// 161 - 255 Unallocated
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d08dd00..156881b 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,12 @@
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_BF17.
+ (md_appdy_fix): Likewise.
+ (tc_gen_reloc): Likewise.
+
+2019-04-15 Sudakshina Das <sudi.das@arm.com>
+
* config/tc-arm.c (ARM_IT_MAX_RELOCS): New macro.
(arm_it): Member reloc renamed relocs and updated to an array.
Rest: Replace all occurrences of reloc to relocs[0].
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 14d114a..d3a21d6 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -22853,6 +22853,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
case BFD_RELOC_THUMB_PCREL_BRANCH12:
case BFD_RELOC_THUMB_PCREL_BRANCH20:
case BFD_RELOC_THUMB_PCREL_BRANCH25:
+ case BFD_RELOC_ARM_THUMB_BF17:
return base + 4;
case BFD_RELOC_THUMB_PCREL_BRANCH23:
@@ -24750,6 +24751,39 @@ md_apply_fix (fixS * fixP,
}
break;
+ case BFD_RELOC_ARM_THUMB_BF17:
+ if (fixP->fx_addsy
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
+ && ARM_IS_FUNC (fixP->fx_addsy)
+ && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
+ {
+ /* Force a relocation for a branch 17 bits wide. */
+ fixP->fx_done = 0;
+ }
+
+ if (v8_1_branch_value_check (value, 17, TRUE) == FAIL)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ BAD_BRANCH_OFF);
+
+ if (fixP->fx_done || !seg->use_rela_p)
+ {
+ offsetT newval2;
+ addressT immA, immB, immC;
+
+ immA = (value & 0x0001f000) >> 12;
+ immB = (value & 0x00000ffc) >> 2;
+ immC = (value & 0x00000002) >> 1;
+
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
+ newval |= immA;
+ newval2 |= (immC << 11) | (immB << 1);
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
+ }
+ break;
+
case BFD_RELOC_ARM_V4BX:
/* This will need to go in the object file. */
fixP->fx_done = 0;
@@ -24932,6 +24966,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
case BFD_RELOC_ARM_GOTFUNCDESC:
case BFD_RELOC_ARM_GOTOFFFUNCDESC:
case BFD_RELOC_ARM_FUNCDESC:
+ case BFD_RELOC_ARM_THUMB_BF17:
code = fixp->fx_r_type;
break;
diff --git a/include/ChangeLog b/include/ChangeLog
index d33d0b0..f60e7a3 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2019-04-15 Sudakshina Das <sudi.das@arm.com>
+
+ * elf/arm.h (START_RELOC_NUMBERS): New entry for R_ARM_THM_BF16.
+
2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
* elf/arm.h (TAG_CPU_ARCH_V8_1M_MAIN): new macro.
diff --git a/include/elf/arm.h b/include/elf/arm.h
index daf1d94..2c6d4ef 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -241,6 +241,7 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G1_NC,133)
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G2_NC,134)
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G3_NC,135)
+ RELOC_NUMBER (R_ARM_THM_BF16, 136)
RELOC_NUMBER (R_ARM_IRELATIVE, 160)
RELOC_NUMBER (R_ARM_GOTFUNCDESC, 161)
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index fc9697b..fedc7ce 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,9 @@
2019-04-15 Sudakshina Das <sudi.das@arm.com>
+ * arm-dis.c (print_insn_thumb32): Updated to accept new %W pattern.
+
+2019-04-15 Sudakshina Das <sudi.das@arm.com>
+
* arm-dis.c (print_insn_thumb32): Updated to accept new %G pattern.
2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 0ed893b..4a5609a 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -2714,6 +2714,7 @@ static const struct opcode16 thumb_opcodes[] =
%E print the lsb and width fields of a bfc/bfi instruction
%F print the lsb and width fields of a sbfx/ubfx instruction
%G print a fallback offset for Branch Future instructions
+ %W print an offset for BF instruction
%b print a conditional branch offset
%B print an unconditional branch offset
%s print the shift field of an SSAT instruction
@@ -5870,6 +5871,23 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
}
break;
+ case 'W':
+ {
+ unsigned int immA = (given & 0x001f0000u) >> 16;
+ unsigned int immB = (given & 0x000007feu) >> 1;
+ unsigned int immC = (given & 0x00000800u) >> 11;
+ bfd_vma offset = 0;
+
+ offset |= immA << 12;
+ offset |= immB << 2;
+ offset |= immC << 1;
+ /* Sign extend. */
+ offset = (offset & 0x10000) ? offset - (1 << 17) : offset;
+
+ info->print_address_func (pc + 4 + offset, info);
+ }
+ break;
+
case 'b':
{
unsigned int S = (given & 0x04000000u) >> 26;