Don't use multi byte nop instructions for i386

bfd/

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.

ld/testsuite/

2012-02-09  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13675
	* ld-i386/tlsnopic.dd: Update no-op padding.
	* ld-i386/tlspic.dd: Likewise.
This commit is contained in:
H.J. Lu 2012-02-09 22:51:58 +00:00
parent f8255c2a40
commit 923f257ffd
7 changed files with 74 additions and 26 deletions

View File

@ -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.

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -1,3 +1,9 @@
2012-02-09 H.J. Lu <hongjiu.lu@intel.com>
PR ld/13675
* ld-i386/tlsnopic.dd: Update no-op padding.
* ld-i386/tlspic.dd: Likewise.
2012-01-31 H.J. Lu <hongjiu.lu@intel.com>
PR ld/13616

View File

@ -156,4 +156,5 @@ Disassembly of section .text:
10ec: 8b 5d fc[ ]+mov -0x4\(%ebp\),%ebx
10ef: c9[ ]+leave *
10f0: c3[ ]+ret *
10f1: 0f 1f 00[ ]+nopl \(%eax\)
10f1: 66 90[ ]+xchg %ax,%ax
10f3: 90[ ]+nop

View File

@ -406,4 +406,5 @@ Disassembly of section .text:
[0-9a-f]+: 8b 5d fc[ ]+mov -0x4\(%ebp\),%ebx
[0-9a-f]+: c9[ ]+leave *
[0-9a-f]+: c3[ ]+ret *
[0-9a-f]+: 0f 1f 00[ ]+nopl \(%eax\)
[0-9a-f]+: 66 90[ ]+xchg %ax,%ax
[0-9a-f]+: 90[ ]+nop