Skip to content

Commit 1caf72a

Browse files
committed
[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 <[email protected]> * 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 <[email protected]> * arm.h (R_ARM_THM_BF18): New relocation code. *** gas/ChangeLog *** 2019-04-15 Sudakshina Das <[email protected]> * 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 <[email protected]> * elf/arm.h (START_RELOC_NUMBERS): New entry for R_ARM_THM_BF18. *** opcodes/ChangeLog *** 2019-04-15 Sudakshina Das <[email protected]> * arm-dis.c (print_insn_thumb32): Updated to accept new %Y pattern.
1 parent f1c7f42 commit 1caf72a

File tree

13 files changed

+154
-1
lines changed

13 files changed

+154
-1
lines changed

bfd/ChangeLog

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2019-04-15 Sudakshina Das <[email protected]>
2+
3+
* reloc.c (BFD_RELOC_ARM_THUMB_BF19): New
4+
* libbfd.h: Regenerated.
5+
* bfd-in2.h: Regenerated.
6+
* bfd-elf32-arm.c (elf32_arm_howto_table_1): New entry for R_ARM_THM_BF18.
7+
(elf32_arm_reloc_map elf32_arm_reloc_map): Map BFD_RELOC_ARM_THUMB_BF19
8+
and R_ARM_THM_BF18 together.
9+
(elf32_arm_final_link_relocate): New switch case for R_ARM_THM_BF19.
10+
111
2019-04-15 Sudakshina Das <[email protected]>
212

313
* reloc.c (BFD_RELOC_ARM_THUMB_BF17): New enum.

bfd/bfd-in2.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3570,6 +3570,9 @@ field in the instruction. */
35703570
/* ARM 17-bit pc-relative branch for Branch Future instructions. */
35713571
BFD_RELOC_ARM_THUMB_BF17,
35723572

3573+
/* ARM 19-bit pc-relative branch for Branch Future Link instruction. */
3574+
BFD_RELOC_ARM_THUMB_BF19,
3575+
35733576
/* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches.
35743577
The lowest bit must be zero and is not stored in the instruction.
35753578
Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an

bfd/elf32-arm.c

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1756,6 +1756,20 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
17561756
0x001f0ffe, /* src_mask. */
17571757
0x001f0ffe, /* dst_mask. */
17581758
TRUE), /* pcrel_offset. */
1759+
EMPTY_HOWTO (137),
1760+
HOWTO (R_ARM_THM_BF18, /* type. */
1761+
0, /* rightshift. */
1762+
1, /* size (0 = byte, 1 = short, 2 = long). */
1763+
18, /* bitsize. */
1764+
TRUE, /* pc_relative. */
1765+
0, /* bitpos. */
1766+
complain_overflow_dont,/* do not complain_on_overflow. */
1767+
bfd_elf_generic_reloc, /* special_function. */
1768+
"R_ARM_THM_BF18", /* name. */
1769+
FALSE, /* partial_inplace. */
1770+
0x007f0ffe, /* src_mask. */
1771+
0x007f0ffe, /* dst_mask. */
1772+
TRUE), /* pcrel_offset. */
17591773
};
17601774

17611775
/* 160 onwards: */
@@ -2068,7 +2082,8 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
20682082
{BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC, R_ARM_THM_ALU_ABS_G2_NC},
20692083
{BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC, R_ARM_THM_ALU_ABS_G1_NC},
20702084
{BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC},
2071-
{BFD_RELOC_ARM_THUMB_BF17, R_ARM_THM_BF16}
2085+
{BFD_RELOC_ARM_THUMB_BF17, R_ARM_THM_BF16},
2086+
{BFD_RELOC_ARM_THUMB_BF19, R_ARM_THM_BF18}
20722087
};
20732088

20742089
static reloc_howto_type *
@@ -12969,6 +12984,51 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
1296912984
return bfd_reloc_ok;
1297012985
}
1297112986

