1 /* ppc-dis.c -- Disassemble PowerPC instructions 2 Copyright (C) 1994-2022 Free Software Foundation, Inc. 3 Written by Ian Lance Taylor, Cygnus Support 4 5 This file is part of the GNU opcodes library. 6 7 This library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 It is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this file; see the file COPYING. If not, write to the 19 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 #include "sysdep.h" 23 #include <stdio.h> 24 #include "disassemble.h" 25 #include "elf-bfd.h" 26 #include "elf/ppc.h" 27 #include "opintl.h" 28 #include "opcode/ppc.h" 29 #include "libiberty.h" 30 31 /* This file provides several disassembler functions, all of which use 32 the disassembler interface defined in dis-asm.h. Several functions 33 are provided because this file handles disassembly for the PowerPC 34 in both big and little endian mode and also for the POWER (RS/6000) 35 chip. */ 36 static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int, 37 ppc_cpu_t); 38 39 struct dis_private 40 { 41 /* Stash the result of parsing disassembler_options here. */ 42 ppc_cpu_t dialect; 43 44 /* .got and .plt sections. NAME is set to NULL if not present. */ 45 struct sec_buf { 46 asection *sec; 47 bfd_byte *buf; 48 const char *name; 49 } special[2]; 50 }; 51 52 static inline struct dis_private * 53 private_data (struct disassemble_info *info) 54 { 55 return (struct dis_private *) info->private_data; 56 } 57 58 struct ppc_mopt { 59 /* Option string, without -m or -M prefix. */ 60 const char *opt; 61 /* CPU option flags. */ 62 ppc_cpu_t cpu; 63 /* Flags that should stay on, even when combined with another cpu 64 option. This should only be used for generic options like 65 "-many" or "-maltivec" where it is reasonable to add some 66 capability to another cpu selection. The added flags are sticky 67 so that, for example, "-many -me500" and "-me500 -many" result in 68 the same assembler or disassembler behaviour. Do not use 69 "sticky" for specific cpus, as this will prevent that cpu's flags 70 from overriding the defaults set in powerpc_init_dialect or a 71 prior -m option. */ 72 ppc_cpu_t sticky; 73 }; 74 75 struct ppc_mopt ppc_opts[] = { 76 { "403", PPC_OPCODE_PPC | PPC_OPCODE_403, 77 0 }, 78 { "405", PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405, 79 0 }, 80 { "440", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440 81 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI), 82 0 }, 83 { "464", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440 84 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI), 85 0 }, 86 { "476", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_476 87 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5), 88 0 }, 89 { "601", PPC_OPCODE_PPC | PPC_OPCODE_601, 90 0 }, 91 { "603", PPC_OPCODE_PPC, 92 0 }, 93 { "604", PPC_OPCODE_PPC, 94 0 }, 95 { "620", PPC_OPCODE_PPC | PPC_OPCODE_64, 96 0 }, 97 { "7400", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC, 98 0 }, 99 { "7410", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC, 100 0 }, 101 { "7450", PPC_OPCODE_PPC | PPC_OPCODE_7450 | PPC_OPCODE_ALTIVEC, 102 0 }, 103 { "7455", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC, 104 0 }, 105 { "750cl", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS 106 , 0 }, 107 { "gekko", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS 108 , 0 }, 109 { "broadway", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS 110 , 0 }, 111 { "821", PPC_OPCODE_PPC | PPC_OPCODE_860, 112 0 }, 113 { "850", PPC_OPCODE_PPC | PPC_OPCODE_860, 114 0 }, 115 { "860", PPC_OPCODE_PPC | PPC_OPCODE_860, 116 0 }, 117 { "a2", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4 118 | PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64 119 | PPC_OPCODE_A2), 120 0 }, 121 { "altivec", PPC_OPCODE_PPC, 122 PPC_OPCODE_ALTIVEC }, 123 { "any", PPC_OPCODE_PPC, 124 PPC_OPCODE_ANY }, 125 { "booke", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE, 126 0 }, 127 { "booke32", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE, 128 0 }, 129 { "cell", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 130 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC), 131 0 }, 132 { "com", PPC_OPCODE_COMMON, 133 0 }, 134 { "e200z4", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE 135 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 136 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 137 | PPC_OPCODE_E500 | PPC_OPCODE_VLE | PPC_OPCODE_E200Z4 138 | PPC_OPCODE_EFS2 | PPC_OPCODE_LSP), 139 0 }, 140 { "e300", PPC_OPCODE_PPC | PPC_OPCODE_E300, 141 0 }, 142 { "e500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE 143 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 144 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 145 | PPC_OPCODE_E500), 146 0 }, 147 { "e500mc", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 148 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 149 | PPC_OPCODE_E500MC), 150 0 }, 151 { "e500mc64", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 152 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 153 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5 154 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7), 155 0 }, 156 { "e5500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 157 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 158 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 159 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7), 160 0 }, 161 { "e6500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 162 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 163 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC 164 | PPC_OPCODE_E6500 | PPC_OPCODE_TMR | PPC_OPCODE_POWER4 165 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7), 166 0 }, 167 { "e500x2", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE 168 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 169 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 170 | PPC_OPCODE_E500), 171 0 }, 172 { "efs", PPC_OPCODE_PPC | PPC_OPCODE_EFS, 173 0 }, 174 { "efs2", PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2, 175 0 }, 176 { "power4", PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4, 177 0 }, 178 { "power5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 179 | PPC_OPCODE_POWER5), 180 0 }, 181 { "power6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 182 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC), 183 0 }, 184 { "power7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 185 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 186 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 187 0 }, 188 { "power8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 189 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 190 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 191 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 192 0 }, 193 { "power9", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 194 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 195 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 196 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 197 0 }, 198 { "power10", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 199 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 200 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 201 | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 202 0 }, 203 { "future", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 204 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 205 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 206 | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 207 0 }, 208 { "ppc", PPC_OPCODE_PPC, 209 0 }, 210 { "ppc32", PPC_OPCODE_PPC, 211 0 }, 212 { "32", PPC_OPCODE_PPC, 213 0 }, 214 { "ppc64", PPC_OPCODE_PPC | PPC_OPCODE_64, 215 0 }, 216 { "64", PPC_OPCODE_PPC | PPC_OPCODE_64, 217 0 }, 218 { "ppc64bridge", PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE, 219 0 }, 220 { "ppcps", PPC_OPCODE_PPC | PPC_OPCODE_PPCPS, 221 0 }, 222 { "pwr", PPC_OPCODE_POWER, 223 0 }, 224 { "pwr2", PPC_OPCODE_POWER | PPC_OPCODE_POWER2, 225 0 }, 226 { "pwr4", PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4, 227 0 }, 228 { "pwr5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 229 | PPC_OPCODE_POWER5), 230 0 }, 231 { "pwr5x", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 232 | PPC_OPCODE_POWER5), 233 0 }, 234 { "pwr6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 235 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC), 236 0 }, 237 { "pwr7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 238 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 239 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 240 0 }, 241 { "pwr8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 242 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 243 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 244 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 245 0 }, 246 { "pwr9", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 247 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 248 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 249 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 250 0 }, 251 { "pwr10", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 252 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 253 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 254 | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 255 0 }, 256 { "pwrx", PPC_OPCODE_POWER | PPC_OPCODE_POWER2, 257 0 }, 258 { "raw", PPC_OPCODE_PPC, 259 PPC_OPCODE_RAW }, 260 { "spe", PPC_OPCODE_PPC | PPC_OPCODE_EFS, 261 PPC_OPCODE_SPE }, 262 { "spe2", PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2 | PPC_OPCODE_SPE, 263 PPC_OPCODE_SPE2 }, 264 { "titan", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR 265 | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN), 266 0 }, 267 { "vle", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE 268 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 269 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 270 | PPC_OPCODE_LSP | PPC_OPCODE_EFS2 | PPC_OPCODE_SPE2), 271 PPC_OPCODE_VLE }, 272 { "vsx", PPC_OPCODE_PPC, 273 PPC_OPCODE_VSX }, 274 }; 275 276 /* Switch between Booke and VLE dialects for interlinked dumps. */ 277 static ppc_cpu_t 278 get_powerpc_dialect (struct disassemble_info *info) 279 { 280 ppc_cpu_t dialect = 0; 281 282 if (info->private_data) 283 dialect = private_data (info)->dialect; 284 285 /* Disassemble according to the section headers flags for VLE-mode. */ 286 if (dialect & PPC_OPCODE_VLE 287 && info->section != NULL && info->section->owner != NULL 288 && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour 289 && elf_object_id (info->section->owner) == PPC32_ELF_DATA 290 && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0) 291 return dialect; 292 else 293 return dialect & ~ PPC_OPCODE_VLE; 294 } 295 296 /* Handle -m and -M options that set cpu type, and .machine arg. */ 297 298 ppc_cpu_t 299 ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg) 300 { 301 unsigned int i; 302 303 for (i = 0; i < ARRAY_SIZE (ppc_opts); i++) 304 if (disassembler_options_cmp (ppc_opts[i].opt, arg) == 0) 305 { 306 if (ppc_opts[i].sticky) 307 { 308 *sticky |= ppc_opts[i].sticky; 309 if ((ppc_cpu & ~*sticky) != 0) 310 break; 311 } 312 ppc_cpu = ppc_opts[i].cpu; 313 break; 314 } 315 if (i >= ARRAY_SIZE (ppc_opts)) 316 return 0; 317 318 ppc_cpu |= *sticky; 319 return ppc_cpu; 320 } 321 322 /* Determine which set of machines to disassemble for. */ 323 324 static void 325 powerpc_init_dialect (struct disassemble_info *info) 326 { 327 ppc_cpu_t dialect = 0; 328 ppc_cpu_t sticky = 0; 329 struct dis_private *priv = calloc (sizeof (*priv), 1); 330 331 if (priv == NULL) 332 return; 333 334 switch (info->mach) 335 { 336 case bfd_mach_ppc_403: 337 case bfd_mach_ppc_403gc: 338 dialect = ppc_parse_cpu (dialect, &sticky, "403"); 339 break; 340 case bfd_mach_ppc_405: 341 dialect = ppc_parse_cpu (dialect, &sticky, "405"); 342 break; 343 case bfd_mach_ppc_601: 344 dialect = ppc_parse_cpu (dialect, &sticky, "601"); 345 break; 346 case bfd_mach_ppc_750: 347 dialect = ppc_parse_cpu (dialect, &sticky, "750cl"); 348 break; 349 case bfd_mach_ppc_a35: 350 case bfd_mach_ppc_rs64ii: 351 case bfd_mach_ppc_rs64iii: 352 dialect = ppc_parse_cpu (dialect, &sticky, "pwr2") | PPC_OPCODE_64; 353 break; 354 case bfd_mach_ppc_e500: 355 dialect = ppc_parse_cpu (dialect, &sticky, "e500"); 356 break; 357 case bfd_mach_ppc_e500mc: 358 dialect = ppc_parse_cpu (dialect, &sticky, "e500mc"); 359 break; 360 case bfd_mach_ppc_e500mc64: 361 dialect = ppc_parse_cpu (dialect, &sticky, "e500mc64"); 362 break; 363 case bfd_mach_ppc_e5500: 364 dialect = ppc_parse_cpu (dialect, &sticky, "e5500"); 365 break; 366 case bfd_mach_ppc_e6500: 367 dialect = ppc_parse_cpu (dialect, &sticky, "e6500"); 368 break; 369 case bfd_mach_ppc_titan: 370 dialect = ppc_parse_cpu (dialect, &sticky, "titan"); 371 break; 372 case bfd_mach_ppc_vle: 373 dialect = ppc_parse_cpu (dialect, &sticky, "vle"); 374 break; 375 default: 376 if (info->arch == bfd_arch_powerpc) 377 dialect = ppc_parse_cpu (dialect, &sticky, "power10") | PPC_OPCODE_ANY; 378 else 379 dialect = ppc_parse_cpu (dialect, &sticky, "pwr"); 380 break; 381 } 382 383 const char *opt; 384 FOR_EACH_DISASSEMBLER_OPTION (opt, info->disassembler_options) 385 { 386 ppc_cpu_t new_cpu = 0; 387 388 if (disassembler_options_cmp (opt, "32") == 0) 389 dialect &= ~(ppc_cpu_t) PPC_OPCODE_64; 390 else if (disassembler_options_cmp (opt, "64") == 0) 391 dialect |= PPC_OPCODE_64; 392 else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0) 393 dialect = new_cpu; 394 else 395 /* xgettext: c-format */ 396 opcodes_error_handler (_("warning: ignoring unknown -M%s option"), opt); 397 } 398 399 info->private_data = priv; 400 private_data (info)->dialect = dialect; 401 } 402 403 #define PPC_OPCD_SEGS (1 + PPC_OP (-1)) 404 static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS + 1]; 405 #define PREFIX_OPCD_SEGS (1 + PPC_PREFIX_SEG (-1)) 406 static unsigned short prefix_opcd_indices[PREFIX_OPCD_SEGS + 1]; 407 #define VLE_OPCD_SEGS (1 + VLE_OP_TO_SEG (VLE_OP (-1, 0xffff))) 408 static unsigned short vle_opcd_indices[VLE_OPCD_SEGS + 1]; 409 #define SPE2_OPCD_SEGS (1 + SPE2_XOP_TO_SEG (SPE2_XOP (-1))) 410 static unsigned short spe2_opcd_indices[SPE2_OPCD_SEGS + 1]; 411 412 static bool 413 ppc_symbol_is_valid (asymbol *sym, 414 struct disassemble_info *info ATTRIBUTE_UNUSED) 415 { 416 elf_symbol_type * est; 417 418 if (sym == NULL) 419 return false; 420 421 est = elf_symbol_from (sym); 422 423 /* Ignore ELF hidden, local, no-type symbols. 424 These are generated by annobin. */ 425 if (est != NULL 426 && ELF_ST_VISIBILITY (est->internal_elf_sym.st_other) == STV_HIDDEN 427 && ELF_ST_BIND (est->internal_elf_sym.st_info) == STB_LOCAL 428 && ELF_ST_TYPE (est->internal_elf_sym.st_info) == STT_NOTYPE) 429 return false; 430 431 return true; 432 } 433 434 /* Calculate opcode table indices to speed up disassembly, 435 and init dialect. */ 436 437 void 438 disassemble_init_powerpc (struct disassemble_info *info) 439 { 440 info->symbol_is_valid = ppc_symbol_is_valid; 441 442 if (powerpc_opcd_indices[PPC_OPCD_SEGS] == 0) 443 { 444 unsigned seg, idx, op; 445 446 /* PPC opcodes */ 447 for (seg = 0, idx = 0; seg <= PPC_OPCD_SEGS; seg++) 448 { 449 powerpc_opcd_indices[seg] = idx; 450 for (; idx < powerpc_num_opcodes; idx++) 451 if (seg < PPC_OP (powerpc_opcodes[idx].opcode)) 452 break; 453 } 454 455 /* 64-bit prefix opcodes */ 456 for (seg = 0, idx = 0; seg <= PREFIX_OPCD_SEGS; seg++) 457 { 458 prefix_opcd_indices[seg] = idx; 459 for (; idx < prefix_num_opcodes; idx++) 460 if (seg < PPC_PREFIX_SEG (prefix_opcodes[idx].opcode)) 461 break; 462 } 463 464 /* VLE opcodes */ 465 for (seg = 0, idx = 0; seg <= VLE_OPCD_SEGS; seg++) 466 { 467 vle_opcd_indices[seg] = idx; 468 for (; idx < vle_num_opcodes; idx++) 469 { 470 op = VLE_OP (vle_opcodes[idx].opcode, vle_opcodes[idx].mask); 471 if (seg < VLE_OP_TO_SEG (op)) 472 break; 473 } 474 } 475 476 /* SPE2 opcodes */ 477 for (seg = 0, idx = 0; seg <= SPE2_OPCD_SEGS; seg++) 478 { 479 spe2_opcd_indices[seg] = idx; 480 for (; idx < spe2_num_opcodes; idx++) 481 { 482 op = SPE2_XOP (spe2_opcodes[idx].opcode); 483 if (seg < SPE2_XOP_TO_SEG (op)) 484 break; 485 } 486 } 487 } 488 489 powerpc_init_dialect (info); 490 if (info->private_data != NULL) 491 { 492 private_data (info)->special[0].name = ".got"; 493 private_data (info)->special[1].name = ".plt"; 494 } 495 } 496 497 /* Print a big endian PowerPC instruction. */ 498 499 int 500 print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info) 501 { 502 return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info)); 503 } 504 505 /* Print a little endian PowerPC instruction. */ 506 507 int 508 print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info) 509 { 510 return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info)); 511 } 512 513 /* Extract the operand value from the PowerPC or POWER instruction. */ 514 515 static int64_t 516 operand_value_powerpc (const struct powerpc_operand *operand, 517 uint64_t insn, ppc_cpu_t dialect) 518 { 519 int64_t value; 520 int invalid = 0; 521 /* Extract the value from the instruction. */ 522 if (operand->extract) 523 value = (*operand->extract) (insn, dialect, &invalid); 524 else 525 { 526 if (operand->shift >= 0) 527 value = (insn >> operand->shift) & operand->bitm; 528 else 529 value = (insn << -operand->shift) & operand->bitm; 530 if ((operand->flags & PPC_OPERAND_SIGNED) != 0) 531 { 532 /* BITM is always some number of zeros followed by some 533 number of ones, followed by some number of zeros. */ 534 uint64_t top = operand->bitm; 535 /* top & -top gives the rightmost 1 bit, so this 536 fills in any trailing zeros. */ 537 top |= (top & -top) - 1; 538 top &= ~(top >> 1); 539 value = (value ^ top) - top; 540 } 541 } 542 543 return value; 544 } 545 546 /* Determine whether the optional operand(s) should be printed. */ 547 548 static bool 549 skip_optional_operands (const ppc_opindex_t *opindex, 550 uint64_t insn, ppc_cpu_t dialect, bool *is_pcrel) 551 { 552 const struct powerpc_operand *operand; 553 int num_optional; 554 555 for (num_optional = 0; *opindex != 0; opindex++) 556 { 557 operand = &powerpc_operands[*opindex]; 558 if ((operand->flags & PPC_OPERAND_NEXT) != 0) 559 return false; 560 if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0) 561 { 562 int64_t value = operand_value_powerpc (operand, insn, dialect); 563 564 if (operand->shift == 52) 565 *is_pcrel = value != 0; 566 567 /* Negative count is used as a flag to extract function. */ 568 --num_optional; 569 if (value != ppc_optional_operand_value (operand, insn, dialect, 570 num_optional)) 571 return false; 572 } 573 } 574 575 return true; 576 } 577 578 /* Find a match for INSN in the opcode table, given machine DIALECT. */ 579 580 static const struct powerpc_opcode * 581 lookup_powerpc (uint64_t insn, ppc_cpu_t dialect) 582 { 583 const struct powerpc_opcode *opcode, *opcode_end; 584 unsigned long op; 585 586 /* Get the major opcode of the instruction. */ 587 op = PPC_OP (insn); 588 589 /* Find the first match in the opcode table for this major opcode. */ 590 opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1]; 591 for (opcode = powerpc_opcodes + powerpc_opcd_indices[op]; 592 opcode < opcode_end; 593 ++opcode) 594 { 595 const ppc_opindex_t *opindex; 596 const struct powerpc_operand *operand; 597 int invalid; 598 599 if ((insn & opcode->mask) != opcode->opcode 600 || ((dialect & PPC_OPCODE_ANY) == 0 601 && ((opcode->flags & dialect) == 0 602 || (opcode->deprecated & dialect) != 0)) 603 || (opcode->deprecated & dialect & PPC_OPCODE_RAW) != 0) 604 continue; 605 606 /* Check validity of operands. */ 607 invalid = 0; 608 for (opindex = opcode->operands; *opindex != 0; opindex++) 609 { 610 operand = powerpc_operands + *opindex; 611 if (operand->extract) 612 (*operand->extract) (insn, dialect, &invalid); 613 } 614 if (invalid) 615 continue; 616 617 return opcode; 618 } 619 620 return NULL; 621 } 622 623 /* Find a match for INSN in the PREFIX opcode table. */ 624 625 static const struct powerpc_opcode * 626 lookup_prefix (uint64_t insn, ppc_cpu_t dialect) 627 { 628 const struct powerpc_opcode *opcode, *opcode_end; 629 unsigned long seg; 630 631 /* Get the opcode segment of the instruction. */ 632 seg = PPC_PREFIX_SEG (insn); 633 634 /* Find the first match in the opcode table for this major opcode. */ 635 opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1]; 636 for (opcode = prefix_opcodes + prefix_opcd_indices[seg]; 637 opcode < opcode_end; 638 ++opcode) 639 { 640 const ppc_opindex_t *opindex; 641 const struct powerpc_operand *operand; 642 int invalid; 643 644 if ((insn & opcode->mask) != opcode->opcode 645 || ((dialect & PPC_OPCODE_ANY) == 0 646 && (opcode->flags & dialect) == 0) 647 || (opcode->deprecated & dialect) != 0) 648 continue; 649 650 /* Check validity of operands. */ 651 invalid = 0; 652 for (opindex = opcode->operands; *opindex != 0; opindex++) 653 { 654 operand = powerpc_operands + *opindex; 655 if (operand->extract) 656 (*operand->extract) (insn, dialect, &invalid); 657 } 658 if (invalid) 659 continue; 660 661 return opcode; 662 } 663 664 return NULL; 665 } 666 667 /* Find a match for INSN in the VLE opcode table. */ 668 669 static const struct powerpc_opcode * 670 lookup_vle (uint64_t insn, ppc_cpu_t dialect) 671 { 672 const struct powerpc_opcode *opcode; 673 const struct powerpc_opcode *opcode_end; 674 unsigned op, seg; 675 676 op = PPC_OP (insn); 677 if (op >= 0x20 && op <= 0x37) 678 { 679 /* This insn has a 4-bit opcode. */ 680 op &= 0x3c; 681 } 682 seg = VLE_OP_TO_SEG (op); 683 684 /* Find the first match in the opcode table for this major opcode. */ 685 opcode_end = vle_opcodes + vle_opcd_indices[seg + 1]; 686 for (opcode = vle_opcodes + vle_opcd_indices[seg]; 687 opcode < opcode_end; 688 ++opcode) 689 { 690 uint64_t table_opcd = opcode->opcode; 691 uint64_t table_mask = opcode->mask; 692 bool table_op_is_short = PPC_OP_SE_VLE(table_mask); 693 uint64_t insn2; 694 const ppc_opindex_t *opindex; 695 const struct powerpc_operand *operand; 696 int invalid; 697 698 insn2 = insn; 699 if (table_op_is_short) 700 insn2 >>= 16; 701 if ((insn2 & table_mask) != table_opcd 702 || (opcode->deprecated & dialect) != 0) 703 continue; 704 705 /* Check validity of operands. */ 706 invalid = 0; 707 for (opindex = opcode->operands; *opindex != 0; ++opindex) 708 { 709 operand = powerpc_operands + *opindex; 710 if (operand->extract) 711 (*operand->extract) (insn, (ppc_cpu_t)0, &invalid); 712 } 713 if (invalid) 714 continue; 715 716 return opcode; 717 } 718 719 return NULL; 720 } 721 722 /* Find a match for INSN in the SPE2 opcode table. */ 723 724 static const struct powerpc_opcode * 725 lookup_spe2 (uint64_t insn, ppc_cpu_t dialect) 726 { 727 const struct powerpc_opcode *opcode, *opcode_end; 728 unsigned op, xop, seg; 729 730 op = PPC_OP (insn); 731 if (op != 0x4) 732 { 733 /* This is not SPE2 insn. 734 * All SPE2 instructions have OP=4 and differs by XOP */ 735 return NULL; 736 } 737 xop = SPE2_XOP (insn); 738 seg = SPE2_XOP_TO_SEG (xop); 739 740 /* Find the first match in the opcode table for this major opcode. */ 741 opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1]; 742 for (opcode = spe2_opcodes + spe2_opcd_indices[seg]; 743 opcode < opcode_end; 744 ++opcode) 745 { 746 uint64_t table_opcd = opcode->opcode; 747 uint64_t table_mask = opcode->mask; 748 uint64_t insn2; 749 const ppc_opindex_t *opindex; 750 const struct powerpc_operand *operand; 751 int invalid; 752 753 insn2 = insn; 754 if ((insn2 & table_mask) != table_opcd 755 || (opcode->deprecated & dialect) != 0) 756 continue; 757 758 /* Check validity of operands. */ 759 invalid = 0; 760 for (opindex = opcode->operands; *opindex != 0; ++opindex) 761 { 762 operand = powerpc_operands + *opindex; 763 if (operand->extract) 764 (*operand->extract) (insn, (ppc_cpu_t)0, &invalid); 765 } 766 if (invalid) 767 continue; 768 769 return opcode; 770 } 771 772 return NULL; 773 } 774 775 static arelent * 776 bsearch_reloc (arelent **lo, arelent **hi, bfd_vma vma) 777 { 778 while (lo < hi) 779 { 780 arelent **mid = lo + (hi - lo) / 2; 781 arelent *rel = *mid; 782 783 if (vma < rel->address) 784 hi = mid; 785 else if (vma > rel->address) 786 lo = mid + 1; 787 else 788 return rel; 789 } 790 return NULL; 791 } 792 793 static bool 794 print_got_plt (struct sec_buf *sb, uint64_t vma, struct disassemble_info *info) 795 { 796 if (sb->name != NULL) 797 { 798 asection *s = sb->sec; 799 if (s == NULL) 800 { 801 s = bfd_get_section_by_name (info->section->owner, sb->name); 802 sb->sec = s; 803 if (s == NULL) 804 sb->name = NULL; 805 } 806 if (s != NULL 807 && vma >= s->vma 808 && vma < s->vma + s->size) 809 { 810 asymbol *sym = NULL; 811 uint64_t ent = 0; 812 if (info->dynrelcount > 0) 813 { 814 arelent **lo = info->dynrelbuf; 815 arelent **hi = lo + info->dynrelcount; 816 arelent *rel = bsearch_reloc (lo, hi, vma); 817 if (rel != NULL && rel->sym_ptr_ptr != NULL) 818 sym = *rel->sym_ptr_ptr; 819 } 820 if (sym == NULL && (s->flags & SEC_HAS_CONTENTS) != 0) 821 { 822 if (sb->buf == NULL 823 && !bfd_malloc_and_get_section (s->owner, s, &sb->buf)) 824 sb->name = NULL; 825 if (sb->buf != NULL) 826 { 827 ent = bfd_get_64 (s->owner, sb->buf + (vma - s->vma)); 828 if (ent != 0) 829 sym = (*info->symbol_at_address_func) (ent, info); 830 } 831 } 832 if (sym != NULL) 833 (*info->fprintf_func) (info->stream, " [%s@%s]", 834 bfd_asymbol_name (sym), sb->name + 1); 835 else 836 (*info->fprintf_func) (info->stream, " [%" PRIx64 "@%s]", 837 ent, sb->name + 1); 838 return true; 839 } 840 } 841 return false; 842 } 843 844 /* Print a PowerPC or POWER instruction. */ 845 846 static int 847 print_insn_powerpc (bfd_vma memaddr, 848 struct disassemble_info *info, 849 int bigendian, 850 ppc_cpu_t dialect) 851 { 852 bfd_byte buffer[4]; 853 int status; 854 uint64_t insn; 855 const struct powerpc_opcode *opcode; 856 int insn_length = 4; /* Assume we have a normal 4-byte instruction. */ 857 858 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 859 860 /* The final instruction may be a 2-byte VLE insn. */ 861 if (status != 0 && (dialect & PPC_OPCODE_VLE) != 0) 862 { 863 /* Clear buffer so unused bytes will not have garbage in them. */ 864 buffer[2] = buffer[3] = 0; 865 status = (*info->read_memory_func) (memaddr, buffer, 2, info); 866 insn_length = 2; 867 } 868 869 if (status != 0) 870 { 871 (*info->memory_error_func) (status, memaddr, info); 872 return -1; 873 } 874 875 if (bigendian) 876 insn = bfd_getb32 (buffer); 877 else 878 insn = bfd_getl32 (buffer); 879 880 /* Get the major opcode of the insn. */ 881 opcode = NULL; 882 if ((dialect & PPC_OPCODE_POWER10) != 0 883 && PPC_OP (insn) == 0x1) 884 { 885 uint64_t temp_insn, suffix; 886 status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info); 887 if (status == 0) 888 { 889 if (bigendian) 890 suffix = bfd_getb32 (buffer); 891 else 892 suffix = bfd_getl32 (buffer); 893 temp_insn = (insn << 32) | suffix; 894 opcode = lookup_prefix (temp_insn, dialect & ~PPC_OPCODE_ANY); 895 if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0) 896 opcode = lookup_prefix (temp_insn, dialect); 897 if (opcode != NULL) 898 { 899 insn = temp_insn; 900 insn_length = 8; 901 if ((info->flags & WIDE_OUTPUT) != 0) 902 info->bytes_per_line = 8; 903 } 904 } 905 } 906 if (opcode == NULL && (dialect & PPC_OPCODE_VLE) != 0) 907 { 908 opcode = lookup_vle (insn, dialect); 909 if (opcode != NULL && PPC_OP_SE_VLE (opcode->mask)) 910 { 911 /* The operands will be fetched out of the 16-bit instruction. */ 912 insn >>= 16; 913 insn_length = 2; 914 } 915 } 916 if (opcode == NULL && insn_length == 4) 917 { 918 if ((dialect & PPC_OPCODE_SPE2) != 0) 919 opcode = lookup_spe2 (insn, dialect); 920 if (opcode == NULL) 921 opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY); 922 if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0) 923 opcode = lookup_powerpc (insn, dialect); 924 } 925 926 if (opcode != NULL) 927 { 928 const ppc_opindex_t *opindex; 929 const struct powerpc_operand *operand; 930 enum { 931 need_comma = 0, 932 need_1space = 1, 933 need_2spaces = 2, 934 need_3spaces = 3, 935 need_4spaces = 4, 936 need_5spaces = 5, 937 need_6spaces = 6, 938 need_7spaces = 7, 939 need_paren 940 } op_separator; 941 bool skip_optional; 942 bool is_pcrel; 943 uint64_t d34; 944 int blanks; 945 946 (*info->fprintf_func) (info->stream, "%s", opcode->name); 947 /* gdb fprintf_func doesn't return count printed. */ 948 blanks = 8 - strlen (opcode->name); 949 if (blanks <= 0) 950 blanks = 1; 951 952 /* Now extract and print the operands. */ 953 op_separator = blanks; 954 skip_optional = false; 955 is_pcrel = false; 956 d34 = 0; 957 for (opindex = opcode->operands; *opindex != 0; opindex++) 958 { 959 int64_t value; 960 961 operand = powerpc_operands + *opindex; 962 963 /* If all of the optional operands past this one have their 964 default value, then don't print any of them. Except in 965 raw mode, print them all. */ 966 if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0 967 && (dialect & PPC_OPCODE_RAW) == 0) 968 { 969 if (!skip_optional) 970 skip_optional = skip_optional_operands (opindex, insn, 971 dialect, &is_pcrel); 972 if (skip_optional) 973 continue; 974 } 975 976 value = operand_value_powerpc (operand, insn, dialect); 977 978 if (op_separator == need_comma) 979 (*info->fprintf_func) (info->stream, ","); 980 else if (op_separator == need_paren) 981 (*info->fprintf_func) (info->stream, "("); 982 else 983 (*info->fprintf_func) (info->stream, "%*s", op_separator, " "); 984 985 /* Print the operand as directed by the flags. */ 986 if ((operand->flags & PPC_OPERAND_GPR) != 0 987 || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0)) 988 (*info->fprintf_func) (info->stream, "r%" PRId64, value); 989 else if ((operand->flags & PPC_OPERAND_FPR) != 0) 990 (*info->fprintf_func) (info->stream, "f%" PRId64, value); 991 else if ((operand->flags & PPC_OPERAND_VR) != 0) 992 (*info->fprintf_func) (info->stream, "v%" PRId64, value); 993 else if ((operand->flags & PPC_OPERAND_VSR) != 0) 994 (*info->fprintf_func) (info->stream, "vs%" PRId64, value); 995 else if ((operand->flags & PPC_OPERAND_ACC) != 0) 996 (*info->fprintf_func) (info->stream, "a%" PRId64, value); 997 else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) 998 (*info->print_address_func) (memaddr + value, info); 999 else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) 1000 (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info); 1001 else if ((operand->flags & PPC_OPERAND_FSL) != 0) 1002 (*info->fprintf_func) (info->stream, "fsl%" PRId64, value); 1003 else if ((operand->flags & PPC_OPERAND_FCR) != 0) 1004 (*info->fprintf_func) (info->stream, "fcr%" PRId64, value); 1005 else if ((operand->flags & PPC_OPERAND_UDI) != 0) 1006 (*info->fprintf_func) (info->stream, "%" PRId64, value); 1007 else if ((operand->flags & PPC_OPERAND_CR_REG) != 0 1008 && (operand->flags & PPC_OPERAND_CR_BIT) == 0 1009 && (((dialect & PPC_OPCODE_PPC) != 0) 1010 || ((dialect & PPC_OPCODE_VLE) != 0))) 1011 (*info->fprintf_func) (info->stream, "cr%" PRId64, value); 1012 else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0 1013 && (operand->flags & PPC_OPERAND_CR_REG) == 0 1014 && (((dialect & PPC_OPCODE_PPC) != 0) 1015 || ((dialect & PPC_OPCODE_VLE) != 0))) 1016 { 1017 static const char *cbnames[4] = { "lt", "gt", "eq", "so" }; 1018 int cr; 1019 int cc; 1020 1021 cr = value >> 2; 1022 if (cr != 0) 1023 (*info->fprintf_func) (info->stream, "4*cr%d+", cr); 1024 cc = value & 3; 1025 (*info->fprintf_func) (info->stream, "%s", cbnames[cc]); 1026 } 1027 else 1028 (*info->fprintf_func) (info->stream, "%" PRId64, value); 1029 1030 if (operand->shift == 52) 1031 is_pcrel = value != 0; 1032 else if (operand->bitm == UINT64_C (0x3ffffffff)) 1033 d34 = value; 1034 1035 if (op_separator == need_paren) 1036 (*info->fprintf_func) (info->stream, ")"); 1037 1038 op_separator = need_comma; 1039 if ((operand->flags & PPC_OPERAND_PARENS) != 0) 1040 op_separator = need_paren; 1041 } 1042 1043 if (is_pcrel) 1044 { 1045 d34 += memaddr; 1046 (*info->fprintf_func) (info->stream, "\t# %" PRIx64, d34); 1047 asymbol *sym = (*info->symbol_at_address_func) (d34, info); 1048 if (sym) 1049 (*info->fprintf_func) (info->stream, " <%s>", 1050 bfd_asymbol_name (sym)); 1051 1052 if (info->private_data != NULL 1053 && info->section != NULL 1054 && info->section->owner != NULL 1055 && (bfd_get_file_flags (info->section->owner) 1056 & (EXEC_P | DYNAMIC)) != 0 1057 && ((insn & ((-1ULL << 50) | (0x3fULL << 26))) 1058 == ((1ULL << 58) | (1ULL << 52) | (57ULL << 26)) /* pld */)) 1059 { 1060 for (int i = 0; i < 2; i++) 1061 if (print_got_plt (private_data (info)->special + i, d34, info)) 1062 break; 1063 } 1064 } 1065 1066 /* We have found and printed an instruction. */ 1067 return insn_length; 1068 } 1069 1070 /* We could not find a match. */ 1071 if (insn_length == 4) 1072 (*info->fprintf_func) (info->stream, ".long 0x%x", 1073 (unsigned int) insn); 1074 else 1075 (*info->fprintf_func) (info->stream, ".word 0x%x", 1076 (unsigned int) insn >> 16); 1077 return insn_length; 1078 } 1079 1080 const disasm_options_and_args_t * 1081 disassembler_options_powerpc (void) 1082 { 1083 static disasm_options_and_args_t *opts_and_args; 1084 1085 if (opts_and_args == NULL) 1086 { 1087 size_t i, num_options = ARRAY_SIZE (ppc_opts); 1088 disasm_options_t *opts; 1089 1090 opts_and_args = XNEW (disasm_options_and_args_t); 1091 opts_and_args->args = NULL; 1092 1093 opts = &opts_and_args->options; 1094 opts->name = XNEWVEC (const char *, num_options + 1); 1095 opts->description = NULL; 1096 opts->arg = NULL; 1097 for (i = 0; i < num_options; i++) 1098 opts->name[i] = ppc_opts[i].opt; 1099 /* The array we return must be NULL terminated. */ 1100 opts->name[i] = NULL; 1101 } 1102 1103 return opts_and_args; 1104 } 1105 1106 void 1107 print_ppc_disassembler_options (FILE *stream) 1108 { 1109 unsigned int i, col; 1110 1111 fprintf (stream, _("\n\ 1112 The following PPC specific disassembler options are supported for use with\n\ 1113 the -M switch:\n")); 1114 1115 for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++) 1116 { 1117 col += fprintf (stream, " %s,", ppc_opts[i].opt); 1118 if (col > 66) 1119 { 1120 fprintf (stream, "\n"); 1121 col = 0; 1122 } 1123 } 1124 fprintf (stream, "\n"); 1125 } 1126