diff options
author | Christophe Lyon <christophe.lyon@st.com> | 2009-04-17 13:04:41 +0000 |
---|---|---|
committer | Christophe Lyon <christophe.lyon@st.com> | 2009-04-17 13:04:41 +0000 |
commit | 69c5861ee1e736adf16998ba505b5054fc633f3f (patch) | |
tree | 2b86ed0ec632978d7b49d94483b24e2ea43351a1 /bfd/elf32-arm.c | |
parent | e9cd066073fafdb8e7824beb32561935134d7113 (diff) | |
download | gdb-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.c | 29 |
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); |