Support arch-dependent fill
[deliverable/binutils-gdb.git] / bfd / cpu-i386.c
index f98c0e50529a74432ee797db0e9c4e11939310b3..f8991cf1ec438cae87e4fa8bc527b13221e5dee4 100644 (file)
@@ -23,6 +23,9 @@
 #include "sysdep.h"
 #include "bfd.h"
 #include "libbfd.h"
+#include "libiberty.h"
+
+extern void * bfd_arch_i386_fill (bfd_size_type, bfd_boolean, bfd_boolean);
 
 static const bfd_arch_info_type *
 bfd_i386_compatible (const bfd_arch_info_type *a,
@@ -38,6 +41,62 @@ bfd_i386_compatible (const bfd_arch_info_type *a,
   return compat;
 }
 
+/* Fill the buffer with zero or nop instruction if CODE is TRUE.  */
+
+void *
+bfd_arch_i386_fill (bfd_size_type count,
+                   bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
+                   bfd_boolean code)
+{
+  /* nop */
+  static const char nop_1[] = { 0x90 };        
+  /* nopw */
+  static const char nop_2[] = { 0x66, 0x90 };
+  /* nopl (%[re]ax) */
+  static const char nop_3[] = { 0x0f, 0x1f, 0x00 };
+  /* nopl 0(%[re]ax) */
+  static const char nop_4[] = { 0x0f, 0x1f, 0x40, 0x00 };
+  /* nopl 0(%[re]ax,%[re]ax,1) */
+  static const char nop_5[] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 };
+  /* nopw 0(%[re]ax,%[re]ax,1) */
+  static const char nop_6[] = { 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 };
+  /* nopl 0L(%[re]ax) */
+  static const char nop_7[] = { 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00 };
+  /* nopl 0L(%[re]ax,%[re]ax,1) */
+  static const char nop_8[] =
+    { 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
+  /* nopw 0L(%[re]ax,%[re]ax,1) */
+  static const char nop_9[] =
+    { 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
+  /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
+  static const char nop_10[] =
+    { 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
+  static const char *const nops[] =
+    { nop_1, nop_2, nop_3, nop_4, nop_5,
+      nop_6, nop_7, nop_8, nop_9, nop_10 };
+
+  void *fill = bfd_malloc (count);
+  if (fill == NULL)
+    return fill;
+
+  if (code)
+    {
+      bfd_byte *p = fill;
+      while (count >= ARRAY_SIZE (nops))
+       {
+         memcpy (p, nops[ARRAY_SIZE (nops) - 1], ARRAY_SIZE (nops));
+         p += ARRAY_SIZE (nops);
+         count -= ARRAY_SIZE (nops);
+       }
+      if (count != 0)
+       memcpy (p, nops[count - 1], count);
+    }
+  else
+    memset (fill, 0, count);
+
+  return fill;
+}
+
 static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
 {
   64, /* 64 bits in a word */
@@ -51,6 +110,7 @@ static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
   FALSE,
   bfd_i386_compatible,
   bfd_default_scan,
+  bfd_arch_i386_fill,
   0
 };
 
@@ -67,6 +127,7 @@ static const bfd_arch_info_type bfd_x86_64_arch_intel_syntax =
   FALSE,
   bfd_i386_compatible,
   bfd_default_scan,
+  bfd_arch_i386_fill,
   &bfd_x64_32_arch_intel_syntax,
 };
 
@@ -83,6 +144,7 @@ static const bfd_arch_info_type bfd_i386_arch_intel_syntax =
   TRUE,
   bfd_i386_compatible,
   bfd_default_scan,
+  bfd_arch_i386_fill,
   &bfd_x86_64_arch_intel_syntax
 };
 
@@ -99,6 +161,7 @@ static const bfd_arch_info_type i8086_arch =
   FALSE,
   bfd_i386_compatible,
   bfd_default_scan,
+  bfd_arch_i386_fill,
   &bfd_i386_arch_intel_syntax
 };
 
@@ -115,6 +178,7 @@ static const bfd_arch_info_type bfd_x64_32_arch =
   FALSE,
   bfd_i386_compatible,
   bfd_default_scan,
+  bfd_arch_i386_fill,
   &i8086_arch
 };
 
@@ -131,6 +195,7 @@ static const bfd_arch_info_type bfd_x86_64_arch =
   FALSE,
   bfd_i386_compatible,
   bfd_default_scan,
+  bfd_arch_i386_fill,
   &bfd_x64_32_arch
 };
 
@@ -147,5 +212,6 @@ const bfd_arch_info_type bfd_i386_arch =
   TRUE,
   bfd_i386_compatible,
   bfd_default_scan,
+  bfd_arch_i386_fill,
   &bfd_x86_64_arch
 };
This page took 0.024273 seconds and 4 git commands to generate.