[BACK]Return to cpu-i386.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / bfd

Annotation of src/external/gpl3/binutils.old/dist/bfd/cpu-i386.c, Revision 1.5.2.1

1.1       christos    1: /* BFD support for the Intel 386 architecture.
1.5.2.1 ! martin      2:    Copyright (C) 1992-2018 Free Software Foundation, Inc.
1.1       christos    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 */
1.3       christos   51:   static const char nop_1[] = { 0x90 };
1.1       christos   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:
1.3       christos  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:
1.1       christos  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,
1.3       christos  199:   &bfd_i386_nacl_arch
1.1       christos  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: };

CVSweb <webmaster@jp.NetBSD.org>