12987+
case R_ARM_THM_BF18:
12988+
{
12989+
bfd_vma relocation;
12990+
bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
12991+
bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
12992+
12993+
if (globals->use_rel)
12994+
{
12995+
bfd_vma immA = (upper_insn & 0x007f);
12996+
bfd_vma immB = (lower_insn & 0x07fe) >> 1;
12997+
bfd_vma immC = (lower_insn & 0x0800) >> 11;
12998+
addend = (immA << 12);
12999+
addend |= (immB << 2);
13000+
addend |= (immC << 1);
13001+
addend |= 1;
13002+
/* Sign extend. */
13003+
addend = (addend & 0x40000) ? addend - (1 << 19) : addend;
13004+
}
13005+
13006+
value = get_value_helper (plt_offset, splt, input_section, sym_sec, h,
13007+
info, input_bfd, rel, sym_name, st_type,
13008+
globals, unresolved_reloc_p);
13009+
13010+
relocation = value + addend;
13011+
relocation -= (input_section->output_section->vma
13012+
+ input_section->output_offset
13013+
+ rel->r_offset);
13014+
13015+
/* Put RELOCATION back into the insn. */
13016+
{
13017+
bfd_vma immA = (relocation & 0x0007f000) >> 12;
13018+
bfd_vma immB = (relocation & 0x00000ffc) >> 2;
13019+
bfd_vma immC = (relocation & 0x00000002) >> 1;
13020+
13021+
upper_insn = (upper_insn & 0xff80) | immA;
13022+
lower_insn = (lower_insn & 0xf001) | (immC << 11) | (immB << 1);
13023+
}
13024+
13025+
/* Put the relocated value back in the object file: */
13026+
bfd_put_16 (input_bfd, upper_insn, hit_data);
13027+
bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
13028+
13029+
return bfd_reloc_ok;
13030+
}
13031+
1297213032
default:
1297313033
return bfd_reloc_notsupported;
1297413034
}

bfd/libbfd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
15311531
"BFD_RELOC_ARM_PCREL_JUMP",
15321532
"BFD_RELOC_THUMB_PCREL_BRANCH5",
15331533
"BFD_RELOC_ARM_THUMB_BF17",
1534+
"BFD_RELOC_ARM_THUMB_BF19",
15341535
"BFD_RELOC_THUMB_PCREL_BRANCH7",
15351536
"BFD_RELOC_THUMB_PCREL_BRANCH9",
15361537
"BFD_RELOC_THUMB_PCREL_BRANCH12",

bfd/reloc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,6 +3024,11 @@ ENUM
30243024
ENUMDOC
30253025
ARM 17-bit pc-relative branch for Branch Future instructions.
30263026
3027+
ENUM
3028+
BFD_RELOC_ARM_THUMB_BF19
3029+
ENUMDOC
3030+
ARM 19-bit pc-relative branch for Branch Future Link instruction.
3031+
30273032
ENUM
30283033
BFD_RELOC_THUMB_PCREL_BRANCH7
30293034
ENUMX

elfcpp/ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2019-04-15 Sudakshina Das <[email protected]>
2+
3+
* arm.h (R_ARM_THM_BF18): New relocation code.
4+
15
2019-04-15 Sudakshina Das <[email protected]>
26

37
* arm.h (R_ARM_THM_BF16): New relocation code.

elfcpp/arm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ enum
197197
// 131 - 135 Unallocated
198198
// Relocations for Armv8.1-M Mainline (BF/BFL)
199199
R_ARM_THM_BF16 = 136, // Static Thumb32 ((S + A) | T) – P
200+
R_ARM_THM_BF18 = 138, // Static Thumb32 ((S + A) | T) – P
200201
// 139 Unallocated
201202
// 140 - 159 Dynamic Reserved for future allocation
202203
R_ARM_IRELATIVE = 160, // Dynamic

gas/ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2019-04-15 Sudakshina Das <[email protected]>
2+
3+
* config/tc-arm.c (md_pcrel_from_section): New switch case for
4+
BFD_RELOC_ARM_THUMB_BF19.
5+
(md_appdy_fix): Likewise.
6+
(tc_gen_reloc): Likewise.
7+
18
2019-04-15 Sudakshina Das <[email protected]>
29

310
* config/tc-arm.c (T16_32_TAB): New entries for bfx and bflx.

gas/config/tc-arm.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22924,6 +22924,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
2292422924
case BFD_RELOC_THUMB_PCREL_BRANCH20:
2292522925
case BFD_RELOC_THUMB_PCREL_BRANCH25:
2292622926
case BFD_RELOC_ARM_THUMB_BF17:
22927+
case BFD_RELOC_ARM_THUMB_BF19:
2292722928
return base + 4;
2292822929

2292922930
case BFD_RELOC_THUMB_PCREL_BRANCH23:
@@ -24854,6 +24855,39 @@ md_apply_fix (fixS * fixP,
2485424855
}
2485524856
break;
2485624857

