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