From 5fa1e0349c984516bfd5786d000f1eb787e414ea Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 12 Sep 2002 13:18:57 +0000 Subject: [PATCH] Fix handling of R_ARM_THM_PC11 --- bfd/ChangeLog | 5 +++++ bfd/elf32-arm.h | 31 +++++++++++++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8a84296e83..5b825a2a3f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2002-09-12 Nick Clifton + + * elf32-arm.h (elf32_arm_final_link_relocate): Fix handling of + R_ARM_THM_PC11. + 2002-09-11 Andrew Haley * elf.c (_bfd_elf_find_nearest_line): Check functionname_ptr and diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 5cd94347c3..e8538ac3ff 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -1501,33 +1501,36 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, case R_ARM_THM_PC11: /* Thumb B (branch) instruction). */ { - bfd_vma relocation; + bfd_signed_vma relocation; bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; bfd_signed_vma reloc_signed_min = ~ reloc_signed_max; - bfd_vma check; bfd_signed_vma signed_check; #ifdef USE_REL /* Need to refetch addend. */ addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask; - /* ??? Need to determine shift amount from operand size. */ - addend >>= howto->rightshift; + if (addend & ((howto->src_mask + 1) >> 1)) + { + signed_addend = -1; + signed_addend &= ~ howto->src_mask; + signed_addend |= addend; + } + else + signed_addend = addend; + /* The value in the insn has been right shifted. We need to + undo this, so that we can perform the address calculation + in terms of bytes. */ + signed_addend <<= howto->rightshift; #endif - relocation = value + addend; + relocation = value + signed_addend; relocation -= (input_section->output_section->vma + input_section->output_offset + rel->r_offset); - check = relocation >> howto->rightshift; - - /* If this is a signed value, the rightshift just - dropped leading 1 bits (assuming twos complement). */ - if ((bfd_signed_vma) relocation >= 0) - signed_check = check; - else - signed_check = check | ~((bfd_vma) -1 >> howto->rightshift); - + relocation >>= howto->rightshift; + signed_check = relocation; + relocation &= howto->dst_mask; relocation |= (bfd_get_16 (input_bfd, hit_data) & (~ howto->dst_mask)); bfd_put_16 (input_bfd, relocation, hit_data); -- 2.11.0