(arm_add_to_rel): Fix R_ARM_THM_PC22 relocations.

This commit is contained in:
Alan Modra 2000-09-29 13:51:49 +00:00
parent 5cc18311d9
commit 9a5aca8c9c
2 changed files with 94 additions and 66 deletions

View File

@ -1,3 +1,8 @@
2000-09-29 Momchil Velikov <velco@fadata.bg>
* elf32-arm.h (arm_add_to_rel): Correctly adjust the addend for
R_ARM_THM_PC22 relocations.
2000-09-29 NIIBE Yutaka <gniibe@chroot.org>
* elflink.h (elf_link_add_object_symbols): Don't bfd_release runpath.

View File

@ -1642,44 +1642,67 @@ arm_add_to_rel (abfd, address, howto, increment)
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))
if (howto->type == R_ARM_THM_PC22)
{
bfd_signed_vma mask;
int upper_insn, lower_insn;
int upper, lower;
mask = -1;
mask &= ~ howto->src_mask;
addend |= mask;
}
upper_insn = bfd_get_16 (abfd, address);
lower_insn = bfd_get_16 (abfd, address + 2);
upper = upper_insn & 0x7ff;
lower = lower_insn & 0x7ff;
/* Add in the increment, (which is a byte value). */
switch (howto->type)
{
case R_ARM_THM_PC22:
default:
addend = (upper << 12) | (lower << 1);
addend += increment;
break;
addend >>= 1;
case R_ARM_PC24:
addend <<= howto->size;
addend += increment;
upper_insn = (upper_insn & 0xf800) | ((addend >> 11) & 0x7ff);
lower_insn = (lower_insn & 0xf800) | (addend & 0x7ff);
/* Should we check for overflow here ? */
/* Drop any undesired bits. */
addend >>= howto->rightshift;
break;
bfd_put_16 (abfd, upper_insn, address);
bfd_put_16 (abfd, lower_insn, address + 2);
}
else
{
bfd_vma contents;
contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask);
contents = bfd_get_32 (abfd, address);
bfd_put_32 (abfd, contents, 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). */
switch (howto->type)
{
default:
addend += increment;
break;
case R_ARM_PC24:
addend <<= howto->size;
addend += increment;
/* Should we check for overflow here ? */
/* Drop any undesired bits. */
addend >>= howto->rightshift;
break;
}
contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask);
bfd_put_32 (abfd, contents, address);
}
}
#endif /* USE_REL */