aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-arm.c
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@st.com>2009-04-17 13:04:41 +0000
committerChristophe Lyon <christophe.lyon@st.com>2009-04-17 13:04:41 +0000
commit69c5861ee1e736adf16998ba505b5054fc633f3f (patch)
tree2b86ed0ec632978d7b49d94483b24e2ea43351a1 /bfd/elf32-arm.c
parente9cd066073fafdb8e7824beb32561935134d7113 (diff)
downloadgdb-69c5861ee1e736adf16998ba505b5054fc633f3f.zip
gdb-69c5861ee1e736adf16998ba505b5054fc633f3f.tar.gz
gdb-69c5861ee1e736adf16998ba505b5054fc633f3f.tar.bz2
2009-04-17 Christophe Lyon <christophe.lyon@st.com>
bfd/ * elf32-arm.c (elf32_arm_size_stubs): Handle long branches through PLT entries to an undefined symbol when generating a shared library. testsuite/ * ld-arm/arm-elf.exp: Add new test farcall-mixed-lib. * ld-arm/farcall-mixed-lib.d: Update expected output. * ld-arm/farcall-mixed-lib1.s: New file. * ld-arm/farcall-mixed-lib2.s: New file.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r--bfd/elf32-arm.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 99beb9e..2f49b7e 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -3832,12 +3832,29 @@ elf32_arm_size_stubs (bfd *output_bfd,
+ sym_sec->output_offset
+ sym_sec->output_section->vma);
}
- else if (hash->root.root.type == bfd_link_hash_undefweak
- || hash->root.root.type == bfd_link_hash_undefined)
- /* For a shared library, these will need a PLT stub,
- which is treated separately.
- For absolute code, they cannot be handled. */
- continue;
+ else if ((hash->root.root.type == bfd_link_hash_undefined)
+ || (hash->root.root.type == bfd_link_hash_undefweak))
+ {
+ /* For a shared library, use the PLT stub as
+ target address to decide whether a long
+ branch stub is needed.
+ For absolute code, they cannot be handled. */
+ struct elf32_arm_link_hash_table *globals =
+ elf32_arm_hash_table (info);
+
+ if (globals->splt != NULL && hash != NULL
+ && hash->root.plt.offset != (bfd_vma) -1)
+ {
+ sym_sec = globals->splt;
+ sym_value = hash->root.plt.offset;
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else
+ continue;
+ }
else
{
bfd_set_error (bfd_error_bad_value);