diff options
author | Nick Clifton <nickc@redhat.com> | 1999-08-19 10:12:28 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 1999-08-19 10:12:28 +0000 |
commit | 98c1d4aab729f61101ac21f24f0c946cb5ceac23 (patch) | |
tree | 0c1889e228bd4bac0a4cd5800abbebaf30d2831c /bfd/elf32-arm.h | |
parent | cd5d26f264f5ecd2c14b57ed4999fc687eaa3a94 (diff) | |
download | gdb-98c1d4aab729f61101ac21f24f0c946cb5ceac23.zip gdb-98c1d4aab729f61101ac21f24f0c946cb5ceac23.tar.gz gdb-98c1d4aab729f61101ac21f24f0c946cb5ceac23.tar.bz2 |
Fix partial REL relocs.
Diffstat (limited to 'bfd/elf32-arm.h')
-rw-r--r-- | bfd/elf32-arm.h | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index da7217a..0dc397b 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -1581,6 +1581,45 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, } } +#ifdef USE_REL +/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. */ +static void +arm_add_to_rel (abfd, address, howto, increment) + bfd * abfd; + bfd_vma address; + reloc_howto_type * howto; + bfd_signed_vma increment; +{ + bfd_vma contents; + bfd_signed_vma addend; + + contents = bfd_get_32 (abfd, address); + + /* Get the (signed) value from the instruction. */ + addend = contents & howto->src_mask; + if (addend & ((howto->src_mask + 1) >> 1)) + { + bfd_signed_vma mask; + + mask = -1; + mask &= ~ howto->src_mask; + addend |= mask; + } + + /* Add in the increment, (which is a byte value). */ + addend <<= howto->size; + addend += increment; + + /* Should we check for overflow here ? */ + + /* Drop any undesired bits. */ + addend >>= howto->rightshift; + + contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask); + + bfd_put_32 (abfd, contents, address); +} +#endif /* USE_REL */ /* Relocate an ARM ELF section. */ static boolean @@ -1641,18 +1680,8 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, { sec = local_sections[r_symndx]; #ifdef USE_REL - { - bfd_vma val; - bfd_vma insn; - - insn = bfd_get_32 (input_bfd, contents + rel->r_offset); - val = insn + ((sec->output_offset + sym->st_value) - >> howto->rightshift); - val &= howto->dst_mask; - val |= insn & ~(howto->dst_mask); - - bfd_put_32 (input_bfd, val, contents + rel->r_offset); - } + arm_add_to_rel (input_bfd, contents + rel->r_offset, + howto, sec->output_offset + sym->st_value); #else rel->r_addend += (sec->output_offset + sym->st_value) >> howto->rightshift; |