diff options
author | Daniel Jacobowitz <dan@debian.org> | 2010-05-07 18:24:44 +0000 |
---|---|---|
committer | Daniel Jacobowitz <dan@debian.org> | 2010-05-07 18:24:44 +0000 |
commit | dbcbaeb953d9e2e318c481c5f636be20aaf86f9d (patch) | |
tree | e8cee56095196923d9aec7499db50f5f61172234 /bfd/elf32-arm.c | |
parent | 79d1092f5e4d31c1549cbba945413f715376fe33 (diff) | |
download | gdb-dbcbaeb953d9e2e318c481c5f636be20aaf86f9d.tar.gz |
bfd/
* elf32-arm.c (struct a8_erratum_reloc): Add hash member. Move
sym_name to improve packing.
(cortex_a8_erratum_scan): Check for PLT entries.
(elf32_arm_size_stubs): Save the target symbol for a8 relocs.
ld/testsuite/
* ld-arm/cortex-a8-fix-bl-rel-plt.d: New file.
* ld-arm/arm-elf.exp (armelftests): Run cortex-a8-fix-bl-rel-plt.d.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r-- | bfd/elf32-arm.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 2c24bddc102..18fddc68ccb 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2409,9 +2409,10 @@ struct a8_erratum_fix { struct a8_erratum_reloc { bfd_vma from; bfd_vma destination; + struct elf32_arm_link_hash_entry *hash; + const char *sym_name; unsigned int r_type; unsigned char st_type; - const char *sym_name; bfd_boolean non_a8_stub; }; @@ -4101,6 +4102,7 @@ cortex_a8_erratum_scan (bfd *input_bfd, { char *error_message = NULL; struct elf_link_hash_entry *entry; + bfd_boolean use_plt = FALSE; /* We don't care about the error returned from this function, only if there is glue or not. */ @@ -4110,12 +4112,18 @@ cortex_a8_erratum_scan (bfd *input_bfd, if (entry) found->non_a8_stub = TRUE; - if (found->r_type == R_ARM_THM_CALL - && found->st_type != STT_ARM_TFUNC) - force_target_arm = TRUE; - else if (found->r_type == R_ARM_THM_CALL - && found->st_type == STT_ARM_TFUNC) - force_target_thumb = TRUE; + /* Keep a simpler condition, for the sake of clarity. */ + if (htab->splt != NULL && found->hash != NULL + && found->hash->root.plt.offset != (bfd_vma) -1) + use_plt = TRUE; + + if (found->r_type == R_ARM_THM_CALL) + { + if (found->st_type != STT_ARM_TFUNC || use_plt) + force_target_arm = TRUE; + else + force_target_thumb = TRUE; + } } /* Check if we have an offending branch instruction. */ @@ -4682,6 +4690,7 @@ elf32_arm_size_stubs (bfd *output_bfd, a8_relocs[num_a8_relocs].st_type = st_type; a8_relocs[num_a8_relocs].sym_name = sym_name; a8_relocs[num_a8_relocs].non_a8_stub = created_stub; + a8_relocs[num_a8_relocs].hash = hash; num_a8_relocs++; } |