Add new target_read_raw_memory function, and consolidate comments.
[deliverable/binutils-gdb.git] / bfd / cpu-i386.c
CommitLineData
252b5132 1/* BFD support for the Intel 386 architecture.
aa820537 2 Copyright 1992, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2004, 2005,
1098fd41 3 2007, 2009, 2010, 2011, 2013
7898deda 4 Free Software Foundation, Inc.
252b5132 5
cd123cb7 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
cd123cb7
NC
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.
252b5132 12
cd123cb7
NC
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.
252b5132 17
cd123cb7
NC
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. */
252b5132 22
252b5132 23#include "sysdep.h"
3db64b00 24#include "bfd.h"
252b5132 25#include "libbfd.h"
b7761f11
L
26#include "libiberty.h"
27
923f257f
L
28extern void * bfd_arch_i386_short_nop_fill (bfd_size_type, bfd_boolean,
29 bfd_boolean);
252b5132 30
889a4d3e
L
31static const bfd_arch_info_type *
32bfd_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. */
d7921315
L
38 if (compat
39 && (a->mach & bfd_mach_x64_32) != (b->mach & bfd_mach_x64_32))
889a4d3e
L
40 compat = NULL;
41
42 return compat;
43}
44
923f257f
L
45/* Fill the buffer with zero or nop instruction if CODE is TRUE. Use
46 multi byte nop instructions if LONG_NOP is TRUE. */
b7761f11 47
923f257f
L
48static void *
49bfd_arch_i386_fill (bfd_size_type count, bfd_boolean code,
50 bfd_boolean long_nop)
b7761f11
L
51{
52 /* nop */
68ffbac6 53 static const char nop_1[] = { 0x90 };
923f257f 54 /* xchg %ax,%ax */
b7761f11
L
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 };
923f257f 78 bfd_size_type nop_size = long_nop ? ARRAY_SIZE (nops) : 2;
b7761f11
L
79
80 void *fill = bfd_malloc (count);
81 if (fill == NULL)
82 return fill;
83
84 if (code)
85 {
86 bfd_byte *p = fill;
923f257f 87 while (count >= nop_size)
b7761f11 88 {
923f257f
L
89 memcpy (p, nops[nop_size - 1], nop_size);
90 p += nop_size;
91 count -= nop_size;
b7761f11
L
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
923f257f
L
102/* Fill the buffer with zero or short nop instruction if CODE is TRUE. */
103
104void *
105bfd_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
114static void *
115bfd_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
1098fd41
RM
122/* Fill the buffer with zero, or one-byte nop instructions if CODE is TRUE. */
123
124static void *
125bfd_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
136static 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
153static 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
170const 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
351f65ca
L
187static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
188{
189 64, /* 64 bits in a word */
d7921315 190 64, /* 64 bits in an address */
351f65ca
L
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,
889a4d3e 198 bfd_i386_compatible,
351f65ca 199 bfd_default_scan,
923f257f 200 bfd_arch_i386_long_nop_fill,
1098fd41 201 &bfd_i386_nacl_arch
351f65ca
L
202};
203
34274ccc 204static const bfd_arch_info_type bfd_x86_64_arch_intel_syntax =
8d88c4ca
NC
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,
beb43bb9
JH
211 "i386:intel",
212 "i386:x86-64:intel",
8d88c4ca 213 3,
1abc8597 214 FALSE,
889a4d3e 215 bfd_i386_compatible,
1abc8597 216 bfd_default_scan,
923f257f 217 bfd_arch_i386_long_nop_fill,
351f65ca 218 &bfd_x64_32_arch_intel_syntax,
1abc8597
AM
219};
220
34274ccc 221static const bfd_arch_info_type bfd_i386_arch_intel_syntax =
1abc8597
AM
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,
b34976b6 231 TRUE,
889a4d3e 232 bfd_i386_compatible,
1abc8597 233 bfd_default_scan,
923f257f 234 bfd_arch_i386_short_nop_fill,
1abc8597 235 &bfd_x86_64_arch_intel_syntax
8d88c4ca 236};
1abc8597 237
34274ccc 238static const bfd_arch_info_type i8086_arch =
252b5132
RH
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,
b34976b6 248 FALSE,
889a4d3e 249 bfd_i386_compatible,
1abc8597 250 bfd_default_scan,
923f257f 251 bfd_arch_i386_short_nop_fill,
1abc8597 252 &bfd_i386_arch_intel_syntax
8d88c4ca
NC
253};
254
351f65ca
L
255static const bfd_arch_info_type bfd_x64_32_arch =
256{
257 64, /* 64 bits in a word */
d7921315 258 64, /* 64 bits in an address */
351f65ca
L
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,
889a4d3e 266 bfd_i386_compatible,
351f65ca 267 bfd_default_scan,
923f257f 268 bfd_arch_i386_long_nop_fill,
351f65ca
L
269 &i8086_arch
270};
271
34274ccc 272static const bfd_arch_info_type bfd_x86_64_arch =
8d88c4ca 273{
b1995b01
L
274 64, /* 64 bits in a word */
275 64, /* 64 bits in an address */
8d88c4ca
NC
276 8, /* 8 bits in a byte */
277 bfd_arch_i386,
278 bfd_mach_x86_64,
beb43bb9
JH
279 "i386",
280 "i386:x86-64",
8d88c4ca 281 3,
1abc8597 282 FALSE,
889a4d3e 283 bfd_i386_compatible,
1abc8597 284 bfd_default_scan,
923f257f 285 bfd_arch_i386_long_nop_fill,
351f65ca 286 &bfd_x64_32_arch
252b5132
RH
287};
288
289const 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,
b34976b6 299 TRUE,
889a4d3e 300 bfd_i386_compatible,
1abc8597 301 bfd_default_scan,
923f257f 302 bfd_arch_i386_short_nop_fill,
3fde5a36 303 &bfd_x86_64_arch
252b5132 304};
This page took 0.618994 seconds and 4 git commands to generate.