summaryrefslogtreecommitdiff
path: root/bfd/elf32-arm.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2010-05-07 18:24:44 +0000
committerDaniel Jacobowitz <dan@debian.org>2010-05-07 18:24:44 +0000
commitdbcbaeb953d9e2e318c481c5f636be20aaf86f9d (patch)
treee8cee56095196923d9aec7499db50f5f61172234 /bfd/elf32-arm.c
parent79d1092f5e4d31c1549cbba945413f715376fe33 (diff)
downloadgdb-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.c23
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++;
}