merge from gcc
[gdb/gnu.git] / bfd / cpu-i386.c
blob2a6bb97b944b37dbde728a07b937928a839e38ee
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.
6 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #include "libiberty.h"
28 extern void * bfd_arch_i386_short_nop_fill (bfd_size_type, bfd_boolean,
29 bfd_boolean);
31 static const bfd_arch_info_type *
32 bfd_i386_compatible (const bfd_arch_info_type *a,
33 const bfd_arch_info_type *b)
35 const bfd_arch_info_type *compat = bfd_default_compatible (a, b);
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;
42 return compat;
45 /* Fill the buffer with zero or nop instruction if CODE is TRUE. Use
46 multi byte nop instructions if LONG_NOP is TRUE. */
48 static void *
49 bfd_arch_i386_fill (bfd_size_type count, bfd_boolean code,
50 bfd_boolean long_nop)
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;
80 void *fill = bfd_malloc (count);
81 if (fill == NULL)
82 return fill;
84 if (code)
86 bfd_byte *p = fill;
87 while (count >= nop_size)
89 memcpy (p, nops[nop_size - 1], nop_size);
90 p += nop_size;
91 count -= nop_size;
93 if (count != 0)
94 memcpy (p, nops[count - 1], count);
96 else
97 memset (fill, 0, count);
99 return fill;
102 /* Fill the buffer with zero or short nop instruction if CODE is TRUE. */
104 void *
105 bfd_arch_i386_short_nop_fill (bfd_size_type count,
106 bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
107 bfd_boolean code)
109 return bfd_arch_i386_fill (count, code, FALSE);
112 /* Fill the buffer with zero or long nop instruction if CODE is TRUE. */
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)
119 return bfd_arch_i386_fill (count, code, TRUE);
122 /* Fill the buffer with zero, or one-byte nop instructions if CODE is TRUE. */
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)
129 void *fill = bfd_malloc (count);
130 if (fill != NULL)
131 memset (fill, code ? 0x90 : 0, count);
132 return fill;
136 static const bfd_arch_info_type bfd_x64_32_nacl_arch =
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",
146 FALSE,
147 bfd_i386_compatible,
148 bfd_default_scan,
149 bfd_arch_i386_onebyte_nop_fill,
150 NULL
153 static const bfd_arch_info_type bfd_x86_64_nacl_arch =
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",
163 FALSE,
164 bfd_i386_compatible,
165 bfd_default_scan,
166 bfd_arch_i386_onebyte_nop_fill,
167 &bfd_x64_32_nacl_arch
170 const bfd_arch_info_type bfd_i386_nacl_arch =
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",
180 TRUE,
181 bfd_i386_compatible,
182 bfd_default_scan,
183 bfd_arch_i386_onebyte_nop_fill,
184 &bfd_x86_64_nacl_arch
187 static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
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",
197 FALSE,
198 bfd_i386_compatible,
199 bfd_default_scan,
200 bfd_arch_i386_long_nop_fill,
201 &bfd_i386_nacl_arch
204 static const bfd_arch_info_type bfd_x86_64_arch_intel_syntax =
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",
214 FALSE,
215 bfd_i386_compatible,
216 bfd_default_scan,
217 bfd_arch_i386_long_nop_fill,
218 &bfd_x64_32_arch_intel_syntax,
221 static const bfd_arch_info_type bfd_i386_arch_intel_syntax =
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",
231 TRUE,
232 bfd_i386_compatible,
233 bfd_default_scan,
234 bfd_arch_i386_short_nop_fill,
235 &bfd_x86_64_arch_intel_syntax
238 static const bfd_arch_info_type i8086_arch =
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",
248 FALSE,
249 bfd_i386_compatible,
250 bfd_default_scan,
251 bfd_arch_i386_short_nop_fill,
252 &bfd_i386_arch_intel_syntax
255 static const bfd_arch_info_type bfd_x64_32_arch =
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",
265 FALSE,
266 bfd_i386_compatible,
267 bfd_default_scan,
268 bfd_arch_i386_long_nop_fill,
269 &i8086_arch
272 static const bfd_arch_info_type bfd_x86_64_arch =
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",
282 FALSE,
283 bfd_i386_compatible,
284 bfd_default_scan,
285 bfd_arch_i386_long_nop_fill,
286 &bfd_x64_32_arch
289 const bfd_arch_info_type bfd_i386_arch =
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",
299 TRUE,
300 bfd_i386_compatible,
301 bfd_default_scan,
302 bfd_arch_i386_short_nop_fill,
303 &bfd_x86_64_arch