daily update
[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,
889a4d3e 3 2007, 2009, 2010, 2011
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 */
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
351f65ca
L
122static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
123{
124 64, /* 64 bits in a word */
d7921315 125 64, /* 64 bits in an address */
351f65ca
L
126 8, /* 8 bits in a byte */
127 bfd_arch_i386,
128 bfd_mach_x64_32_intel_syntax,
129 "i386:intel",
130 "i386:x64-32:intel",
131 3,
132 FALSE,
889a4d3e 133 bfd_i386_compatible,
351f65ca 134 bfd_default_scan,
923f257f 135 bfd_arch_i386_long_nop_fill,
351f65ca
L
136 0
137};
138
34274ccc 139static const bfd_arch_info_type bfd_x86_64_arch_intel_syntax =
8d88c4ca
NC
140{
141 64, /* 64 bits in a word */
142 64, /* 64 bits in an address */
143 8, /* 8 bits in a byte */
144 bfd_arch_i386,
145 bfd_mach_x86_64_intel_syntax,
beb43bb9
JH
146 "i386:intel",
147 "i386:x86-64:intel",
8d88c4ca 148 3,
1abc8597 149 FALSE,
889a4d3e 150 bfd_i386_compatible,
1abc8597 151 bfd_default_scan,
923f257f 152 bfd_arch_i386_long_nop_fill,
351f65ca 153 &bfd_x64_32_arch_intel_syntax,
1abc8597
AM
154};
155
34274ccc 156static const bfd_arch_info_type bfd_i386_arch_intel_syntax =
1abc8597
AM
157{
158 32, /* 32 bits in a word */
159 32, /* 32 bits in an address */
160 8, /* 8 bits in a byte */
161 bfd_arch_i386,
162 bfd_mach_i386_i386_intel_syntax,
163 "i386:intel",
164 "i386:intel",
165 3,
b34976b6 166 TRUE,
889a4d3e 167 bfd_i386_compatible,
1abc8597 168 bfd_default_scan,
923f257f 169 bfd_arch_i386_short_nop_fill,
1abc8597 170 &bfd_x86_64_arch_intel_syntax
8d88c4ca 171};
1abc8597 172
34274ccc 173static const bfd_arch_info_type i8086_arch =
252b5132
RH
174{
175 32, /* 32 bits in a word */
176 32, /* 32 bits in an address (well, not really) */
177 8, /* 8 bits in a byte */
178 bfd_arch_i386,
179 bfd_mach_i386_i8086,
180 "i8086",
181 "i8086",
182 3,
b34976b6 183 FALSE,
889a4d3e 184 bfd_i386_compatible,
1abc8597 185 bfd_default_scan,
923f257f 186 bfd_arch_i386_short_nop_fill,
1abc8597 187 &bfd_i386_arch_intel_syntax
8d88c4ca
NC
188};
189
351f65ca
L
190static const bfd_arch_info_type bfd_x64_32_arch =
191{
192 64, /* 64 bits in a word */
d7921315 193 64, /* 64 bits in an address */
351f65ca
L
194 8, /* 8 bits in a byte */
195 bfd_arch_i386,
196 bfd_mach_x64_32,
197 "i386",
198 "i386:x64-32",
199 3,
200 FALSE,
889a4d3e 201 bfd_i386_compatible,
351f65ca 202 bfd_default_scan,
923f257f 203 bfd_arch_i386_long_nop_fill,
351f65ca
L
204 &i8086_arch
205};
206
34274ccc 207static const bfd_arch_info_type bfd_x86_64_arch =
8d88c4ca 208{
b1995b01
L
209 64, /* 64 bits in a word */
210 64, /* 64 bits in an address */
8d88c4ca
NC
211 8, /* 8 bits in a byte */
212 bfd_arch_i386,
213 bfd_mach_x86_64,
beb43bb9
JH
214 "i386",
215 "i386:x86-64",
8d88c4ca 216 3,
1abc8597 217 FALSE,
889a4d3e 218 bfd_i386_compatible,
1abc8597 219 bfd_default_scan,
923f257f 220 bfd_arch_i386_long_nop_fill,
351f65ca 221 &bfd_x64_32_arch
252b5132
RH
222};
223
224const bfd_arch_info_type bfd_i386_arch =
225{
226 32, /* 32 bits in a word */
227 32, /* 32 bits in an address */
228 8, /* 8 bits in a byte */
229 bfd_arch_i386,
230 bfd_mach_i386_i386,
231 "i386",
232 "i386",
233 3,
b34976b6 234 TRUE,
889a4d3e 235 bfd_i386_compatible,
1abc8597 236 bfd_default_scan,
923f257f 237 bfd_arch_i386_short_nop_fill,
3fde5a36 238 &bfd_x86_64_arch
252b5132 239};
This page took 0.637789 seconds and 4 git commands to generate.