diff options
author | Christophe Lyon <christophe.lyon@st.com> | 2009-06-22 10:55:33 +0000 |
---|---|---|
committer | Christophe Lyon <christophe.lyon@st.com> | 2009-06-22 10:55:33 +0000 |
commit | 022f83127a7d608506b67ae5b7ce7960c446895d (patch) | |
tree | b40846b791fcba677a33c299516e68cc5f7097d4 /bfd/elf32-arm.c | |
parent | 11275b5ad5433ffa55d7b1331c102be58250d3d8 (diff) | |
download | gdb-022f83127a7d608506b67ae5b7ce7960c446895d.zip gdb-022f83127a7d608506b67ae5b7ce7960c446895d.tar.gz gdb-022f83127a7d608506b67ae5b7ce7960c446895d.tar.bz2 |
2009-06-22 Christophe Lyon <christophe.lyon@st.com>
bfd/
* elf32-arm.c (elf32_arm_size_stubs): Use PLT address as
destination for defined dynamic symbols when deciding whether to
insert a stub or not.
(allocate_dynrelocs): Make sure functions are not marked as Thumb
when actually accessed through a PLT, even when generating a
shared lib.
ld/testsuite:
* ld-arm/farcall-mixed-app.s: Add new references to check more
modes switching.
* ld-arm/farcall-mixed-lib1.s: Likewise.
* ld-arm/farcall-mixed-app-v5.d: Update expected result.
* farcall-mixed-app.d: Likewise.
* ld-arm/farcall-mixed-lib.d: Likewise.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r-- | bfd/elf32-arm.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index bdb895a..cd40eef 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -4361,7 +4361,25 @@ elf32_arm_size_stubs (bfd *output_bfd, { sym_sec = hash->root.root.u.def.section; sym_value = hash->root.root.u.def.value; - if (sym_sec->output_section != NULL) + + struct elf32_arm_link_hash_table *globals = + elf32_arm_hash_table (info); + + /* For a destination in a shared library, + use the PLT stub as target address to + decide whether a branch stub is + needed. */ + 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 if (sym_sec->output_section != NULL) destination = (sym_value + irela->r_addend + sym_sec->output_offset + sym_sec->output_section->vma); @@ -11277,14 +11295,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) { h->root.u.def.section = s; h->root.u.def.value = h->plt.offset; - - /* Make sure the function is not marked as Thumb, in case - it is the target of an ABS32 relocation, which will - point to the PLT entry. */ - if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) - h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC); } + /* Make sure the function is not marked as Thumb, in case + it is the target of an ABS32 relocation, which will + point to the PLT entry. */ + if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) + h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC); + /* Make room for this entry. */ s->size += htab->plt_entry_size; |