bfd/ChangeLog

2014-08-21  Tony Wang  <tony.wang@arm.com>

	* elf32-arm.c (elf32_arm_final_link_relocate): Implement
	the veneer routine for R_ARM_THM_JUMP19.
	(arm_type_of_stub): Add conditional clause for R_ARM_THM_JUMP19
	(elf32_arm_size_stub): Ditto.

ld/testsuite/ChangeLog
2014-08-21  Tony Wang  <tony.wang@arm.com>

	* ld-arm/jump-reloc-veneers-cond.s: New test.
	* ld-arm/farcall-cond-thumb-arm.s: Ditto.
	* ld-arm/jump-reloc-veneers-cond-short.d: Expected output
	for target without a veneer generation.
	* ld-arm/jump-reloc-veneers-cond-long.d: Expected output
	for target with a veneer generation.
	* ld-arm/farcall-cond-thumb-arm.d: Expected output for
	inter working veneer generation.
	* ld-arm/arm-elf.exp: Add tests for conditional branch veneer.
This commit is contained in:
Terry Guo 2014-08-21 18:00:35 +08:00
parent de589d04f3
commit c542398150
11 changed files with 220 additions and 6 deletions

View File

@ -1,3 +1,10 @@
2014-08-21 Tony Wang <tony.wang@arm.com>
* elf32-arm.c (elf32_arm_final_link_relocate): Implement
the veneer routine for R_ARM_THM_JUMP19.
(arm_type_of_stub): Add conditional clause for R_ARM_THM_JUMP19
(elf32_arm_size_stub): Ditto.
2014-08-20 Roland McGrath <mcgrathr@google.com>
PR ld/17277

View File

