GNU Binutils with patches for OS216
リビジョン | d5a67c02901c0abe946546f2b3b1a3b67a876136 (tree) |
---|---|
日時 | 2016-07-05 19:39:06 |
作者 | Andre Vieria <andre.simoesdiasvieira@arm....> |
コミッター | Richard Earnshaw |
[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.
@@ -1,5 +1,15 @@ | ||
1 | 1 | 2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com> |
2 | 2 | |
3 | + * elf32-arm.c (THUMB32_MOVT): New veneer macro. | |
4 | + (THUMB32_MOVW): Likewise. | |
5 | + (elf32_arm_stub_long_branch_thumb2_only_pure): New. | |
6 | + (DEF_STUBS): Define long_branch_thumb2_only_pure. | |
7 | + (arm_stub_is_thumb): Add new veneer stub. | |
8 | + (arm_type_of_stub): Use new veneer. | |
9 | + (arm_stub_required_alignment): Add new veneer. | |
10 | + | |
11 | +2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com> | |
12 | + | |
3 | 13 | * bfd-in2.h (SEC_ELF_NOREAD): Rename to ... |
4 | 14 | (SEC_ELF_PURECODE): ... this. |
5 | 15 | * elf32-arm.c (elf32_arm_post_process_headers): Rename SEC_ELF_NOREAD |
@@ -2360,6 +2360,8 @@ enum stub_insn_type | ||
2360 | 2360 | is inserted in arm_build_one_stub(). */ |
2361 | 2361 | #define THUMB16_BCOND_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 1} |
2362 | 2362 | #define THUMB32_INSN(X) {(X), THUMB32_TYPE, R_ARM_NONE, 0} |
2363 | +#define THUMB32_MOVT(X) {(X), THUMB32_TYPE, R_ARM_THM_MOVT_ABS, 0} | |
2364 | +#define THUMB32_MOVW(X) {(X), THUMB32_TYPE, R_ARM_THM_MOVW_ABS_NC, 0} | |
2363 | 2365 | #define THUMB32_B_INSN(X, Z) {(X), THUMB32_TYPE, R_ARM_THM_JUMP24, (Z)} |
2364 | 2366 | #define ARM_INSN(X) {(X), ARM_TYPE, R_ARM_NONE, 0} |
2365 | 2367 | #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[] = | ||
2409 | 2411 | DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(x) */ |
2410 | 2412 | }; |
2411 | 2413 | |
2414 | +/* Thumb -> Thumb long branch stub. Used for PureCode sections on Thumb2 | |
2415 | + M-profile architectures. */ | |
2416 | +static const insn_sequence elf32_arm_stub_long_branch_thumb2_only_pure[] = | |
2417 | +{ | |
2418 | + THUMB32_MOVW (0xf2400c00), /* mov.w ip, R_ARM_MOVW_ABS_NC */ | |
2419 | + THUMB32_MOVT (0xf2c00c00), /* movt ip, R_ARM_MOVT_ABS << 16 */ | |
2420 | + THUMB16_INSN (0x4760), /* bx ip */ | |
2421 | +}; | |
2422 | + | |
2412 | 2423 | /* V4T Thumb -> Thumb long branch stub. Using the stack is not |
2413 | 2424 | allowed. */ |
2414 | 2425 | 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[] = | ||
2634 | 2645 | DEF_STUB(a8_veneer_bl) \ |
2635 | 2646 | DEF_STUB(a8_veneer_blx) \ |
2636 | 2647 | DEF_STUB(long_branch_thumb2_only) \ |
2648 | + DEF_STUB(long_branch_thumb2_only_pure) | |
2637 | 2649 | |
2638 | 2650 | #define DEF_STUB(x) arm_stub_##x, |
2639 | 2651 | enum elf32_arm_stub_type |
@@ -3808,6 +3820,7 @@ arm_stub_is_thumb (enum elf32_arm_stub_type stub_type) | ||
3808 | 3820 | { |
3809 | 3821 | case arm_stub_long_branch_thumb_only: |
3810 | 3822 | case arm_stub_long_branch_thumb2_only: |
3823 | + case arm_stub_long_branch_thumb2_only_pure: | |
3811 | 3824 | case arm_stub_long_branch_v4t_thumb_arm: |
3812 | 3825 | case arm_stub_short_branch_v4t_thumb_arm: |
3813 | 3826 | case arm_stub_long_branch_v4t_thumb_arm_pic: |
@@ -3847,6 +3860,8 @@ arm_type_of_stub (struct bfd_link_info *info, | ||
3847 | 3860 | enum arm_st_branch_type branch_type = *actual_branch_type; |
3848 | 3861 | union gotplt_union *root_plt; |
3849 | 3862 | struct arm_plt_info *arm_plt; |
3863 | + int arch; | |
3864 | + int thumb2_movw; | |
3850 | 3865 | |
3851 | 3866 | if (branch_type == ST_BRANCH_LONG) |
3852 | 3867 | return stub_type; |
@@ -3859,6 +3874,11 @@ arm_type_of_stub (struct bfd_link_info *info, | ||
3859 | 3874 | thumb2 = using_thumb2 (globals); |
3860 | 3875 | thumb2_bl = using_thumb2_bl (globals); |
3861 | 3876 | |
3877 | + arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch); | |
3878 | + | |
3879 | + /* True for architectures that implement the thumb2 movw instruction. */ | |
3880 | + thumb2_movw = thumb2 || (arch == TAG_CPU_ARCH_V8M_BASE); | |
3881 | + | |
3862 | 3882 | /* Determine where the call point is. */ |
3863 | 3883 | location = (input_sec->output_offset |
3864 | 3884 | + input_sec->output_section->vma |
@@ -3945,6 +3965,15 @@ arm_type_of_stub (struct bfd_link_info *info, | ||
3945 | 3965 | /* Thumb to thumb. */ |
3946 | 3966 | if (!thumb_only) |
3947 | 3967 | { |
3968 | + if (input_sec->flags & SEC_ELF_PURECODE) | |
3969 | + (*_bfd_error_handler) (_("%B(%s): warning: long branch " | |
3970 | + " veneers used in section with " | |
3971 | + "SHF_ARM_PURECODE section " | |
3972 | + "attribute is only supported" | |
3973 | + " for M-profile targets that " | |
3974 | + "implement the movw " | |
3975 | + "instruction.")); | |
3976 | + | |
3948 | 3977 | stub_type = (bfd_link_pic (info) | globals->pic_veneer) |
3949 | 3978 | /* PIC stubs. */ |
3950 | 3979 | ? ((globals->use_blx |
@@ -3967,16 +3996,39 @@ arm_type_of_stub (struct bfd_link_info *info, | ||
3967 | 3996 | } |
3968 | 3997 | else |
3969 | 3998 | { |
3970 | - stub_type = (bfd_link_pic (info) | globals->pic_veneer) | |
3971 | - /* PIC stub. */ | |
3972 | - ? arm_stub_long_branch_thumb_only_pic | |
3973 | - /* non-PIC stub. */ | |
3974 | - : (thumb2 ? arm_stub_long_branch_thumb2_only | |
3975 | - : arm_stub_long_branch_thumb_only); | |
3999 | + if (thumb2_movw && (input_sec->flags & SEC_ELF_PURECODE)) | |
4000 | + stub_type = arm_stub_long_branch_thumb2_only_pure; | |
4001 | + else | |
4002 | + { | |
4003 | + if (input_sec->flags & SEC_ELF_PURECODE) | |
4004 | + (*_bfd_error_handler) (_("%B(%s): warning: long branch " | |
4005 | + " veneers used in section with " | |
4006 | + "SHF_ARM_PURECODE section " | |
4007 | + "attribute is only supported" | |
4008 | + " for M-profile targets that " | |
4009 | + "implement the movw " | |
4010 | + "instruction.")); | |
4011 | + | |
4012 | + stub_type = (bfd_link_pic (info) | globals->pic_veneer) | |
4013 | + /* PIC stub. */ | |
4014 | + ? arm_stub_long_branch_thumb_only_pic | |
4015 | + /* non-PIC stub. */ | |
4016 | + : (thumb2 ? arm_stub_long_branch_thumb2_only | |
4017 | + : arm_stub_long_branch_thumb_only); | |
4018 | + } | |
3976 | 4019 | } |
3977 | 4020 | } |
3978 | 4021 | else |
3979 | 4022 | { |
4023 | + if (input_sec->flags & SEC_ELF_PURECODE) | |
4024 | + (*_bfd_error_handler) (_("%B(%s): warning: long branch " | |
4025 | + " veneers used in section with " | |
4026 | + "SHF_ARM_PURECODE section " | |
4027 | + "attribute is only supported" | |
4028 | + " for M-profile targets that " | |
4029 | + "implement the movw " | |
4030 | + "instruction.")); | |
4031 | + | |
3980 | 4032 | /* Thumb to arm. */ |
3981 | 4033 | if (sym_sec != NULL |
3982 | 4034 | && sym_sec->owner != NULL |
@@ -4021,6 +4073,14 @@ arm_type_of_stub (struct bfd_link_info *info, | ||
4021 | 4073 | || r_type == R_ARM_PLT32 |
4022 | 4074 | || r_type == R_ARM_TLS_CALL) |
4023 | 4075 | { |
4076 | + if (input_sec->flags & SEC_ELF_PURECODE) | |
4077 | + (*_bfd_error_handler) (_("%B(%s): warning: long branch " | |
4078 | + " veneers used in section with " | |
4079 | + "SHF_ARM_PURECODE section " | |
4080 | + "attribute is only supported" | |
4081 | + " for M-profile targets that " | |
4082 | + "implement the movw " | |
4083 | + "instruction.")); | |
4024 | 4084 | if (branch_type == ST_BRANCH_TO_THUMB) |
4025 | 4085 | { |
4026 | 4086 | /* Arm to thumb. */ |
@@ -4446,6 +4506,7 @@ arm_stub_required_alignment (enum elf32_arm_stub_type stub_type) | ||
4446 | 4506 | case arm_stub_long_branch_v4t_arm_thumb: |
4447 | 4507 | case arm_stub_long_branch_thumb_only: |
4448 | 4508 | case arm_stub_long_branch_thumb2_only: |
4509 | + case arm_stub_long_branch_thumb2_only_pure: | |
4449 | 4510 | case arm_stub_long_branch_v4t_thumb_thumb: |
4450 | 4511 | case arm_stub_long_branch_v4t_thumb_arm: |
4451 | 4512 | case arm_stub_short_branch_v4t_thumb_arm: |
@@ -1,5 +1,11 @@ | ||
1 | 1 | 2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com> |
2 | 2 | |
3 | + * testsuite/ld-arm/farcall-thumb2-purecode.d: New test result. | |
4 | + * testsuite/ld-arm/farcall-thumb2-purecode.s: New test. | |
5 | + * testsuite/ld-arm/arm-elf.exp: Run it. | |
6 | + | |
7 | +2016-07-05 Andre Vieria <andre.simoesdiasvieira@arm.com> | |
8 | + | |
3 | 9 | * testsuite/ld-arm/arm_noread.ld: Renamed to ... |
4 | 10 | testsuite/ld-arm/arm_purecode.ld: ... this, and replaced |
5 | 11 | all noread's by purecode. |
@@ -505,6 +505,9 @@ set armeabitests_nonacl { | ||
505 | 505 | {farcall-thumb-thumb-m-no-profile-a.s farcall-thumb-thumb-m-no-profile-b.s} |
506 | 506 | {{objdump -d farcall-thumb-thumb-m-no-profile.d}} |
507 | 507 | "farcall-thumb-thumb-m-no-profile"} |
508 | + {"Thumb2 purecode farcall" "-Ttext 0x1000 --section-start .foo=0x2001020" "" "" {farcall-thumb2-purecode.s} | |
509 | + {{objdump -d farcall-thumb2-purecode.d}} | |
510 | + "farcall-thumb2-purecode"} | |
508 | 511 | |
509 | 512 | {"Thumb-ARM farcall" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "" "-W" {farcall-thumb-arm.s} |
510 | 513 | {{objdump -d farcall-thumb-arm.d}} |
@@ -0,0 +1,22 @@ | ||
1 | +.*: file format .* | |
2 | + | |
3 | +Disassembly of section .text: | |
4 | + | |
5 | +00001000 <bar>: | |
6 | + 1000: 4770 bx lr | |
7 | + | |
8 | +Disassembly of section .foo: | |
9 | + | |
10 | +02001020 <_start>: | |
11 | + 2001020: f000 f802 bl 2001028 <__bar_veneer> | |
12 | + 2001024: 0000 movs r0, r0 | |
13 | + \.\.\. | |
14 | + | |
15 | +02001028 <__bar_veneer>: | |
16 | + 2001028: f241 0c01 movw ip, #4097 ; 0x1001 | |
17 | + 200102c: f2c0 0c00 movt ip, #0 | |
18 | + 2001030: 4760 bx ip | |
19 | + 2001032: 0000 movs r0, r0 | |
20 | + 2001034: 0000 movs r0, r0 | |
21 | + \.\.\. | |
22 | + |
@@ -0,0 +1,19 @@ | ||
1 | +@ Test to ensure that a purecode Thumb2 call exceeding 4Mb generates a stub. | |
2 | + | |
3 | + .global _start | |
4 | + .syntax unified | |
5 | + .arch armv7-m | |
6 | + .thumb | |
7 | + .thumb_func | |
8 | + | |
9 | +@ We will place the section .text at 0x1000. | |
10 | + | |
11 | + .text | |
12 | +bar: | |
13 | + bx lr | |
14 | + | |
15 | +@ We will place the section .foo at 0x02001014. | |
16 | + | |
17 | + .section .foo, "0x20000006" | |
18 | +_start: | |
19 | + bl bar |