This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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 */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]