@ -2283,6 +2283,8 @@ static const bfd_vma elf32_arm_nacl_plt_entry [] =
#define THM_MAX_BWD_BRANCH_OFFSET (-(1 << 22) + 4)
#define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4)
#define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4)
#define THM2_MAX_FWD_COND_BRANCH_OFFSET (((1 << 20) -2) + 4)
#define THM2_MAX_BWD_COND_BRANCH_OFFSET (-(1 << 20) + 4)
enum stub_insn_type
{
@ -3667,7 +3669,8 @@ arm_type_of_stub (struct bfd_link_info *info,
/* ST_BRANCH_TO_ARM is nonsense to thumb-only targets when we
are considering a function call relocation. */
if (thumb_only && (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
if (thumb_only && (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24
|| r_type == R_ARM_THM_JUMP19)
&& branch_type == ST_BRANCH_TO_ARM)
branch_type = ST_BRANCH_TO_THUMB;
@ -3711,7 +3714,7 @@ arm_type_of_stub (struct bfd_link_info *info,
branch_offset = (bfd_signed_vma)(destination - location);
if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24
|| r_type == R_ARM_THM_TLS_CALL)
|| r_type == R_ARM_THM_TLS_CALL || r_type == R_ARM_THM_JUMP19)
{
/* Handle cases where:
- this call goes too far (different Thumb/Thumb2 max
@ -3727,10 +3730,15 @@ arm_type_of_stub (struct bfd_link_info *info,
|| (thumb2
&& (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
|| (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
|| (thumb2
&& (branch_offset > THM2_MAX_FWD_COND_BRANCH_OFFSET
|| (branch_offset < THM2_MAX_BWD_COND_BRANCH_OFFSET))
&& (r_type == R_ARM_THM_JUMP19))
|| (branch_type == ST_BRANCH_TO_ARM
&& (((r_type == R_ARM_THM_CALL
|| r_type == R_ARM_THM_TLS_CALL) && !globals->use_blx)
|| (r_type == R_ARM_THM_JUMP24))
|| (r_type == R_ARM_THM_JUMP24)
|| (r_type == R_ARM_THM_JUMP19))
&& !use_plt))
{
if (branch_type == ST_BRANCH_TO_THUMB)
@ -5347,7 +5355,8 @@ elf32_arm_size_stubs (bfd *output_bfd,
/* For historical reasons, use the existing names for
ARM-to-Thumb and Thumb-to-ARM stubs. */
if ((r_type == (unsigned int) R_ARM_THM_CALL
|| r_type == (unsigned int) R_ARM_THM_JUMP24)
|| r_type == (unsigned int) R_ARM_THM_JUMP24
|| r_type == (unsigned int) R_ARM_THM_JUMP19)
&& branch_type == ST_BRANCH_TO_ARM)
sprintf (stub_entry->output_name,
THUMB2ARM_GLUE_ENTRY_NAME, sym_name);
@ -9125,6 +9134,9 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
bfd_signed_vma reloc_signed_max = 0xffffe;
bfd_signed_vma reloc_signed_min = -0x100000;
bfd_signed_vma signed_check;
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;
/* Need to refetch the addend, reconstruct the top three bits,
and squish the two 11 bit pieces together. */
@ -9156,8 +9168,25 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
*unresolved_reloc_p = FALSE;
}
/* ??? Should handle interworking? GCC might someday try to
use this for tail calls. */
hash = (struct elf32_arm_link_hash_entry *)h;
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);
}
}
relocation = value + signed_addend;
relocation -= (input_section->output_section->vma

View File

@ -1,3 +1,15 @@
2014-08-21 Tony Wang <tony.wang@arm.com>
* ld-arm/jump-reloc-veneers-cond.s: New test.
* ld-arm/farcall-cond-thumb-arm.s: Ditto.
* ld-arm/jump-reloc-veneers-cond-short.d: Expected output
for target without a veneer generation.
* ld-arm/jump-reloc-veneers-cond-long.d: Expected output
for target with a veneer generation.
* ld-arm/farcall-cond-thumb-arm.d: Expected output for
inter working veneer generation.
* ld-arm/arm-elf.exp: Add tests for conditional branch veneer.
2014-08-20 Roland McGrath <mcgrathr@google.com>
PR ld/17277

View File

@ -453,6 +453,16 @@ set armeabitests_nonacl {
{{objdump -d farcall-thumb-arm-pic-veneer.d}}
"farcall-thumb-arm-pic-veneer"}
{"Thumb-ARM farcall cond" "-Ttext 0x8000 --section-start .foo=0x118000" "" "-W" {farcall-cond-thumb-arm.s}
{{objdump -d farcall-cond-thumb-arm.d}}
"farcall-cond-thumb-arm"}
{"Thumb-ARM farcall cond (BE8)" "-Ttext 0x8000 --section-start .foo=0x118000 -EB --be8" "" "-W -EB" {farcall-cond-thumb-arm.s}
{{objdump -d farcall-cond-thumb-arm.d}}
"farcall-cond-thumb-arm-be8"}
{"Thumb-ARM farcall cond (BE)" "-Ttext 0x8000 --section-start .foo=0x118000 -EB" "" "-W -EB" {farcall-cond-thumb-arm.s}
{{objdump -d farcall-cond-thumb-arm.d}}
"farcall-cond-thumb-arm-be"}
{"Multiple farcalls" "-Ttext 0x1000 --section-start .foo=0x2002020" "" "" {farcall-mix.s}
{{objdump -d farcall-mix.d}}
"farcall-mix"}
@ -551,6 +561,31 @@ set armeabitests_nonacl {
{{objdump -d jump-reloc-veneers-long.d}}
"jump-reloc-veneers-long"}
{"R_ARM_THM_JUMP19 Relocation veneers: Short"
"--section-start destsect=0x000108002 --section-start .text=0x8000" ""
"-march=armv7-m -mthumb"
{jump-reloc-veneers-cond.s}
{{objdump -d jump-reloc-veneers-cond-short.d}}
"jump-reloc-veneers-cond-short"}
{"R_ARM_THM_JUMP19 Relocation veneers: Long"
"--section-start destsect=0x00108004 --section-start .text=0x8000" ""
"-march=armv7-m -mthumb"
{jump-reloc-veneers-cond.s}
{{objdump -d jump-reloc-veneers-cond-long.d}}
"jump-reloc-veneers-cond-long"}
{"R_ARM_THM_JUMP19 Relocation veneers: Short backward"
"--section-start destsect=0x8004 --section-start .text=0x108000" ""
"-march=armv7-m -mthumb"
{jump-reloc-veneers-cond.s}
{{objdump -d jump-reloc-veneers-cond-short-backward.d}}
"jump-reloc-veneers-cond-short-backward"}
{"R_ARM_THM_JUMP19 Relocation veneers: Long backward"
"--section-start destsect=0x8002 --section-start .text=0x108000" ""
"-march=armv7-m -mthumb"
{jump-reloc-veneers-cond.s}
{{objdump -d jump-reloc-veneers-cond-long-backward.d}}
"jump-reloc-veneers-cond-long-backward"}
{"Default group size" "-Ttext 0x1000 --section-start .foo=0x2003020" "" "" {farcall-group.s farcall-group2.s}
{{objdump -d farcall-group.d}}
"farcall-group-default"}

View File

@ -0,0 +1,18 @@
.*: file format .*
Disassembly of section .text:
00008000 <_start>:
8000: f050 a002 bne.w 58008 <__bar_from_thumb>
\.\.\.
58004: f040 8000 bne.w 58008 <__bar_from_thumb>
00058008 <__bar_from_thumb>:
58008: 4778 bx pc
5800a: 46c0 nop ; \(mov r8, r8\)
5800c: ea02fffb b 118000 <bar>
Disassembly of section .foo:
00118000 <bar>:
118000: e12fff1e bx lr

View File

@ -0,0 +1,27 @@
@ Test to ensure that a Thumb to ARM call exceeding 4Mb generates a stub.
@ Check that we can generate two types of stub in the same section.
.global _start
.syntax unified
@ We will place the section .text at 0x1c01010.
.text
.thumb_func
_start:
.global bar
bne bar
@ This call is close enough to generate a "short branch" stub
@ or no stub if blx is available.
.space 0x050000
bne bar
@ We will place the section .foo at 0x2001014.
.section .foo, "xa"
.arm
.type bar, %function
bar:
bx lr

View File

@ -0,0 +1,24 @@
.*: file format.*
Disassembly of section destsect:
00008002 <[^>]*>:
8002: f7ff fffe bl 8002 <dest>
Disassembly of section .text:
001080.. <[^>]*>:
1080..: f040 8002 bne.w 108008 <__dest_veneer>
1080..: 0000 movs r0, r0
...
001080.. <[^>]*>:
1080..: b401 push {r0}
1080..: 4802 ldr r0, \[pc, #8\] ; \(108014 <__dest_veneer\+0xc>\)
1080..: 4684 mov ip, r0
1080..: bc01 pop {r0}
1080..: 4760 bx ip
1080..: bf00 nop
1080..: 00008003 .word 0x00008003

View File

@ -0,0 +1,24 @@
.*: file format.*
Disassembly of section destsect:
00108004 <[^>]*>:
108004: f7ff fffe bl 108004 <dest>
Disassembly of section .text:
000080.. <[^>]*>:
80..: (8002f040|f0408002) .word 0x(8002f040|f0408002)
80..: 0000 movs r0, r0
...
000080.. <[^>]*>:
80..: b401 push {r0}
80..: 4802 ldr r0, \[pc, #8\] ; \(80.. <__dest_veneer\+0xc>\)
80..: 4684 mov ip, r0
80..: bc01 pop {r0}
80..: 4760 bx ip
80..: bf00 nop
80..: 00108005 .word 0x00108005

View File

@ -0,0 +1,13 @@
.*: file format.*
Disassembly of section destsect:
00008004 <[^>]*>:
8004: f7ff fffe bl 8004 <dest>
Disassembly of section .text:
001080.. <_start>:
1080..: f440 8000 bne.w 8004 <dest>

View File

@ -0,0 +1,13 @@
.*: file format.*
Disassembly of section destsect:
00108002 <[^>]*>:
108002: f7ff fffe bl 108002 <dest>
Disassembly of section .text:
000080.. <[^>]*>:
80..: f07f afff bne.w 108002 <dest>

View File

@ -0,0 +1,12 @@
.text
.syntax unified
.thumb_func
.global _start
.type _start,%function
_start:
bne dest
.section destsect, "x"
.thumb_func
dest:
bl dest