This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Patch for R_ARM_THM_PC22 relocs
Momchil Velikov wrote:
>
> Alan Modra wrote:
> >
> > On 28 Sep 2000, Momchil Velikov wrote:
> >
> > > --- bfd/elf32-arm.h.orig Thu Sep 28 21:03:13 2000
> > > +++ bfd/elf32-arm.h Thu Sep 28 21:03:44 2000
> > > @@ -1642,9 +1642,29 @@
> > > reloc_howto_type * howto;
> > > bfd_signed_vma increment;
> > > {
> > > - bfd_vma contents;
> > > bfd_signed_vma addend;
> > >
> > > + if (howto->type == R_ARM_THM_PC22)
> > > + {
> > > + short upper, lower;
> > > + upper = bfd_get_16 (abfd, address) & 0x7ff;
> > > + lower = bfd_get_16 (abfd, address + 2) & 0x7ff;
> > > + upper = (upper ^ 0x400) - 0x400; /* Sign extend. */
> > > +
> > > + addend = (upper << 12) | (lower << 1);
> > > + addend += increment;
> > > + addend >>= 1;
> > > +
> > > + upper = (upper & 0xf800) | ((addend >> 11) & 0x7ff);
> > > + lower = (lower & 0xf800) | (addend & 0x7ff);
> >
> > Seems to me you're trying to extract bits from upper and lower that have
> > been removed with the "& 0x7ff" above.
>
> Well, I'm an idiot, of course. And, of course, this is not
> the patch I've tested. I'll send another one.
OK, here's the correct patch.
diff -ubr binutils-000920.orig/bfd/elf32-arm.h
binutils-000920/bfd/elf32-arm.h
--- binutils-000920.orig/bfd/elf32-arm.h Sat Sep 09 02:40:08 2000
+++ binutils-000920/bfd/elf32-arm.h Fri Sep 29 09:53:42 2000
@@ -1642,9 +1642,33 @@
reloc_howto_type * howto;
bfd_signed_vma increment;
{
- bfd_vma contents;
bfd_signed_vma addend;
+ if (howto->type == R_ARM_THM_PC22)
+ {
+ short upper_insn, lower_insn;
+ short upper, lower;
+
+ upper_insn = bfd_get_16 (abfd, address);
+ lower_insn = bfd_get_16 (abfd, address + 2);
+ upper = upper_insn & 0x7ff;
+ upper = (upper ^ 0x400) - 0x400; /* Sign extend. */
+ lower = lower_insn & 0x7ff;
+
+ addend = (upper << 12) | (lower << 1);
+ addend += increment;
+ addend >>= 1;
+
+ upper_insn = (upper_insn & 0xf800) | ((addend >> 11) & 0x7ff);
+ lower_insn = (lower_insn & 0xf800) | (addend & 0x7ff);
+
+ bfd_put_16 (abfd, upper_insn, address);
+ bfd_put_16 (abfd, lower_insn, address + 2);
+ }
+ else
+ {
+ bfd_vma contents;
+
contents = bfd_get_32 (abfd, address);
/* Get the (signed) value from the instruction. */
@@ -1661,7 +1685,6 @@
/* Add in the increment, (which is a byte value). */
switch (howto->type)
{
- case R_ARM_THM_PC22:
default:
addend += increment;
break;
@@ -1680,6 +1703,7 @@
contents = (contents & ~ howto->dst_mask) | (addend &
howto->dst_mask);
bfd_put_32 (abfd, contents, address);
+ }
}
#endif /* USE_REL */