+2012-02-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13675
+ * cpu-i386.c (bfd_arch_i386_fill): Updated to support multi byte
+ nop instructions.
+ (bfd_arch_i386_short_nop_fill): New.
+ (bfd_arch_i386_long_nop_fill): Likewise.
+ Use bfd_arch_i386_short_nop_fill in 32bit bfd_arch_info
+ initializers. Use bfd_arch_i386_long_nop_fill on 64bit
+ bfd_arch_info initializers.
+
+ * cpu-k1om.c (bfd_arch_i386_fill): Renamed to ...
+ (bfd_arch_i386_short_nop_fill): This.
+ Update bfd_arch_info initializers.
+ * cpu-l1om.c: Likewise.
+
2012-02-08 Alan Modra <amodra@gmail.com>
* elflink.c (_bfd_elf_gc_mark_rsec): Mark weakdef syms too.
#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,
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 };
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)
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);
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 */
FALSE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_long_nop_fill,
0
};
FALSE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_long_nop_fill,
&bfd_x64_32_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
};
FALSE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_short_nop_fill,
&bfd_i386_arch_intel_syntax
};
FALSE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_long_nop_fill,
&i8086_arch
};
FALSE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_long_nop_fill,
&bfd_x64_32_arch
};
TRUE,
bfd_i386_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_short_nop_fill,
&bfd_x86_64_arch
};