Home | History | Annotate | Download | only in bfd
      1 /* BFD support for the Intel 386 architecture.
      2    Copyright (C) 1992-2016 Free Software Foundation, Inc.
      3 
      4    This file is part of BFD, the Binary File Descriptor library.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "libbfd.h"
     24 #include "libiberty.h"
     25 
     26 extern void * bfd_arch_i386_short_nop_fill (bfd_size_type, bfd_boolean,
     27 					    bfd_boolean);
     28 
     29 static const bfd_arch_info_type *
     30 bfd_i386_compatible (const bfd_arch_info_type *a,
     31 		     const bfd_arch_info_type *b)
     32 {
     33   const bfd_arch_info_type *compat = bfd_default_compatible (a, b);
     34 
     35   /* Don't allow mixing x64_32 with x86_64.  */
     36   if (compat
     37       && (a->mach & bfd_mach_x64_32) != (b->mach & bfd_mach_x64_32))
     38     compat = NULL;
     39 
     40   return compat;
     41 }
     42 
     43 /* Fill the buffer with zero or nop instruction if CODE is TRUE.  Use
     44    multi byte nop instructions if LONG_NOP is TRUE.  */
     45 
     46 static void *
     47 bfd_arch_i386_fill (bfd_size_type count, bfd_boolean code,
     48 		    bfd_boolean long_nop)
     49 {
     50   /* nop */
     51   static const char nop_1[] = { 0x90 };
     52   /* xchg %ax,%ax */
     53   static const char nop_2[] = { 0x66, 0x90 };
     54   /* nopl (%[re]ax) */
     55   static const char nop_3[] = { 0x0f, 0x1f, 0x00 };
     56   /* nopl 0(%[re]ax) */
     57   static const char nop_4[] = { 0x0f, 0x1f, 0x40, 0x00 };
     58   /* nopl 0(%[re]ax,%[re]ax,1) */
     59   static const char nop_5[] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 };
     60   /* nopw 0(%[re]ax,%[re]ax,1) */
     61   static const char nop_6[] = { 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 };
     62   /* nopl 0L(%[re]ax) */
     63   static const char nop_7[] = { 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00 };
     64   /* nopl 0L(%[re]ax,%[re]ax,1) */
     65   static const char nop_8[] =
     66     { 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
     67   /* nopw 0L(%[re]ax,%[re]ax,1) */
     68   static const char nop_9[] =
     69     { 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
     70   /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
     71   static const char nop_10[] =
     72     { 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
     73   static const char *const nops[] =
     74     { nop_1, nop_2, nop_3, nop_4, nop_5,
     75       nop_6, nop_7, nop_8, nop_9, nop_10 };
     76   bfd_size_type nop_size = long_nop ? ARRAY_SIZE (nops) : 2;
     77 
     78   void *fill = bfd_malloc (count);
     79   if (fill == NULL)
     80     return fill;
     81 
     82   if (code)
     83     {
     84       bfd_byte *p = fill;
     85       while (count >= nop_size)
     86 	{
     87 	  memcpy (p, nops[nop_size - 1], nop_size);
     88 	  p += nop_size;
     89 	  count -= nop_size;
     90 	}
     91       if (count != 0)
     92 	memcpy (p, nops[count - 1], count);
     93     }
     94   else
     95     memset (fill, 0, count);
     96 
     97   return fill;
     98 }
     99 
    100 /* Fill the buffer with zero or short nop instruction if CODE is TRUE.  */
    101 
    102 void *
    103 bfd_arch_i386_short_nop_fill (bfd_size_type count,
    104 			      bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
    105 			      bfd_boolean code)
    106 {
    107   return bfd_arch_i386_fill (count, code, FALSE);
    108 }
    109 
    110 /* Fill the buffer with zero or long nop instruction if CODE is TRUE.  */
    111 
    112 static void *
    113 bfd_arch_i386_long_nop_fill (bfd_size_type count,
    114 			     bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
    115 			     bfd_boolean code)
    116 {
    117   return bfd_arch_i386_fill (count, code, TRUE);
    118 }
    119 
    120 /* Fill the buffer with zero, or one-byte nop instructions if CODE is TRUE.  */
    121 
    122 static void *
    123 bfd_arch_i386_onebyte_nop_fill (bfd_size_type count,
    124 				bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
    125 				bfd_boolean code)
    126 {
    127   void *fill = bfd_malloc (count);
    128   if (fill != NULL)
    129     memset (fill, code ? 0x90 : 0, count);
    130   return fill;
    131 }
    132 
    133 
    134 static const bfd_arch_info_type bfd_x64_32_nacl_arch =
    135 {
    136   64, /* 64 bits in a word */
    137   64, /* 64 bits in an address */
    138   8,  /* 8 bits in a byte */
    139   bfd_arch_i386,
    140   bfd_mach_x64_32_nacl,
    141   "i386",
    142   "i386:x64-32:nacl",
    143   3,
    144   FALSE,
    145   bfd_i386_compatible,
    146   bfd_default_scan,
    147   bfd_arch_i386_onebyte_nop_fill,
    148   NULL
    149 };
    150 
    151 static const bfd_arch_info_type bfd_x86_64_nacl_arch =
    152 {
    153   64, /* 64 bits in a word */
    154   64, /* 64 bits in an address */
    155   8,  /* 8 bits in a byte */
    156   bfd_arch_i386,
    157   bfd_mach_x86_64_nacl,
    158   "i386",
    159   "i386:x86-64:nacl",
    160   3,
    161   FALSE,
    162   bfd_i386_compatible,
    163   bfd_default_scan,
    164   bfd_arch_i386_onebyte_nop_fill,
    165   &bfd_x64_32_nacl_arch
    166 };
    167 
    168 const bfd_arch_info_type bfd_i386_nacl_arch =
    169 {
    170   32,	/* 32 bits in a word */
    171   32,	/* 32 bits in an address */
    172   8,	/* 8 bits in a byte */
    173   bfd_arch_i386,
    174   bfd_mach_i386_i386_nacl,
    175   "i386",
    176   "i386:nacl",
    177   3,
    178   TRUE,
    179   bfd_i386_compatible,
    180   bfd_default_scan,
    181   bfd_arch_i386_onebyte_nop_fill,
    182   &bfd_x86_64_nacl_arch
    183 };
    184 
    185 static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
    186 {
    187   64, /* 64 bits in a word */
    188   64, /* 64 bits in an address */
    189   8,  /* 8 bits in a byte */
    190   bfd_arch_i386,
    191   bfd_mach_x64_32_intel_syntax,
    192   "i386:intel",
    193   "i386:x64-32:intel",
    194   3,
    195   FALSE,
    196   bfd_i386_compatible,
    197   bfd_default_scan,
    198   bfd_arch_i386_long_nop_fill,
    199   &bfd_i386_nacl_arch
    200 };
    201 
    202 static const bfd_arch_info_type bfd_x86_64_arch_intel_syntax =
    203 {
    204   64, /* 64 bits in a word */
    205   64, /* 64 bits in an address */
    206   8,  /* 8 bits in a byte */
    207   bfd_arch_i386,
    208   bfd_mach_x86_64_intel_syntax,
    209   "i386:intel",
    210   "i386:x86-64:intel",
    211   3,
    212   FALSE,
    213   bfd_i386_compatible,
    214   bfd_default_scan,
    215   bfd_arch_i386_long_nop_fill,
    216   &bfd_x64_32_arch_intel_syntax,
    217 };
    218 
    219 static const bfd_arch_info_type bfd_i386_arch_intel_syntax =
    220 {
    221   32,	/* 32 bits in a word */
    222   32,	/* 32 bits in an address */
    223   8,	/* 8 bits in a byte */
    224   bfd_arch_i386,
    225   bfd_mach_i386_i386_intel_syntax,
    226   "i386:intel",
    227   "i386:intel",
    228   3,
    229   TRUE,
    230   bfd_i386_compatible,
    231   bfd_default_scan,
    232   bfd_arch_i386_short_nop_fill,
    233   &bfd_x86_64_arch_intel_syntax
    234 };
    235 
    236 static const bfd_arch_info_type i8086_arch =
    237 {
    238   32,	/* 32 bits in a word */
    239   32,	/* 32 bits in an address (well, not really) */
    240   8,	/* 8 bits in a byte */
    241   bfd_arch_i386,
    242   bfd_mach_i386_i8086,
    243   "i8086",
    244   "i8086",
    245   3,
    246   FALSE,
    247   bfd_i386_compatible,
    248   bfd_default_scan,
    249   bfd_arch_i386_short_nop_fill,
    250   &bfd_i386_arch_intel_syntax
    251 };
    252 
    253 static const bfd_arch_info_type bfd_x64_32_arch =
    254 {
    255   64, /* 64 bits in a word */
    256   64, /* 64 bits in an address */
    257   8,  /* 8 bits in a byte */
    258   bfd_arch_i386,
    259   bfd_mach_x64_32,
    260   "i386",
    261   "i386:x64-32",
    262   3,
    263   FALSE,
    264   bfd_i386_compatible,
    265   bfd_default_scan,
    266   bfd_arch_i386_long_nop_fill,
    267   &i8086_arch
    268 };
    269 
    270 static const bfd_arch_info_type bfd_x86_64_arch =
    271 {
    272   64, /* 64 bits in a word */
    273   64, /* 64 bits in an address */
    274   8,  /* 8 bits in a byte */
    275   bfd_arch_i386,
    276   bfd_mach_x86_64,
    277   "i386",
    278   "i386:x86-64",
    279   3,
    280   FALSE,
    281   bfd_i386_compatible,
    282   bfd_default_scan,
    283   bfd_arch_i386_long_nop_fill,
    284   &bfd_x64_32_arch
    285 };
    286 
    287 const bfd_arch_info_type bfd_i386_arch =
    288 {
    289   32,	/* 32 bits in a word */
    290   32,	/* 32 bits in an address */
    291   8,	/* 8 bits in a byte */
    292   bfd_arch_i386,
    293   bfd_mach_i386_i386,
    294   "i386",
    295   "i386",
    296   3,
    297   TRUE,
    298   bfd_i386_compatible,
    299   bfd_default_scan,
    300   bfd_arch_i386_short_nop_fill,
    301   &bfd_x86_64_arch
    302 };
    303