[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.
This commit is contained in:
Andre Vieira
2019-04-15 11:37:51 +01:00
parent f1c7f42126
commit 1caf72a584
13 changed files with 154 additions and 1 deletions

View File

@ -1,3 +1,13 @@
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> 2019-04-15 Sudakshina Das <sudi.das@arm.com>
* reloc.c (BFD_RELOC_ARM_THUMB_BF17): New enum. * reloc.c (BFD_RELOC_ARM_THUMB_BF17): New enum.

View File

@ -3570,6 +3570,9 @@ field in the instruction. */
/* ARM 17-bit pc-relative branch for Branch Future instructions. */ /* ARM 17-bit pc-relative branch for Branch Future instructions. */
BFD_RELOC_ARM_THUMB_BF17, 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. /* 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. 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 Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an

View File

@ -1756,6 +1756,20 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
0x001f0ffe, /* src_mask. */ 0x001f0ffe, /* src_mask. */
0x001f0ffe, /* dst_mask. */ 0x001f0ffe, /* dst_mask. */
TRUE), /* pcrel_offset. */ 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: */ /* 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_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_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} {BFD_RELOC_ARM_THUMB_BF17, R_ARM_THM_BF16},
{BFD_RELOC_ARM_THUMB_BF19, R_ARM_THM_BF18}
}; };
static reloc_howto_type * static reloc_howto_type *
@ -12969,6 +12984,51 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
return bfd_reloc_ok; 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: default:
return bfd_reloc_notsupported; return bfd_reloc_notsupported;
} }

View File

@ -1531,6 +1531,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ARM_PCREL_JUMP", "BFD_RELOC_ARM_PCREL_JUMP",
"BFD_RELOC_THUMB_PCREL_BRANCH5", "BFD_RELOC_THUMB_PCREL_BRANCH5",
"BFD_RELOC_ARM_THUMB_BF17", "BFD_RELOC_ARM_THUMB_BF17",
"BFD_RELOC_ARM_THUMB_BF19",
"BFD_RELOC_THUMB_PCREL_BRANCH7", "BFD_RELOC_THUMB_PCREL_BRANCH7",
"BFD_RELOC_THUMB_PCREL_BRANCH9", "BFD_RELOC_THUMB_PCREL_BRANCH9",
"BFD_RELOC_THUMB_PCREL_BRANCH12", "BFD_RELOC_THUMB_PCREL_BRANCH12",

View File

@ -3024,6 +3024,11 @@ ENUM
ENUMDOC ENUMDOC
ARM 17-bit pc-relative branch for Branch Future instructions. 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 ENUM
BFD_RELOC_THUMB_PCREL_BRANCH7 BFD_RELOC_THUMB_PCREL_BRANCH7
ENUMX ENUMX

View File

@ -1,3 +1,7 @@
2019-04-15 Sudakshina Das <sudi.das@arm.com>
* arm.h (R_ARM_THM_BF18): New relocation code.
2019-04-15 Sudakshina Das <sudi.das@arm.com> 2019-04-15 Sudakshina Das <sudi.das@arm.com>
* arm.h (R_ARM_THM_BF16): New relocation code. * arm.h (R_ARM_THM_BF16): New relocation code.

View File

@ -197,6 +197,7 @@ enum
// 131 - 135 Unallocated // 131 - 135 Unallocated
// Relocations for Armv8.1-M Mainline (BF/BFL) // Relocations for Armv8.1-M Mainline (BF/BFL)
R_ARM_THM_BF16 = 136, // Static Thumb32 ((S + A) | T) P R_ARM_THM_BF16 = 136, // Static Thumb32 ((S + A) | T) P
R_ARM_THM_BF18 = 138, // Static Thumb32 ((S + A) | T) P
// 139 Unallocated // 139 Unallocated
// 140 - 159 Dynamic Reserved for future allocation // 140 - 159 Dynamic Reserved for future allocation
R_ARM_IRELATIVE = 160, // Dynamic R_ARM_IRELATIVE = 160, // Dynamic

View File

@ -1,3 +1,10 @@
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.
2019-04-15 Sudakshina Das <sudi.das@arm.com> 2019-04-15 Sudakshina Das <sudi.das@arm.com>
* config/tc-arm.c (T16_32_TAB): New entries for bfx and bflx. * config/tc-arm.c (T16_32_TAB): New entries for bfx and bflx.

View File

@ -22924,6 +22924,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
case BFD_RELOC_THUMB_PCREL_BRANCH20: case BFD_RELOC_THUMB_PCREL_BRANCH20:
case BFD_RELOC_THUMB_PCREL_BRANCH25: case BFD_RELOC_THUMB_PCREL_BRANCH25:
case BFD_RELOC_ARM_THUMB_BF17: case BFD_RELOC_ARM_THUMB_BF17:
case BFD_RELOC_ARM_THUMB_BF19:
return base + 4; return base + 4;
case BFD_RELOC_THUMB_PCREL_BRANCH23: case BFD_RELOC_THUMB_PCREL_BRANCH23:
@ -24854,6 +24855,39 @@ md_apply_fix (fixS * fixP,
} }
break; break;
case BFD_RELOC_ARM_THUMB_BF19:
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 19 bits wide. */
fixP->fx_done = 0;
}
if (v8_1_branch_value_check (value, 19, 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 & 0x0007f000) >> 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: case BFD_RELOC_ARM_V4BX:
/* This will need to go in the object file. */ /* This will need to go in the object file. */
fixP->fx_done = 0; fixP->fx_done = 0;
@ -25037,6 +25071,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
case BFD_RELOC_ARM_GOTOFFFUNCDESC: case BFD_RELOC_ARM_GOTOFFFUNCDESC:
case BFD_RELOC_ARM_FUNCDESC: case BFD_RELOC_ARM_FUNCDESC:
case BFD_RELOC_ARM_THUMB_BF17: case BFD_RELOC_ARM_THUMB_BF17:
case BFD_RELOC_ARM_THUMB_BF19:
code = fixp->fx_r_type; code = fixp->fx_r_type;
break; break;

View File

@ -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_BF18.
2019-04-15 Sudakshina Das <sudi.das@arm.com> 2019-04-15 Sudakshina Das <sudi.das@arm.com>
* elf/arm.h (START_RELOC_NUMBERS): New entry for R_ARM_THM_BF16. * elf/arm.h (START_RELOC_NUMBERS): New entry for R_ARM_THM_BF16.

View File

@ -242,6 +242,7 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G2_NC,134) 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_ALU_ABS_G3_NC,135)
RELOC_NUMBER (R_ARM_THM_BF16, 136) RELOC_NUMBER (R_ARM_THM_BF16, 136)
RELOC_NUMBER (R_ARM_THM_BF18, 138)
RELOC_NUMBER (R_ARM_IRELATIVE, 160) RELOC_NUMBER (R_ARM_IRELATIVE, 160)
RELOC_NUMBER (R_ARM_GOTFUNCDESC, 161) RELOC_NUMBER (R_ARM_GOTFUNCDESC, 161)