24858+
case BFD_RELOC_ARM_THUMB_BF19:
24859+
if (fixP->fx_addsy
24860+
&& (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24861+
&& !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
24862+
&& ARM_IS_FUNC (fixP->fx_addsy)
24863+
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
24864+
{
24865+
/* Force a relocation for a branch 19 bits wide. */
24866+
fixP->fx_done = 0;
24867+
}
24868+
24869+
if (v8_1_branch_value_check (value, 19, TRUE) == FAIL)
24870+
as_bad_where (fixP->fx_file, fixP->fx_line,
24871+
BAD_BRANCH_OFF);
24872+
24873+
if (fixP->fx_done || !seg->use_rela_p)
24874+
{
24875+
offsetT newval2;
24876+
addressT immA, immB, immC;
24877+
24878+
immA = (value & 0x0007f000) >> 12;
24879+
immB = (value & 0x00000ffc) >> 2;
24880+
immC = (value & 0x00000002) >> 1;
24881+
24882+
newval = md_chars_to_number (buf, THUMB_SIZE);
24883+
newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24884+
newval |= immA;
24885+
newval2 |= (immC << 11) | (immB << 1);
24886+
md_number_to_chars (buf, newval, THUMB_SIZE);
24887+
md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
24888+
}
24889+
break;
24890+
2485724891
case BFD_RELOC_ARM_V4BX:
2485824892
/* This will need to go in the object file. */
2485924893
fixP->fx_done = 0;
@@ -25037,6 +25071,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
2503725071
case BFD_RELOC_ARM_GOTOFFFUNCDESC:
2503825072
case BFD_RELOC_ARM_FUNCDESC:
2503925073
case BFD_RELOC_ARM_THUMB_BF17:
25074+
case BFD_RELOC_ARM_THUMB_BF19:
2504025075
code = fixp->fx_r_type;
2504125076
break;
2504225077

include/ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2019-04-15 Sudakshina Das <[email protected]>
2+
3+
* elf/arm.h (START_RELOC_NUMBERS): New entry for R_ARM_THM_BF18.
4+
15
2019-04-15 Sudakshina Das <[email protected]>
26

37
* elf/arm.h (START_RELOC_NUMBERS): New entry for R_ARM_THM_BF16.

include/elf/arm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
242242
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G2_NC,134)
243243
RELOC_NUMBER (R_ARM_THM_ALU_ABS_G3_NC,135)
244244
RELOC_NUMBER (R_ARM_THM_BF16, 136)
245+
RELOC_NUMBER (R_ARM_THM_BF18, 138)
245246

246247
RELOC_NUMBER (R_ARM_IRELATIVE, 160)
247248
RELOC_NUMBER (R_ARM_GOTFUNCDESC, 161)

opcodes/ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2019-04-15 Sudakshina Das <[email protected]>
2+
3+
* arm-dis.c (print_insn_thumb32): Updated to accept new %Y pattern.
4+
15
2019-04-15 Sudakshina Das <[email protected]>
26

37
* arm-dis.c (print_insn_thumb32): Add '%<bitfield>S' to print an

opcodes/arm-dis.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2715,6 +2715,7 @@ static const struct opcode16 thumb_opcodes[] =
27152715
%F print the lsb and width fields of a sbfx/ubfx instruction
27162716
%G print a fallback offset for Branch Future instructions
27172717
%W print an offset for BF instruction
2718+
%Y print an offset for BFL instruction
27182719
%b print a conditional branch offset
27192720
%B print an unconditional branch offset
27202721
%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)
58985899
}
58995900
break;
59005901

5902+
case 'Y':
5903+
{
5904+
unsigned int immA = (given & 0x007f0000u) >> 16;
5905+
unsigned int immB = (given & 0x000007feu) >> 1;
5906+
unsigned int immC = (given & 0x00000800u) >> 11;
5907+
bfd_vma offset = 0;
5908+
5909+
offset |= immA << 12;
5910+
offset |= immB << 2;
5911+
offset |= immC << 1;
5912+
/* Sign extend. */
5913+
offset = (offset & 0x40000) ? offset - (1 << 19) : offset;
5914+
5915+
info->print_address_func (pc + 4 + offset, info);
5916+
}
5917+
break;
5918+
59015919
case 'b':
59025920
{
59035921
unsigned int S = (given & 0x04000000u) >> 26;

0 commit comments

Comments
 (0)