aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog16
-rw-r--r--bfd/cpu-i386.c58
-rw-r--r--bfd/cpu-k1om.c7
-rw-r--r--bfd/cpu-l1om.c7
4 files changed, 64 insertions, 24 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4b896f2..d85c9f5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,19 @@
+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.
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
};
diff --git a/bfd/cpu-k1om.c b/bfd/cpu-k1om.c
index f9958e4..54b6e58 100644
--- a/bfd/cpu-k1om.c
+++ b/bfd/cpu-k1om.c
@@ -23,7 +23,8 @@
#include "bfd.h"
#include "libbfd.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_k1om_arch_intel_syntax =
{
@@ -38,7 +39,7 @@ static const bfd_arch_info_type bfd_k1om_arch_intel_syntax =
TRUE,
bfd_default_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_short_nop_fill,
0
};
@@ -55,6 +56,6 @@ const bfd_arch_info_type bfd_k1om_arch =
TRUE,
bfd_default_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_short_nop_fill,
&bfd_k1om_arch_intel_syntax
};
diff --git a/bfd/cpu-l1om.c b/bfd/cpu-l1om.c
index 0fabd49..46ac3a0 100644
--- a/bfd/cpu-l1om.c
+++ b/bfd/cpu-l1om.c
@@ -23,7 +23,8 @@
#include "bfd.h"
#include "libbfd.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_l1om_arch_intel_syntax =
{
@@ -38,7 +39,7 @@ static const bfd_arch_info_type bfd_l1om_arch_intel_syntax =
TRUE,
bfd_default_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_short_nop_fill,
0
};
@@ -55,6 +56,6 @@ const bfd_arch_info_type bfd_l1om_arch =
TRUE,
bfd_default_compatible,
bfd_default_scan,
- bfd_arch_i386_fill,
+ bfd_arch_i386_short_nop_fill,
&bfd_l1om_arch_intel_syntax
};