diff options
author | Paul Brook <paul@codesourcery.com> | 2007-06-29 15:05:47 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2007-06-29 15:05:47 +0000 |
commit | 5ab79981933708d465b91676baf6994996979da8 (patch) | |
tree | 0a568768ea8df53fb6ba1afb1b055e99f1ca73aa | |
parent | 32e8a950c4e551038786bc4980dcb9fbfb8384b0 (diff) | |
download | gdb-5ab79981933708d465b91676baf6994996979da8.zip gdb-5ab79981933708d465b91676baf6994996979da8.tar.gz gdb-5ab79981933708d465b91676baf6994996979da8.tar.bz2 |
2007-06-29 Paul Brook <paul@codesourcery.com>
bfd/
* elf32-arm.c (bfd_elf32_arm_process_before_allocation): Suppress
call veneers for call relocations against undefined symbols.
(elf32_arm_final_link_relocate): Turn call to undefined symbol
into a jump to the next instruction.
ld/testuite/
* ld-arm/arm-elf.exp (armelftests): Add callweak.
* ld-arm/callweak.d: New test.
* ld-arm/callweak.s: New test.
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 63 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/arm-elf.exp | 3 |
4 files changed, 54 insertions, 25 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ad71032..1f7f5c4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2007-06-29 Paul Brook <paul@codesourcery.com> + + * elf32-arm.c (bfd_elf32_arm_process_before_allocation): Suppress + call veneers for call relocations against undefined symbols. + (elf32_arm_final_link_relocate): Turn call to undefined symbol + into a jump to the next instruction. + 2007-06-29 Michael Snyder <msnyder@svkmacdonelllnx> * bfd.c (bfd_demangle): Plug memory leak (Coverity). diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index bf4f49f..a213bab 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -3236,7 +3236,8 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd, /* This one is a call from thumb code. We look up the target of the call. If it is not a thumb target, we insert glue. */ - if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC && !globals->use_blx) + if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC && !globals->use_blx + && h->root.type != bfd_link_hash_undefweak) record_thumb_to_arm_glue (link_info, h); break; @@ -4812,40 +4813,43 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, signed_addend = value; signed_addend >>= howto->rightshift; - /* It is not an error for an undefined weak reference to be - out of range. Any program that branches to such a symbol - is going to crash anyway, so there is no point worrying - about getting the destination exactly right. */ - if (! h || h->root.type != bfd_link_hash_undefweak) + /* A branch to an undefined weak symbol is turned into a jump to + the next instruction. */ + if (h && h->root.type == bfd_link_hash_undefweak) + { + value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000) + | 0x0affffff; + } + else { /* Perform a signed range check. */ if ( signed_addend > ((bfd_signed_vma) (howto->dst_mask >> 1)) || signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1))) return bfd_reloc_overflow; - } - addend = (value & 2); + addend = (value & 2); - value = (signed_addend & howto->dst_mask) - | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask)); + value = (signed_addend & howto->dst_mask) + | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask)); - /* Set the H bit in the BLX instruction. */ - if (sym_flags == STT_ARM_TFUNC) - { - if (addend) - value |= (1 << 24); - else - value &= ~(bfd_vma)(1 << 24); - } - if (r_type == R_ARM_CALL) - { - /* Select the correct instruction (BL or BLX). */ + /* Set the H bit in the BLX instruction. */ if (sym_flags == STT_ARM_TFUNC) - value |= (1 << 28); - else { - value &= ~(bfd_vma)(1 << 28); - value |= (1 << 24); + if (addend) + value |= (1 << 24); + else + value &= ~(bfd_vma)(1 << 24); + } + if (r_type == R_ARM_CALL) + { + /* Select the correct instruction (BL or BLX). */ + if (sym_flags == STT_ARM_TFUNC) + value |= (1 << 28); + else + { + value &= ~(bfd_vma)(1 << 28); + value |= (1 << 24); + } } } break; @@ -5022,6 +5026,15 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, int bitsize; int thumb2 = using_thumb2 (globals); + /* A branch to an undefined weak symbol is turned into a jump to + the next instruction. */ + if (h && h->root.type == bfd_link_hash_undefweak) + { + bfd_put_16 (input_bfd, 0xe000, hit_data); + bfd_put_16 (input_bfd, 0xbf00, hit_data + 2); + return bfd_reloc_ok; + } + /* Fetch the addend. We use the Thumb-2 encoding (backwards compatible with Thumb-1) involving the J1 and J2 bits. */ if (globals->use_rel) diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index f0a5de3..cd4281d 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-06-29 Paul Brook <paul@codesourcery.com> + + * ld-arm/arm-elf.exp (armelftests): Add callweak. + * ld-arm/callweak.d: New test. + * ld-arm/callweak.s: New test. + 2007-06-28 H.J. Lu <hongjiu.lu@intel.com> PR ld/4701 diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 087225f..a83c1ee 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -170,6 +170,9 @@ set armelftests { {"EABI attribute merging" "-r" "" {attr-merge.s attr-merge.s} {{readelf -A attr-merge.attr}} "attr-merge"} + {"callweak" "-static -T arm.ld" "" {callweak.s} + {{objdump -dr callweak.d}} + "callweak"} } run_ld_link_tests $armelftests |