View File

@ -1,3 +1,7 @@
2019-04-15 Sudakshina Das <sudi.das@arm.com>
* arm-dis.c (print_insn_thumb32): Updated to accept new %Y pattern.
2019-04-15 Sudakshina Das <sudi.das@arm.com> 2019-04-15 Sudakshina Das <sudi.das@arm.com>
* arm-dis.c (print_insn_thumb32): Add '%<bitfield>S' to print an * arm-dis.c (print_insn_thumb32): Add '%<bitfield>S' to print an

View File

@ -2715,6 +2715,7 @@ static const struct opcode16 thumb_opcodes[] =
%F print the lsb and width fields of a sbfx/ubfx instruction %F print the lsb and width fields of a sbfx/ubfx instruction
%G print a fallback offset for Branch Future instructions %G print a fallback offset for Branch Future instructions
%W print an offset for BF instruction %W print an offset for BF instruction
%Y print an offset for BFL instruction
%b print a conditional branch offset %b print a conditional branch offset
%B print an unconditional branch offset %B print an unconditional branch offset
%s print the shift field of an SSAT instruction %s print the shift field of an SSAT instruction
@ -5898,6 +5899,23 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
} }
break; break;
case 'Y':
{
unsigned int immA = (given & 0x007f0000u) >> 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 & 0x40000) ? offset - (1 << 19) : offset;
info->print_address_func (pc + 4 + offset, info);
}
break;
case 'b': case 'b':
{ {
unsigned int S = (given & 0x04000000u) >> 26; unsigned int S = (given & 0x04000000u) >> 26;