[ARM] Purecode compatible long branch veneer for M-profile targets with MOVW.
2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com> * elf32-arm.c (THUMB32_MOVT): New veneer macro. (THUMB32_MOVW): Likewise. (elf32_arm_stub_long_branch_thumb2_only_pure): New. (DEF_STUBS): Define long_branch_thumb2_only_pure. (arm_stub_is_thumb): Add new veneer stub. (arm_type_of_stub): Use new veneer. (arm_stub_required_alignment): Add new veneer. 2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com> * testsuite/ld-arm/farcall-thumb2-purecode.d: New test result. * testsuite/ld-arm/farcall-thumb2-purecode.s: New test. * testsuite/ld-arm/arm-elf.exp: Run it.
This commit is contained in:
parent
f0728ee368
commit
d5a67c0290
6 changed files with 127 additions and 6 deletions
|
@ -1,3 +1,13 @@
|
|||
2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com>
|
||||
|
||||
* elf32-arm.c (THUMB32_MOVT): New veneer macro.
|
||||
(THUMB32_MOVW): Likewise.
|
||||
(elf32_arm_stub_long_branch_thumb2_only_pure): New.
|
||||
(DEF_STUBS): Define long_branch_thumb2_only_pure.
|
||||
(arm_stub_is_thumb): Add new veneer stub.
|
||||
(arm_type_of_stub): Use new veneer.
|
||||
(arm_stub_required_alignment): Add new veneer.
|
||||
|
||||
2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com>
|
||||
|
||||
* bfd-in2.h (SEC_ELF_NOREAD): Rename to ...
|
||||
|
|
|
@ -2360,6 +2360,8 @@ enum stub_insn_type
|
|||
is inserted in arm_build_one_stub(). */
|
||||
#define THUMB16_BCOND_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 1}
|
||||
#define THUMB32_INSN(X) {(X), THUMB32_TYPE, R_ARM_NONE, 0}
|
||||
#define THUMB32_MOVT(X) {(X), THUMB32_TYPE, R_ARM_THM_MOVT_ABS, 0}
|
||||
#define THUMB32_MOVW(X) {(X), THUMB32_TYPE, R_ARM_THM_MOVW_ABS_NC, 0}
|
||||
#define THUMB32_B_INSN(X, Z) {(X), THUMB32_TYPE, R_ARM_THM_JUMP24, (Z)}
|
||||
#define ARM_INSN(X) {(X), ARM_TYPE, R_ARM_NONE, 0}
|
||||
#define ARM_REL_INSN(X, Z) {(X), ARM_TYPE, R_ARM_JUMP24, (Z)}
|
||||
|
@ -2409,6 +2411,15 @@ static const insn_sequence elf32_arm_stub_long_branch_thumb2_only[] =
|
|||
DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(x) */
|
||||
};
|
||||
|
||||
/* Thumb -> Thumb long branch stub. Used for PureCode sections on Thumb2
|
||||
M-profile architectures. */
|
||||
static const insn_sequence elf32_arm_stub_long_branch_thumb2_only_pure[] =
|
||||
{
|
||||
THUMB32_MOVW (0xf2400c00), /* mov.w ip, R_ARM_MOVW_ABS_NC */
|
||||
THUMB32_MOVT (0xf2c00c00), /* movt ip, R_ARM_MOVT_ABS << 16 */
|
||||
THUMB16_INSN (0x4760), /* bx ip */
|
||||
};
|
||||
|
||||
/* V4T Thumb -> Thumb long branch stub. Using the stack is not
|
||||
allowed. */
|
||||
static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb[] =
|
||||
|
@ -2634,6 +2645,7 @@ static const insn_sequence elf32_arm_stub_a8_veneer_blx[] =
|
|||
DEF_STUB(a8_veneer_bl) \
|
||||
DEF_STUB(a8_veneer_blx) \
|
||||
DEF_STUB(long_branch_thumb2_only) \
|
||||
DEF_STUB(long_branch_thumb2_only_pure)
|
||||
|
||||
#define DEF_STUB(x) arm_stub_##x,
|
||||
enum elf32_arm_stub_type
|
||||
|
@ -3808,6 +3820,7 @@ arm_stub_is_thumb (enum elf32_arm_stub_type stub_type)
|
|||
{
|
||||
case arm_stub_long_branch_thumb_only:
|
||||
case arm_stub_long_branch_thumb2_only:
|
||||
case arm_stub_long_branch_thumb2_only_pure:
|
||||
case arm_stub_long_branch_v4t_thumb_arm:
|
||||
case arm_stub_short_branch_v4t_thumb_arm:
|
||||
case arm_stub_long_branch_v4t_thumb_arm_pic:
|
||||
|
@ -3847,6 +3860,8 @@ arm_type_of_stub (struct bfd_link_info *info,
|
|||
enum arm_st_branch_type branch_type = *actual_branch_type;
|
||||
union gotplt_union *root_plt;
|
||||
struct arm_plt_info *arm_plt;
|
||||
int arch;
|
||||
int thumb2_movw;
|
||||
|
||||
if (branch_type == ST_BRANCH_LONG)
|
||||
return stub_type;
|
||||
|
@ -3859,6 +3874,11 @@ arm_type_of_stub (struct bfd_link_info *info,
|
|||
thumb2 = using_thumb2 (globals);
|
||||
thumb2_bl = using_thumb2_bl (globals);
|
||||
|
||||
arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
|
||||
|
||||
/* True for architectures that implement the thumb2 movw instruction. */
|
||||
thumb2_movw = thumb2 || (arch == TAG_CPU_ARCH_V8M_BASE);
|
||||
|
||||
/* Determine where the call point is. */
|
||||
location = (input_sec->output_offset
|
||||
+ input_sec->output_section->vma
|
||||
|
@ -3945,6 +3965,15 @@ arm_type_of_stub (struct bfd_link_info *info,
|
|||
/* Thumb to thumb. */
|
||||
if (!thumb_only)
|
||||
{
|
||||
if (input_sec->flags & SEC_ELF_PURECODE)
|
||||
(*_bfd_error_handler) (_("%B(%s): warning: long branch "
|
||||
" veneers used in section with "
|
||||
"SHF_ARM_PURECODE section "
|
||||
"attribute is only supported"
|
||||
" for M-profile targets that "
|
||||
"implement the movw "
|
||||
"instruction."));
|
||||
|
||||
stub_type = (bfd_link_pic (info) | globals->pic_veneer)
|
||||
/* PIC stubs. */
|
||||
? ((globals->use_blx
|
||||
|
@ -3967,16 +3996,39 @@ arm_type_of_stub (struct bfd_link_info *info,
|
|||
}
|
||||
else
|
||||
{
|
||||
stub_type = (bfd_link_pic (info) | globals->pic_veneer)
|
||||
/* PIC stub. */
|
||||
? arm_stub_long_branch_thumb_only_pic
|
||||
/* non-PIC stub. */
|
||||
: (thumb2 ? arm_stub_long_branch_thumb2_only
|
||||
: arm_stub_long_branch_thumb_only);
|
||||
if (thumb2_movw && (input_sec->flags & SEC_ELF_PURECODE))
|
||||
stub_type = arm_stub_long_branch_thumb2_only_pure;
|
||||
else
|
||||
{
|
||||
if (input_sec->flags & SEC_ELF_PURECODE)
|
||||
(*_bfd_error_handler) (_("%B(%s): warning: long branch "
|
||||
" veneers used in section with "
|
||||
"SHF_ARM_PURECODE section "
|
||||
"attribute is only supported"
|
||||
" for M-profile targets that "
|
||||
"implement the movw "
|
||||
"instruction."));
|
||||
|
||||
stub_type = (bfd_link_pic (info) | globals->pic_veneer)
|
||||
/* PIC stub. */
|
||||
? arm_stub_long_branch_thumb_only_pic
|
||||
/* non-PIC stub. */
|
||||
: (thumb2 ? arm_stub_long_branch_thumb2_only
|
||||
: arm_stub_long_branch_thumb_only);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (input_sec->flags & SEC_ELF_PURECODE)
|
||||
(*_bfd_error_handler) (_("%B(%s): warning: long branch "
|
||||
" veneers used in section with "
|
||||
"SHF_ARM_PURECODE section "
|
||||
"attribute is only supported"
|
||||
" for M-profile targets that "
|
||||
"implement the movw "
|
||||
"instruction."));
|
||||
|
||||
/* Thumb to arm. */
|
||||
if (sym_sec != NULL
|
||||
&& sym_sec->owner != NULL
|
||||
|
@ -4021,6 +4073,14 @@ arm_type_of_stub (struct bfd_link_info *info,
|
|||
|| r_type == R_ARM_PLT32
|
||||
|| r_type == R_ARM_TLS_CALL)
|
||||
{
|
||||
if (input_sec->flags & SEC_ELF_PURECODE)
|
||||
(*_bfd_error_handler) (_("%B(%s): warning: long branch "
|
||||
" veneers used in section with "
|
||||
"SHF_ARM_PURECODE section "
|
||||
"attribute is only supported"
|
||||
" for M-profile targets that "
|
||||
"implement the movw "
|
||||
"instruction."));
|
||||
if (branch_type == ST_BRANCH_TO_THUMB)
|
||||
{
|
||||
/* Arm to thumb. */
|
||||
|
@ -4446,6 +4506,7 @@ arm_stub_required_alignment (enum elf32_arm_stub_type stub_type)
|
|||
case arm_stub_long_branch_v4t_arm_thumb:
|
||||
case arm_stub_long_branch_thumb_only:
|
||||
case arm_stub_long_branch_thumb2_only:
|
||||
case arm_stub_long_branch_thumb2_only_pure:
|
||||
case arm_stub_long_branch_v4t_thumb_thumb:
|
||||
case arm_stub_long_branch_v4t_thumb_arm:
|
||||
case arm_stub_short_branch_v4t_thumb_arm:
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com>
|
||||
|
||||
* testsuite/ld-arm/farcall-thumb2-purecode.d: New test result.
|
||||
* testsuite/ld-arm/farcall-thumb2-purecode.s: New test.
|
||||
* testsuite/ld-arm/arm-elf.exp: Run it.
|
||||
|
||||
2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com>
|
||||
|
||||
* testsuite/ld-arm/arm_noread.ld: Renamed to ...
|
||||
|
|
|
@ -505,6 +505,9 @@ set armeabitests_nonacl {
|
|||
{farcall-thumb-thumb-m-no-profile-a.s farcall-thumb-thumb-m-no-profile-b.s}
|
||||
{{objdump -d farcall-thumb-thumb-m-no-profile.d}}
|
||||
"farcall-thumb-thumb-m-no-profile"}
|
||||
{"Thumb2 purecode farcall" "-Ttext 0x1000 --section-start .foo=0x2001020" "" "" {farcall-thumb2-purecode.s}
|
||||
{{objdump -d farcall-thumb2-purecode.d}}
|
||||
"farcall-thumb2-purecode"}
|
||||
|
||||
{"Thumb-ARM farcall" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "" "-W" {farcall-thumb-arm.s}
|
||||
{{objdump -d farcall-thumb-arm.d}}
|
||||
|
|
22
ld/testsuite/ld-arm/farcall-thumb2-purecode.d
Normal file
22
ld/testsuite/ld-arm/farcall-thumb2-purecode.d
Normal file
|
@ -0,0 +1,22 @@
|
|||
.*: file format .*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00001000 <bar>:
|
||||
1000: 4770 bx lr
|
||||
|
||||
Disassembly of section .foo:
|
||||
|
||||
02001020 <_start>:
|
||||
2001020: f000 f802 bl 2001028 <__bar_veneer>
|
||||
2001024: 0000 movs r0, r0
|
||||
\.\.\.
|
||||
|
||||
02001028 <__bar_veneer>:
|
||||
2001028: f241 0c01 movw ip, #4097 ; 0x1001
|
||||
200102c: f2c0 0c00 movt ip, #0
|
||||
2001030: 4760 bx ip
|
||||
2001032: 0000 movs r0, r0
|
||||
2001034: 0000 movs r0, r0
|
||||
\.\.\.
|
||||
|
19
ld/testsuite/ld-arm/farcall-thumb2-purecode.s
Normal file
19
ld/testsuite/ld-arm/farcall-thumb2-purecode.s
Normal file
|
@ -0,0 +1,19 @@
|
|||
@ Test to ensure that a purecode Thumb2 call exceeding 4Mb generates a stub.
|
||||
|
||||
.global _start
|
||||
.syntax unified
|
||||
.arch armv7-m
|
||||
.thumb
|
||||
.thumb_func
|
||||
|
||||
@ We will place the section .text at 0x1000.
|
||||
|
||||
.text
|
||||
bar:
|
||||
bx lr
|
||||
|
||||
@ We will place the section .foo at 0x02001014.
|
||||
|
||||
.section .foo, "0x20000006"
|
||||
_start:
|
||||
bl bar
|
Loading…
Reference in a new issue