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