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