aboutsummaryrefslogtreecommitdiff
path: root/bfd/cpu-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/cpu-i386.c')
-rw-r--r--bfd/cpu-i386.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/bfd/cpu-i386.c b/bfd/cpu-i386.c
index f8991cf..4cb59ed 100644
--- a/bfd/cpu-i386.c
+++ b/bfd/cpu-i386.c
@@ -25,7 +25,8 @@
#include "libbfd.h"
#include "libiberty.h"
-extern void * bfd_arch_i386_fill (bfd_size_type, bfd_boolean, bfd_boolean);
+extern void * bfd_arch_i386_short_nop_fill (bfd_size_type, bfd_boolean,
+ bfd_boolean);
static const bfd_arch_info_type *
bfd_i386_compatible (const bfd_arch_info_type *a,
@@ -41,16 +42,16 @@ bfd_i386_compatible (const bfd_arch_info_type *a,
return compat;
}
-/* Fill the buffer with zero or nop instruction if CODE is TRUE. */
+/* Fill the buffer with zero or nop instruction if CODE is TRUE. Use
+ multi byte nop instructions if LONG_NOP is TRUE. */
-void *
-bfd_arch_i386_fill (bfd_size_type count,
- bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
- bfd_boolean code)
+static void *
+bfd_arch_i386_fill (bfd_size_type count, bfd_boolean code,
+ bfd_boolean long_nop)
{
/* nop */
static const char nop_1[] = { 0x90 };
- /* nopw */
+ /* xchg %ax,%ax */
static const char nop_2[] = { 0x66, 0x90 };
/* nopl (%[re]ax) */
static const char nop_3[] = { 0x0f, 0x1f, 0x00 };
@@ -74,6 +75,7 @@ bfd_arch_i386_fill (bfd_size_type count,
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 };
+ bfd_size_type nop_size = long_nop ? ARRAY_SIZE (nops) : 2;
void *fill = bfd_malloc (count);
if (fill == NULL)
@@ -82,11 +84,11 @@ bfd_arch_i386_fill (bfd_size_type count,
if (code)
{
bfd_byte *p = fill;
- while (count >= ARRAY_SIZE (nops))
+ while (count >= nop_size)
{
- memcpy (p, nops[ARRAY_SIZE (nops) - 1], ARRAY_SIZE (nops));
- p += ARRAY_SIZE (nops);
- count -= ARRAY_SIZE (nops);
+ memcpy (p, nops[nop_size - 1], nop_size);
+ p += nop_size;
+ count -= nop_size;
}
if (count != 0)
memcpy (p, nops[count - 1], count);
@@ -97,6 +99,26 @@ bfd_arch_i386_fill (bfd_size_type count,
return fill;
}
+/* Fill the buffer with zero or short nop instruction if CODE is TRUE. */
+
+void *
+bfd_arch_i386_short_nop_fill (bfd_size_type count,
+ bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
+ bfd_boolean code)
+{
+ return bfd_arch_i386_fill (count, code, FALSE);
+}
+
+/* Fill the buffer with zero or long nop instruction if CODE is TRUE. */
+
+static void *
+bfd_arch_i386_long_nop_fill (bfd_size_type count,
+ bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
+ bfd_boolean code)
+{
+ return bfd_arch_i386_fill (count, code, TRUE);
+}
+
static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
{
64, /* 64 bits in a word */
@@ -110,7 +132,7 @@ static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
FALSE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_long_nop_fill,
0
};
@@ -127,7 +149,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_arch_i386_long_nop_fill,
&bfd_x64_32_arch_intel_syntax,
};
@@ -144,7 +166,7 @@ static const bfd_arch_info_type bfd_i386_arch_intel_syntax =
TRUE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_short_nop_fill,
&bfd_x86_64_arch_intel_syntax
};
@@ -161,7 +183,7 @@ static const bfd_arch_info_type i8086_arch =
FALSE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_short_nop_fill,
&bfd_i386_arch_intel_syntax
};
@@ -178,7 +200,7 @@ static const bfd_arch_info_type bfd_x64_32_arch =
FALSE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_long_nop_fill,
&i8086_arch
};
@@ -195,7 +217,7 @@ static const bfd_arch_info_type bfd_x86_64_arch =
FALSE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_long_nop_fill,
&bfd_x64_32_arch
};
@@ -212,6 +234,6 @@ const bfd_arch_info_type bfd_i386_arch =
TRUE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_short_nop_fill,
&bfd_x86_64_arch
};