diff options
author | Paul Brook <paul@codesourcery.com> | 2011-05-31 13:37:27 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2011-05-31 13:37:27 +0000 |
commit | 12352d3f854285aaaecf6bc89df80e6247968a63 (patch) | |
tree | b84ebdb4a945751576354d7572cb36abdd466fc2 /bfd/elf32-arm.c | |
parent | 1ab52cbe0549166fc916f60dc4e666c97ad8b113 (diff) | |
download | gdb-12352d3f854285aaaecf6bc89df80e6247968a63.zip gdb-12352d3f854285aaaecf6bc89df80e6247968a63.tar.gz gdb-12352d3f854285aaaecf6bc89df80e6247968a63.tar.bz2 |
2011-05-31 Paul Brook <paul@codesourcery.com>
bfd/
* elf32-arm.c (arm_stub_is_thumb): Add
arm_stub_long_branch_v4t_thumb_tls_pic.
(elf32_arm_final_link_relocate): TLS stubs are always ARM.
Handle Thumb stubs.
ld/testsuite/
* ld-arm/tls-longplt.d: Update expected output.
* ld-arm/tls-thumb1.d: Ditto.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r-- | bfd/elf32-arm.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 671a209..611e08e 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -3427,6 +3427,7 @@ arm_stub_is_thumb (enum elf32_arm_stub_type stub_type) case arm_stub_long_branch_v4t_thumb_arm: case arm_stub_short_branch_v4t_thumb_arm: case arm_stub_long_branch_v4t_thumb_arm_pic: + case arm_stub_long_branch_v4t_thumb_tls_pic: case arm_stub_long_branch_thumb_only_pic: return TRUE; case arm_stub_none: @@ -9304,6 +9305,9 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, || ELF32_R_TYPE(rel->r_info) == R_ARM_THM_TLS_CALL) { bfd_signed_vma offset; + /* TLS stubs are arm mode. The original symbol is a + data object, so branch_type is bogus. */ + branch_type = ST_BRANCH_TO_ARM; enum elf32_arm_stub_type stub_type = arm_type_of_stub (info, input_section, rel, st_type, &branch_type, @@ -9348,16 +9352,25 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, input_section->output_offset + rel->r_offset + 4); - /* Round up the offset to a word boundary */ - offset = (offset + 2) & ~2; + if (stub_type != arm_stub_none + && arm_stub_is_thumb (stub_type)) + { + lower_insn = 0xd000; + } + else + { + lower_insn = 0xc000; + /* Round up the offset to a word boundary */ + offset = (offset + 2) & ~2; + } + neg = offset < 0; upper_insn = (0xf000 | ((offset >> 12) & 0x3ff) | (neg << 10)); - lower_insn = (0xc000 - | (((!((offset >> 23) & 1)) ^ neg) << 13) + lower_insn |= (((!((offset >> 23) & 1)) ^ neg) << 13) | (((!((offset >> 22) & 1)) ^ neg) << 11) - | ((offset >> 1) & 0x7ff)); + | ((offset >> 1) & 0x7ff); bfd_put_16 (input_bfd, upper_insn, hit_data); bfd_put_16 (input_bfd, lower_insn, hit_data + 2); return bfd_reloc_ok; |