| Index: bfd/cpu-i386.c
|
| diff --git a/bfd/cpu-i386.c b/bfd/cpu-i386.c
|
| index f98c0e50529a74432ee797db0e9c4e11939310b3..4cb59ed8981527ac94896d8054184c97bf96f9ad 100644
|
| --- a/bfd/cpu-i386.c
|
| +++ b/bfd/cpu-i386.c
|
| @@ -23,6 +23,10 @@
|
| #include "sysdep.h"
|
| #include "bfd.h"
|
| #include "libbfd.h"
|
| +#include "libiberty.h"
|
| +
|
| +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,
|
| @@ -38,6 +42,83 @@ bfd_i386_compatible (const bfd_arch_info_type *a,
|
| return compat;
|
| }
|
|
|
| +/* Fill the buffer with zero or nop instruction if CODE is TRUE. Use
|
| + multi byte nop instructions if LONG_NOP is TRUE. */
|
| +
|
| +static void *
|
| +bfd_arch_i386_fill (bfd_size_type count, bfd_boolean code,
|
| + bfd_boolean long_nop)
|
| +{
|
| + /* nop */
|
| + static const char nop_1[] = { 0x90 };
|
| + /* xchg %ax,%ax */
|
| + 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 };
|
| + bfd_size_type nop_size = long_nop ? ARRAY_SIZE (nops) : 2;
|
| +
|
| + void *fill = bfd_malloc (count);
|
| + if (fill == NULL)
|
| + return fill;
|
| +
|
| + if (code)
|
| + {
|
| + bfd_byte *p = fill;
|
| + while (count >= nop_size)
|
| + {
|
| + memcpy (p, nops[nop_size - 1], nop_size);
|
| + p += nop_size;
|
| + count -= nop_size;
|
| + }
|
| + if (count != 0)
|
| + memcpy (p, nops[count - 1], count);
|
| + }
|
| + else
|
| + memset (fill, 0, 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 */
|
| @@ -51,6 +132,7 @@ static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
|
| FALSE,
|
| bfd_i386_compatible,
|
| bfd_default_scan,
|
| + bfd_arch_i386_long_nop_fill,
|
| 0
|
| };
|
|
|
| @@ -67,6 +149,7 @@ static const bfd_arch_info_type bfd_x86_64_arch_intel_syntax =
|
| FALSE,
|
| bfd_i386_compatible,
|
| bfd_default_scan,
|
| + bfd_arch_i386_long_nop_fill,
|
| &bfd_x64_32_arch_intel_syntax,
|
| };
|
|
|
| @@ -83,6 +166,7 @@ static const bfd_arch_info_type bfd_i386_arch_intel_syntax =
|
| TRUE,
|
| bfd_i386_compatible,
|
| bfd_default_scan,
|
| + bfd_arch_i386_short_nop_fill,
|
| &bfd_x86_64_arch_intel_syntax
|
| };
|
|
|
| @@ -99,6 +183,7 @@ static const bfd_arch_info_type i8086_arch =
|
| FALSE,
|
| bfd_i386_compatible,
|
| bfd_default_scan,
|
| + bfd_arch_i386_short_nop_fill,
|
| &bfd_i386_arch_intel_syntax
|
| };
|
|
|
| @@ -115,6 +200,7 @@ static const bfd_arch_info_type bfd_x64_32_arch =
|
| FALSE,
|
| bfd_i386_compatible,
|
| bfd_default_scan,
|
| + bfd_arch_i386_long_nop_fill,
|
| &i8086_arch
|
| };
|
|
|
| @@ -131,6 +217,7 @@ static const bfd_arch_info_type bfd_x86_64_arch =
|
| FALSE,
|
| bfd_i386_compatible,
|
| bfd_default_scan,
|
| + bfd_arch_i386_long_nop_fill,
|
| &bfd_x64_32_arch
|
| };
|
|
|
| @@ -147,5 +234,6 @@ const bfd_arch_info_type bfd_i386_arch =
|
| TRUE,
|
| bfd_i386_compatible,
|
| bfd_default_scan,
|
| + bfd_arch_i386_short_nop_fill,
|
| &bfd_x86_64_arch
|
| };
|
|
|