(arm_add_to_rel): Fix R_ARM_THM_PC22 relocations.
This commit is contained in:
parent
5cc18311d9
commit
9a5aca8c9c
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue