+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
#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
{
/* 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;
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
|| (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)
/* 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);
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. */
*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
+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
{{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"}
{{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"}
--- /dev/null
+.*: 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
--- /dev/null
+@ 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
+
--- /dev/null
+
+.*: 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
--- /dev/null
+
+.*: 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
--- /dev/null
+
+.*: 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>
--- /dev/null
+
+.*: 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>
--- /dev/null
+ .text
+ .syntax unified
+ .thumb_func
+ .global _start
+ .type _start,%function
+_start:
+ bne dest
+
+ .section destsect, "x"
+ .thumb_func
+dest:
+ bl dest