This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [ping] [patch] ARM support for long calls
Hi Nick,
Thanks again for your support. I am fine with the wording you have
finally checked in.
I have found a few issues with my patch, and here is attached the
corresponding fix.
Here is what is fixed now:
- in some tests, encoding was incorrect (ld-arm/farcall-thumb-arm,
ld-arm/farcall-thumb-arm-blx, ld-arm/farcall-thumb-arm-blx-pic-veneer).
This implied adding -W to gas flags in order not to be bothered by a
"Failed to find real start of function" warning.
- in some tests, destination symbols were converted to STT_SECTION type
by gas. However, in this case we can not tell if the destination symbol
is arm or thumb, so we no longer generate a stub. This is checked by
ld-arm/farcall-section. ld-arm/farcall-arm-arm.s,
ld-arm/farcall-thumb-arm.s were fixed so that the destination is of
function type.
- when stubs were necessary from several input sections, mapping symbols
could be generated in the wrong place. This is checked with
ld-arm/farcall-mix and ld-arm/farcall-mix2.
- tests exhibiting what --stub-group-size does have been added in
ld-arm/farcall-group.
Are you OK with this?
Christophe.
On 21.05.2008 10:11, Nick Clifton wrote:
Hi Dan, Hi Christophe,
Right - I have applied my documentation patch, adjusted slightly to
incorporate the wording that Christophe proposed. I have also applied
Christophe's patch to move the description of the --pic-veneer option
into the correct section of the linker manual.
Cheers
Nick
ld/ChangeLog
2008-05-21 Christophe Lyon <christophe.lyon@st.com>
Nick Clifton <nickc@redhat.com>
* ld.texinfo (ARM): Document --stub-group-size=N option.
Move description of --pic-veneer option into the ARM section.
* NEWS: Mention the support for long function calls.
2008-05-22 Christophe Lyon <christophe.lyon@st.com>
bfd/
* elf32-arm.c (arm_type_of_stub): Ignore STT_SECTION symbols.
(elf32_arm_stub_add_mapping_symbol): Remove.
(elf32_arm_add_stub): Don't generate mapping symbols. Change
prototype.
(elf32_arm_size_stubs): Use new elf32_arm_add_stub
prototype. Don't generate thumb to arm glue for calls.
(arm_map_one_stub): Define.
(elf32_arm_output_arch_local_syms): Generate mapping symbols for
long calls stubs.
ld/testsuite/
* ld-arm/farcall-arm-arm.s: Force function type on 'bar'.
* ld-arm/farcall-thumb-arm.s: Likewise.
* ld-arm/farcall-thumb-arm-blx.d: Fix encoding.
* ld-arm/farcall-thumb-arm.d: Likewise.
* ld-arm/farcall-thumb-arm-blx-pic-veneer.d: Likewise.
* ld-arm/arm-elf.exp (armelftests): Add farcall-mix, farcall-mix2,
farcall-group-default, farcall-group-size2, farcall-section Ignore
gas warnings in farcall-thumb-arm, farcall-thumb-arm-blx,
farcall-thumb-arm-blx-pic-veneer.
Index: ld/testsuite/ld-arm/farcall-arm-arm.s
===================================================================
--- ld/testsuite/ld-arm/farcall-arm-arm.s (revision 680)
+++ ld/testsuite/ld-arm/farcall-arm-arm.s (working copy)
@@ -14,6 +14,7 @@ _start:
.section .foo, "xa"
+ .type bar, %function
bar:
bx lr
Index: ld/testsuite/ld-arm/farcall-mix2.d
===================================================================
--- ld/testsuite/ld-arm/farcall-mix2.d (revision 0)
+++ ld/testsuite/ld-arm/farcall-mix2.d (revision 0)
@@ -0,0 +1,48 @@
+
+.*: file format .*
+
+Disassembly of section .text:
+
+00001000 <_start-0x18>:
+ 1000: e51ff004 ldr pc, \[pc, #-4\] ; 1004 <_start-0x14>
+ 1004: 02003024 .word 0x02003024
+ 1008: e59fc000 ldr ip, \[pc, #0\] ; 1010 <_start-0x8>
+ 100c: e12fff1c bx ip
+ 1010: 02003021 .word 0x02003021
+ 1014: 00000000 .word 0x00000000
+
+00001018 <_start>:
+ 1018: ebfffffa bl 1008 <_start-0x10>
+ 101c: ebfffff7 bl 1000 <_start-0x18>
+Disassembly of section .mytext:
+
+00002000 <.mytext>:
+ 2000: e59fc000 ldr ip, \[pc, #0\] ; 2008 <__exidx_end\+0xfe8>
+ 2004: e12fff1c bx ip
+ 2008: 0200302f .word 0x0200302f
+ 200c: e51ff004 ldr pc, \[pc, #-4\] ; 2010 <__exidx_end\+0xff0>
+ 2010: 02003028 .word 0x02003028
+ 2014: e59fc000 ldr ip, \[pc, #0\] ; 201c <__exidx_end\+0xffc>
+ 2018: e12fff1c bx ip
+ 201c: 0200302d .word 0x0200302d
+ ...
+ 2028: ebfffff7 bl 200c <__exidx_end\+0xfec>
+ 202c: ebfffff8 bl 2014 <__exidx_end\+0xff4>
+ 2030: ebfffff2 bl 2000 <__exidx_end\+0xfe0>
+Disassembly of section .foo:
+
+02003020 <bar>:
+ 2003020: 4770 bx lr
+ ...
+
+02003024 <bar2>:
+ 2003024: e12fff1e bx lr
+
+02003028 <bar3>:
+ 2003028: e12fff1e bx lr
+
+0200302c <bar4>:
+ 200302c: 4770 bx lr
+
+0200302e <bar5>:
+ 200302e: 4770 bx lr
Index: ld/testsuite/ld-arm/farcall-mix2.s
===================================================================
--- ld/testsuite/ld-arm/farcall-mix2.s (revision 0)
+++ ld/testsuite/ld-arm/farcall-mix2.s (revision 0)
@@ -0,0 +1,51 @@
+@ Test to ensure that ARM calls exceeding 32Mb generate stubs.
+
+ .global _start
+ .syntax unified
+
+@ We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ bl bar
+ bl bar2
+
+
+@ We will place the section .mytext at 0x2000.
+
+ .section .mytext, "xa"
+ bl bar3
+ bl bar4
+ bl bar5
+
+@ We will place the section .foo at 0x2003020.
+
+ .section .foo, "xa"
+
+ .global bar
+ .thumb_func
+bar:
+ bx lr
+
+ .arm
+ .global bar2
+ .type bar2, %function
+bar2:
+ bx lr
+
+ .global bar3
+ .type bar3, %function
+bar3:
+ bx lr
+
+ .global bar4
+ .thumb_func
+bar4:
+ bx lr
+
+ .global bar5
+ .type bar5, %function
+bar5:
+ bx lr
+
Index: ld/testsuite/ld-arm/farcall-thumb-arm-blx.d
===================================================================
--- ld/testsuite/ld-arm/farcall-thumb-arm-blx.d (revision 680)
+++ ld/testsuite/ld-arm/farcall-thumb-arm-blx.d (working copy)
@@ -11,4 +11,4 @@ Disassembly of section .text:
Disassembly of section .foo:
02001014 <bar>:
- 2001014: 4770 bx lr
+ 2001014: e12fff1e bx lr
Index: ld/testsuite/ld-arm/farcall-group2.s
===================================================================
--- ld/testsuite/ld-arm/farcall-group2.s (revision 0)
+++ ld/testsuite/ld-arm/farcall-group2.s (revision 0)
@@ -0,0 +1,10 @@
+
+@ Test to ensure that ARM calls exceeding 32Mb generate stubs.
+
+@ We will place the section .foo at 0x2000.
+
+ .text
+myfunc:
+ bl bar3
+ bl bar4
+ bl bar5
Index: ld/testsuite/ld-arm/farcall-mix.d
===================================================================
--- ld/testsuite/ld-arm/farcall-mix.d (revision 0)
+++ ld/testsuite/ld-arm/farcall-mix.d (revision 0)
@@ -0,0 +1,44 @@
+
+.*: file format .*
+
+Disassembly of section .text:
+
+00001000 <_start-0x40>:
+ 1000: e51ff004 ldr pc, \[pc, #-4\] ; 1004 <_start-0x3c>
+ 1004: 02002024 .word 0x02002024
+ 1008: e59fc000 ldr ip, \[pc, #0\] ; 1010 <_start-0x30>
+ 100c: e12fff1c bx ip
+ 1010: 02002021 .word 0x02002021
+ 1014: e51ff004 ldr pc, \[pc, #-4\] ; 1018 <_start-0x28>
+ 1018: 02002028 .word 0x02002028
+ 101c: e59fc000 ldr ip, \[pc, #0\] ; 1024 <_start-0x1c>
+ 1020: e12fff1c bx ip
+ 1024: 0200202d .word 0x0200202d
+ 1028: e59fc000 ldr ip, \[pc, #0\] ; 1030 <_start-0x10>
+ 102c: e12fff1c bx ip
+ 1030: 0200202f .word 0x0200202f
+ ...
+
+00001040 <_start>:
+ 1040: ebfffff0 bl 1008 <_start-0x38>
+ 1044: ebffffed bl 1000 <_start-0x40>
+ 1048: ebfffff1 bl 1014 <_start-0x2c>
+ 104c: ebfffff2 bl 101c <_start-0x24>
+ 1050: ebfffff4 bl 1028 <_start-0x18>
+Disassembly of section .foo:
+
+02002020 <bar>:
+ 2002020: 4770 bx lr
+ ...
+
+02002024 <bar2>:
+ 2002024: e12fff1e bx lr
+
+02002028 <bar3>:
+ 2002028: e12fff1e bx lr
+
+0200202c <bar4>:
+ 200202c: 4770 bx lr
+
+0200202e <bar5>:
+ 200202e: 4770 bx lr
Index: ld/testsuite/ld-arm/farcall-mix.s
===================================================================
--- ld/testsuite/ld-arm/farcall-mix.s (revision 0)
+++ ld/testsuite/ld-arm/farcall-mix.s (revision 0)
@@ -0,0 +1,46 @@
+@ Test to ensure that ARM calls exceeding 32Mb generate stubs.
+
+ .global _start
+ .syntax unified
+
+@ We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ bl bar
+ bl bar2
+ bl bar3
+ bl bar4
+ bl bar5
+
+@ We will place the section .foo at 0x2002020.
+
+ .section .foo, "xa"
+
+ .global bar
+ .thumb_func
+bar:
+ bx lr
+
+ .arm
+ .global bar2
+ .type bar2, %function
+bar2:
+ bx lr
+
+ .global bar3
+ .type bar3, %function
+bar3:
+ bx lr
+
+ .global bar4
+ .thumb_func
+bar4:
+ bx lr
+
+ .global bar5
+ .type bar5, %function
+bar5:
+ bx lr
+
Index: ld/testsuite/ld-arm/farcall-group-size2.d
===================================================================
--- ld/testsuite/ld-arm/farcall-group-size2.d (revision 0)
+++ ld/testsuite/ld-arm/farcall-group-size2.d (revision 0)
@@ -0,0 +1,47 @@
+
+.*: file format .*
+
+Disassembly of section .text:
+
+00001000 <_start-0x18>:
+ 1000: e51ff004 ldr pc, \[pc, #-4\] ; 1004 <_start-0x14>
+ 1004: 02003024 .word 0x02003024
+ 1008: e59fc000 ldr ip, \[pc, #0\] ; 1010 <_start-0x8>
+ 100c: e12fff1c bx ip
+ 1010: 02003021 .word 0x02003021
+ 1014: 00000000 .word 0x00000000
+
+00001018 <_start>:
+ 1018: ebfffffa bl 1008 <_start-0x10>
+ 101c: ebfffff7 bl 1000 <_start-0x18>
+ 1020: e51ff004 ldr pc, \[pc, #-4\] ; 1024 <_start\+0xc>
+ 1024: 02003028 .word 0x02003028
+ 1028: e59fc000 ldr ip, \[pc, #0\] ; 1030 <_start\+0x18>
+ 102c: e12fff1c bx ip
+ 1030: 0200302f .word 0x0200302f
+ 1034: e59fc000 ldr ip, \[pc, #0\] ; 103c <_start\+0x24>
+ 1038: e12fff1c bx ip
+ 103c: 0200302d .word 0x0200302d
+ ...
+
+00001048 <myfunc>:
+ 1048: ebfffff4 bl 1020 <_start\+0x8>
+ 104c: ebfffff8 bl 1034 <_start\+0x1c>
+ 1050: ebfffff4 bl 1028 <_start\+0x10>
+Disassembly of section .foo:
+
+02003020 <bar>:
+ 2003020: 4770 bx lr
+ ...
+
+02003024 <bar2>:
+ 2003024: e12fff1e bx lr
+
+02003028 <bar3>:
+ 2003028: e12fff1e bx lr
+
+0200302c <bar4>:
+ 200302c: 4770 bx lr
+
+0200302e <bar5>:
+ 200302e: 4770 bx lr
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
--- ld/testsuite/ld-arm/arm-elf.exp (revision 680)
+++ ld/testsuite/ld-arm/arm-elf.exp (working copy)
@@ -222,15 +222,29 @@ set armelftests {
{{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}}
"farcall-thumb-thumb-blx-pic-veneer"}
- {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "" {farcall-thumb-arm.s}
+ {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s}
{{objdump -d farcall-thumb-arm.d}}
"farcall-thumb-arm"}
- {"Thumb-ARM farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-thumb-arm.s}
+ {"Thumb-ARM farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
{{objdump -d farcall-thumb-arm-blx.d}}
"farcall-thumb-arm-blx"}
- {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-arm.s}
+ {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
{{objdump -d farcall-thumb-arm-blx-pic-veneer.d}}
"farcall-thumb-arm-blx-pic-veneer"}
+
+ {"Multiple farcalls" "-Ttext 0x1000 --section-start .foo=0x2002020" "" {farcall-mix.s}
+ {{objdump -d farcall-mix.d}}
+ "farcall-mix"}
+ {"Multiple farcalls from several sections" "-Ttext 0x1000 --section-start .mytext=0x2000 --section-start .foo=0x2003020" "" {farcall-mix2.s}
+ {{objdump -d farcall-mix2.d}}
+ "farcall-mix2"}
+
+ {"Default group size" "-Ttext 0x1000 --section-start .foo=0x2003020" "" {farcall-group.s farcall-group2.s}
+ {{objdump -d farcall-group.d}}
+ "farcall-group-default"}
+ {"Group size=2" "-Ttext 0x1000 --section-start .foo=0x2003020 --stub-group-size=2" "" {farcall-group.s farcall-group2.s}
+ {{objdump -d farcall-group-size2.d}}
+ "farcall-group-size2"}
}
run_ld_link_tests $armelftests
@@ -243,6 +257,7 @@ run_dump_test "farcall-thumb-thumb"
run_dump_test "farcall-thumb-thumb-pic-veneer"
run_dump_test "farcall-thumb-thumb-m-pic-veneer"
run_dump_test "farcall-thumb-arm-pic-veneer"
+run_dump_test "farcall-section"
# Exclude non-ARM-EABI targets.
Index: ld/testsuite/ld-arm/farcall-group.d
===================================================================
--- ld/testsuite/ld-arm/farcall-group.d (revision 0)
+++ ld/testsuite/ld-arm/farcall-group.d (revision 0)
@@ -0,0 +1,46 @@
+
+.*: file format .*
+
+Disassembly of section .text:
+
+00001000 <_start-0x40>:
+ 1000: e51ff004 ldr pc, \[pc, #-4\] ; 1004 <_start-0x3c>
+ 1004: 02003024 .word 0x02003024
+ 1008: e59fc000 ldr ip, \[pc, #0\] ; 1010 <_start-0x30>
+ 100c: e12fff1c bx ip
+ 1010: 02003021 .word 0x02003021
+ 1014: e51ff004 ldr pc, \[pc, #-4\] ; 1018 <_start-0x28>
+ 1018: 02003028 .word 0x02003028
+ 101c: e59fc000 ldr ip, \[pc, #0\] ; 1024 <_start-0x1c>
+ 1020: e12fff1c bx ip
+ 1024: 0200302d .word 0x0200302d
+ 1028: e59fc000 ldr ip, \[pc, #0\] ; 1030 <_start-0x10>
+ 102c: e12fff1c bx ip
+ 1030: 0200302f .word 0x0200302f
+ ...
+
+00001040 <_start>:
+ 1040: ebfffff0 bl 1008 <_start-0x38>
+ 1044: ebffffed bl 1000 <_start-0x40>
+
+00001048 <myfunc>:
+ 1048: ebfffff1 bl 1014 <_start-0x2c>
+ 104c: ebfffff2 bl 101c <_start-0x24>
+ 1050: ebfffff4 bl 1028 <_start-0x18>
+Disassembly of section .foo:
+
+02003020 <bar>:
+ 2003020: 4770 bx lr
+ ...
+
+02003024 <bar2>:
+ 2003024: e12fff1e bx lr
+
+02003028 <bar3>:
+ 2003028: e12fff1e bx lr
+
+0200302c <bar4>:
+ 200302c: 4770 bx lr
+
+0200302e <bar5>:
+ 200302e: 4770 bx lr
Index: ld/testsuite/ld-arm/farcall-thumb-arm.d
===================================================================
--- ld/testsuite/ld-arm/farcall-thumb-arm.d (revision 680)
+++ ld/testsuite/ld-arm/farcall-thumb-arm.d (working copy)
@@ -16,4 +16,4 @@ Disassembly of section .text:
Disassembly of section .foo:
02001014 <bar>:
- 2001014: 4770 bx lr
+ 2001014: e12fff1e bx lr
Index: ld/testsuite/ld-arm/farcall-thumb-arm.s
===================================================================
--- ld/testsuite/ld-arm/farcall-thumb-arm.s (revision 680)
+++ ld/testsuite/ld-arm/farcall-thumb-arm.s (working copy)
@@ -14,6 +14,8 @@ _start:
.section .foo, "xa"
+ .arm
+ .type bar, %function
bar:
bx lr
Index: ld/testsuite/ld-arm/farcall-group.s
===================================================================
--- ld/testsuite/ld-arm/farcall-group.s (revision 0)
+++ ld/testsuite/ld-arm/farcall-group.s (revision 0)
@@ -0,0 +1,44 @@
+@ Test to ensure that ARM calls exceeding 32Mb generate stubs.
+
+ .global _start
+ .syntax unified
+
+@ We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ bl bar
+ bl bar2
+
+
+@ We will place the section .foo at 0x2003020.
+
+ .section .foo, "xa"
+
+ .global bar
+ .thumb_func
+bar:
+ bx lr
+
+ .arm
+ .global bar2
+ .type bar2, %function
+bar2:
+ bx lr
+
+ .global bar3
+ .type bar3, %function
+bar3:
+ bx lr
+
+ .global bar4
+ .thumb_func
+bar4:
+ bx lr
+
+ .global bar5
+ .type bar5, %function
+bar5:
+ bx lr
+
Index: ld/testsuite/ld-arm/farcall-section.d
===================================================================
--- ld/testsuite/ld-arm/farcall-section.d (revision 0)
+++ ld/testsuite/ld-arm/farcall-section.d (revision 0)
@@ -0,0 +1,5 @@
+#name: ARM-ARM farcall to symbol of type STT_SECTION
+#source: farcall-section.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x2001014
+#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_CALL against `.foo'
Index: ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d
===================================================================
--- ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d (revision 680)
+++ ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d (working copy)
@@ -13,4 +13,4 @@ Disassembly of section .text:
Disassembly of section .foo:
02001014 <bar>:
- 2001014: 4770 bx lr
+ 2001014: e12fff1e bx lr
Index: ld/testsuite/ld-arm/farcall-section.s
===================================================================
--- ld/testsuite/ld-arm/farcall-section.s (revision 0)
+++ ld/testsuite/ld-arm/farcall-section.s (revision 0)
@@ -0,0 +1,20 @@
+@ Test to ensure that a ARM to ARM call exceeding 32Mb generates an error
+@ if the destination is of type STT_SECTION (eg non-global symbol)
+
+ .global _start
+ .syntax unified
+
+@ We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ bl bar
+
+@ We will place the section .foo at 0x2001020.
+
+ .section .foo, "xa"
+
+bar:
+ bx lr
+
Index: bfd/elf32-arm.c
===================================================================
--- bfd/elf32-arm.c (revision 680)
+++ bfd/elf32-arm.c (working copy)
@@ -2696,6 +2696,11 @@ arm_type_of_stub (struct bfd_link_info *
int thumb_only;
enum elf32_arm_stub_type stub_type = arm_stub_none;
+ /* We don't know the actual type of destination in case it is of
+ type STT_SECTION: give up */
+ if (st_type == STT_SECTION)
+ return stub_type;
+
globals = elf32_arm_hash_table (info);
thumb_only = using_thumb_only(globals);
@@ -2875,32 +2880,13 @@ elf32_arm_get_stub_entry (const asection
return stub_entry;
}
-static void elf32_arm_stub_add_mapping_symbol(struct bfd_link_info * link_info,
- asection *stub_sec, char* name,
- bfd_vma val)
-{
- struct bfd_link_hash_entry * bh = NULL;
- struct elf_link_hash_entry * myh;
-
- _bfd_generic_link_add_one_symbol (link_info,
- stub_sec->owner, name,
- BSF_LOCAL, stub_sec, stub_sec->size + val,
- NULL, TRUE, FALSE, &bh);
-
- myh = (struct elf_link_hash_entry *) bh;
- myh->type = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
- myh->forced_local = 1;
-}
-
/* Add a new stub entry to the stub hash. Not all fields of the new
stub entry are initialised. */
static struct elf32_arm_stub_hash_entry *
elf32_arm_add_stub (const char *stub_name,
asection *section,
- struct elf32_arm_link_hash_table *htab,
- struct bfd_link_info * link_info,
- enum elf32_arm_stub_type stub_type)
+ struct elf32_arm_link_hash_table *htab)
{
asection *link_sec;
asection *stub_sec;
@@ -2948,32 +2934,6 @@ elf32_arm_add_stub (const char *stub_nam
stub_entry->stub_offset = 0;
stub_entry->id_sec = link_sec;
- switch(stub_type) {
- case arm_stub_long_branch:
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$a", 0);
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$d", 4);
- break;
- case arm_thumb_v4t_stub_long_branch:
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$a", 0);
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$d", 8);
- break;
- case arm_thumb_thumb_stub_long_branch:
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$t", 0);
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$d", 12);
- break;
- case arm_thumb_arm_v4t_stub_long_branch:
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$t", 0);
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$a", 8);
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$d", 16);
- break;
- case arm_stub_pic_long_branch:
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$a", 0);
- elf32_arm_stub_add_mapping_symbol(link_info, stub_sec, "$d", 8);
- break;
- default:
- BFD_FAIL ();
- }
-
return stub_entry;
}
@@ -3561,7 +3521,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
continue;
}
- stub_entry = elf32_arm_add_stub (stub_name, section, htab, info, stub_type);
+ stub_entry = elf32_arm_add_stub (stub_name, section, htab);
if (stub_entry == NULL)
{
free (stub_name);
@@ -6286,7 +6246,8 @@ elf32_arm_final_link_relocate (reloc_how
/* Convert BL to BLX. */
lower_insn = (lower_insn & ~0x1000) | 0x0800;
}
- else if (elf32_thumb_to_arm_stub
+ else if (r_type != R_ARM_THM_CALL) {
+ if (elf32_thumb_to_arm_stub
(info, sym_name, input_bfd, output_bfd, input_section,
hit_data, sym_sec, rel->r_offset, signed_addend, value,
error_message))
@@ -6294,6 +6255,7 @@ elf32_arm_final_link_relocate (reloc_how
else
return bfd_reloc_dangerous;
}
+ }
else if (sym_flags == STT_ARM_TFUNC && globals->use_blx
&& r_type == R_ARM_THM_CALL)
{
@@ -10905,6 +10867,72 @@ elf32_arm_output_plt_map (struct elf_lin
}
+static bfd_boolean
+arm_map_one_stub (struct bfd_hash_entry *gen_entry,
+ PTR in_arg)
+{
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ struct bfd_link_info *info;
+ struct elf32_arm_link_hash_table *htab;
+ asection *stub_sec;
+ bfd_vma addr;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
+
+ output_arch_syminfo *osi = (output_arch_syminfo *) in_arg;
+ info = osi->info;
+
+ htab = elf32_arm_hash_table (info);
+ stub_sec = stub_entry->stub_sec;
+
+ /* Ensure this stub is attached to the current section being
+ processed */
+ if (stub_sec != osi->sec)
+ return TRUE;
+
+ addr = (bfd_vma)stub_entry->stub_offset;
+
+ switch(stub_entry->stub_type) {
+ case arm_stub_long_branch:
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+ return FALSE;
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 4))
+ return FALSE;
+ break;
+ case arm_thumb_v4t_stub_long_branch:
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+ return FALSE;
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 8))
+ return FALSE;
+ break;
+ case arm_thumb_thumb_stub_long_branch:
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_THUMB, addr))
+ return FALSE;
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 12))
+ return FALSE;
+ break;
+ case arm_thumb_arm_v4t_stub_long_branch:
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_THUMB, addr))
+ return FALSE;
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr + 8))
+ return FALSE;
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 16))
+ return FALSE;
+ break;
+ case arm_stub_pic_long_branch:
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+ return FALSE;
+ if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 8))
+ return FALSE;
+ break;
+ default:
+ BFD_FAIL ();
+ }
+
+ return TRUE;
+}
+
/* Output mapping symbols for linker generated sections. */
static bfd_boolean
@@ -10967,6 +10995,26 @@ elf32_arm_output_arch_local_syms (bfd *o
}
}
+ /* Long calls stubs. */
+ if (htab->stub_bfd && htab->stub_bfd->sections) {
+ asection* stub_sec;
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next) {
+
+ /* Ignore non-stub sections */
+ if (!strstr(stub_sec->name, STUB_SUFFIX))
+ continue;
+
+ osi.sec = stub_sec;
+
+ osi.sec_shndx = _bfd_elf_section_from_bfd_section
+ (output_bfd, osi.sec->output_section);
+
+ bfd_hash_traverse (&htab->stub_hash_table, arm_map_one_stub, &osi);
+ }
+ }
+
/* Finally, output mapping symbols for the PLT. */
if (!htab->splt || htab->splt->size == 0)
return TRUE;