This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

bfd_arch_info.fill vs ARM (bug 13616)


I took a crack at adding the ARM support for fixing bug 13616.  But I think
the new hook's signature passes insufficient information for all cases.
It's easy to get right for 32-bit ARM.  But the hook has no way to know
whether the preceding code was ARM or Thumb.

I'm not even really sure how you're supposed to determine that.  Best I can
figure is you're supposed to look at the symbol table for symbols named
"$a" or "$t" in that section, the highest-addressed of those indicating
which mode was being assembled at the end of the section.

Whatever the details, it seems certain it will require that the hook get at
least the asection pointer.


Thanks,
Roland


--- a/bfd/cpu-arm.c
+++ b/bfd/cpu-arm.c
@@ -123,9 +123,72 @@ scan (const struct bfd_arch_info *info, 
   return FALSE;
 }
 
+#define ARM_NOP 	0xe1a00000
+#define THUMB_NOP 	0x46c0
+#define THUMB_NOP_W 	0xf3af8000
+
+/* Fill the buffer with zero, or with nop instruction if CODE is TRUE.  */
+static void *
+bfd_arch_arm_fill (bfd_size_type count,
+                   bfd_boolean is_bigendian,
+                   bfd_boolean code)
+{
+  if (!code)
+    return bfd_arch_default_fill (count, is_bigendian, code);
+  else
+    {
+      void *fill = bfd_malloc (count);
+      if (fill != NULL)
+        {
+          bfd_byte *p = fill;
+          while (count >= 4)
+            {
+              (is_bigendian ? bfd_putb32 : bfd_putl32) (ARM_NOP, p);
+              p += 4;
+              count -= 4;
+            }
+          memset (p, 0, count);
+        }
+      return fill;
+    }
+}
+
+#if 0
+static void *
+bfd_arch_thumb_fill (bfd_size_type count,
+                     bfd_boolean is_bigendian,
+                     bfd_boolean code)
+{
+  if (!code)
+    return bfd_arch_default_fill (count, is_bigendian, code);
+  else
+    {
+      void *fill = bfd_malloc (count);
+      if (fill != NULL)
+        {
+          bfd_byte *p = fill;
+          while (count >= 4)
+            {
+              (is_bigendian ? bfd_putb32 : bfd_putl32) (THUMB_NOP_W, p);
+              p += 4;
+              count -= 4;
+            }
+          while (count >= 2)
+            {
+              (is_bigendian ? bfd_putb16 : bfd_putl16) (THUMB_NOP, p);
+              p += 2;
+              count -= 2;
+            }
+          memset (p, 0, count);
+        }
+      return fill;
+    }
+}
+#endif
+
 #define N(number, print, default, next)  \
 {  32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, \
-   scan, bfd_arch_default_fill, next }
+   scan, bfd_arch_arm_fill, next }
 
 static const bfd_arch_info_type arch_info_struct[] =
 {


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