Support arch-dependent fill
[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
28extern void * bfd_arch_i386_fill (bfd_size_type, bfd_boolean, bfd_boolean);
252b5132 29
889a4d3e
L
30static const bfd_arch_info_type *
31bfd_i386_compatible (const bfd_arch_info_type *a,
32 const bfd_arch_info_type *b)
33{
34 const bfd_arch_info_type *compat = bfd_default_compatible (a, b);
35
36 /* Don't allow mixing x64_32 with x86_64. */
d7921315
L
37 if (compat
38 && (a->mach & bfd_mach_x64_32) != (b->mach & bfd_mach_x64_32))
889a4d3e
L
39 compat = NULL;
40
41 return compat;
42}
43
b7761f11
L
44/* Fill the buffer with zero or nop instruction if CODE is TRUE. */
45
46void *
47bfd_arch_i386_fill (bfd_size_type count,
48 bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
49 bfd_boolean code)
50{
51 /* nop */
52 static const char nop_1[] = { 0x90 };
53 /* nopw */
54 static const char nop_2[] = { 0x66, 0x90 };
55 /* nopl (%[re]ax) */
56 static const char nop_3[] = { 0x0f, 0x1f, 0x00 };
57 /* nopl 0(%[re]ax) */
58 static const char nop_4[] = { 0x0f, 0x1f, 0x40, 0x00 };
59 /* nopl 0(%[re]ax,%[re]ax,1) */
60 static const char nop_5[] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 };
61 /* nopw 0(%[re]ax,%[re]ax,1) */
62 static const char nop_6[] = { 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 };
63 /* nopl 0L(%[re]ax) */
64 static const char nop_7[] = { 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00 };
65 /* nopl 0L(%[re]ax,%[re]ax,1) */
66 static const char nop_8[] =
67 { 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
68 /* nopw 0L(%[re]ax,%[re]ax,1) */
69 static const char nop_9[] =
70 { 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
71 /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
72 static const char nop_10[] =
73 { 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
74 static const char *const nops[] =
75 { nop_1, nop_2, nop_3, nop_4, nop_5,
76 nop_6, nop_7, nop_8, nop_9, nop_10 };
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 >= ARRAY_SIZE (nops))
86 {
87 memcpy (p, nops[ARRAY_SIZE (nops) - 1], ARRAY_SIZE (nops));
88 p += ARRAY_SIZE (nops);
89 count -= ARRAY_SIZE (nops);
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
351f65ca
L
100static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
101{
102 64, /* 64 bits in a word */
d7921315 103 64, /* 64 bits in an address */
351f65ca
L
104 8, /* 8 bits in a byte */
105 bfd_arch_i386,
106 bfd_mach_x64_32_intel_syntax,
107 "i386:intel",
108 "i386:x64-32:intel",
109 3,
110 FALSE,
889a4d3e 111 bfd_i386_compatible,
351f65ca 112 bfd_default_scan,
b7761f11 113 bfd_arch_i386_fill,
351f65ca
L
114 0
115};
116
34274ccc 117static const bfd_arch_info_type bfd_x86_64_arch_intel_syntax =
8d88c4ca
NC
118{
119 64, /* 64 bits in a word */
120 64, /* 64 bits in an address */
121 8, /* 8 bits in a byte */
122 bfd_arch_i386,
123 bfd_mach_x86_64_intel_syntax,
beb43bb9
JH
124 "i386:intel",
125 "i386:x86-64:intel",
8d88c4ca 126 3,
1abc8597 127 FALSE,
889a4d3e 128 bfd_i386_compatible,
1abc8597 129 bfd_default_scan,
b7761f11 130 bfd_arch_i386_fill,
351f65ca 131 &bfd_x64_32_arch_intel_syntax,
1abc8597
AM
132};
133
34274ccc 134static const bfd_arch_info_type bfd_i386_arch_intel_syntax =
1abc8597
AM
135{
136 32, /* 32 bits in a word */
137 32, /* 32 bits in an address */
138 8, /* 8 bits in a byte */
139 bfd_arch_i386,
140 bfd_mach_i386_i386_intel_syntax,
141 "i386:intel",
142 "i386:intel",
143 3,
b34976b6 144 TRUE,
889a4d3e 145 bfd_i386_compatible,
1abc8597 146 bfd_default_scan,
b7761f11 147 bfd_arch_i386_fill,
1abc8597 148 &bfd_x86_64_arch_intel_syntax
8d88c4ca 149};
1abc8597 150
34274ccc 151static const bfd_arch_info_type i8086_arch =
252b5132
RH
152{
153 32, /* 32 bits in a word */
154 32, /* 32 bits in an address (well, not really) */
155 8, /* 8 bits in a byte */
156 bfd_arch_i386,
157 bfd_mach_i386_i8086,
158 "i8086",
159 "i8086",
160 3,
b34976b6 161 FALSE,
889a4d3e 162 bfd_i386_compatible,
1abc8597 163 bfd_default_scan,
b7761f11 164 bfd_arch_i386_fill,
1abc8597 165 &bfd_i386_arch_intel_syntax
8d88c4ca
NC
166};
167
351f65ca
L
168static const bfd_arch_info_type bfd_x64_32_arch =
169{
170 64, /* 64 bits in a word */
d7921315 171 64, /* 64 bits in an address */
351f65ca
L
172 8, /* 8 bits in a byte */
173 bfd_arch_i386,
174 bfd_mach_x64_32,
175 "i386",
176 "i386:x64-32",
177 3,
178 FALSE,
889a4d3e 179 bfd_i386_compatible,
351f65ca 180 bfd_default_scan,
b7761f11 181 bfd_arch_i386_fill,
351f65ca
L
182 &i8086_arch
183};
184
34274ccc 185static const bfd_arch_info_type bfd_x86_64_arch =
8d88c4ca 186{
b1995b01
L
187 64, /* 64 bits in a word */
188 64, /* 64 bits in an address */
8d88c4ca
NC
189 8, /* 8 bits in a byte */
190 bfd_arch_i386,
191 bfd_mach_x86_64,
beb43bb9
JH
192 "i386",
193 "i386:x86-64",
8d88c4ca 194 3,
1abc8597 195 FALSE,
889a4d3e 196 bfd_i386_compatible,
1abc8597 197 bfd_default_scan,
b7761f11 198 bfd_arch_i386_fill,
351f65ca 199 &bfd_x64_32_arch
252b5132
RH
200};
201
202const bfd_arch_info_type bfd_i386_arch =
203{
204 32, /* 32 bits in a word */
205 32, /* 32 bits in an address */
206 8, /* 8 bits in a byte */
207 bfd_arch_i386,
208 bfd_mach_i386_i386,
209 "i386",
210 "i386",
211 3,
b34976b6 212 TRUE,
889a4d3e 213 bfd_i386_compatible,
1abc8597 214 bfd_default_scan,
b7761f11 215 bfd_arch_i386_fill,
3fde5a36 216 &bfd_x86_64_arch
252b5132 217};
This page took 0.558198 seconds and 4 git commands to generate.