1 /* RISC-V disassembler 2 Copyright 2011-2014 Free Software Foundation, Inc. 3 4 Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. 5 Based on MIPS target. 6 7 This file is part of the GNU opcodes library. 8 9 This library is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3, or (at your option) 12 any later version. 13 14 It is distributed in the hope that it will be useful, but WITHOUT 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 17 License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 22 MA 02110-1301, USA. */ 23 24 #include "sysdep.h" 25 #include "dis-asm.h" 26 #include "libiberty.h" 27 #include "opcode/riscv.h" 28 #include "opintl.h" 29 #include "elf-bfd.h" 30 #include "elf/riscv.h" 31 32 #include <stdint.h> 33 #include <assert.h> 34 35 struct riscv_private_data 36 { 37 bfd_vma gp; 38 bfd_vma print_addr; 39 bfd_vma hi_addr[OP_MASK_RD + 1]; 40 }; 41 42 static const char * const *riscv_gpr_names; 43 static const char * const *riscv_fpr_names; 44 45 /* Other options */ 46 static int no_aliases; /* If set disassemble as most general inst. */ 47 48 static void 49 set_default_riscv_dis_options (void) 50 { 51 riscv_gpr_names = riscv_gpr_names_abi; 52 riscv_fpr_names = riscv_fpr_names_abi; 53 no_aliases = 0; 54 } 55 56 static void 57 parse_riscv_dis_option (const char *option) 58 { 59 if (CONST_STRNEQ (option, "no-aliases")) 60 no_aliases = 1; 61 else if (CONST_STRNEQ (option, "numeric")) 62 { 63 riscv_gpr_names = riscv_gpr_names_numeric; 64 riscv_fpr_names = riscv_fpr_names_numeric; 65 } 66 67 /* Invalid option. */ 68 fprintf (stderr, _("Unrecognized disassembler option: %s\n"), option); 69 } 70 71 static void 72 parse_riscv_dis_options (const char *opts_in) 73 { 74 char *opts = xstrdup (opts_in), *opt = opts, *opt_end = opts; 75 76 set_default_riscv_dis_options (); 77 78 for ( ; opt_end != NULL; opt = opt_end + 1) 79 { 80 if ((opt_end = strchr (opt, ',')) != NULL) 81 *opt_end = 0; 82 parse_riscv_dis_option (opt); 83 } 84 85 free (opts); 86 } 87 88 /* Print one argument from an array. */ 89 90 static void 91 arg_print (struct disassemble_info *info, unsigned long val, 92 const char* const* array, size_t size) 93 { 94 const char *s = val >= size || array[val] == NULL ? "unknown" : array[val]; 95 (*info->fprintf_func) (info->stream, "%s", s); 96 } 97 98 static void 99 maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset) 100 { 101 if (pd->hi_addr[base_reg] != (bfd_vma)-1) 102 { 103 pd->print_addr = pd->hi_addr[base_reg] + offset; 104 pd->hi_addr[base_reg] = -1; 105 } 106 else if (base_reg == X_GP && pd->gp != (bfd_vma)-1) 107 pd->print_addr = pd->gp + offset; 108 else if (base_reg == X_TP) 109 pd->print_addr = offset; 110 } 111 112 /* Print insn arguments for 32/64-bit code. */ 113 114 static void 115 print_insn_args (const char *d, insn_t l, bfd_vma pc, disassemble_info *info) 116 { 117 struct riscv_private_data *pd = info->private_data; 118 int rs1 = (l >> OP_SH_RS1) & OP_MASK_RS1; 119 int rd = (l >> OP_SH_RD) & OP_MASK_RD; 120 121 if (*d != '\0') 122 (*info->fprintf_func) (info->stream, "\t"); 123 124 for (; *d != '\0'; d++) 125 { 126 switch (*d) 127 { 128 /* Xcustom */ 129 case '^': 130 switch (*++d) 131 { 132 case 'd': 133 (*info->fprintf_func) (info->stream, "%d", rd); 134 break; 135 case 's': 136 (*info->fprintf_func) (info->stream, "%d", rs1); 137 break; 138 case 't': 139 (*info->fprintf_func) 140 ( info->stream, "%d", (int)((l >> OP_SH_RS2) & OP_MASK_RS2)); 141 break; 142 case 'j': 143 (*info->fprintf_func) 144 ( info->stream, "%d", (int)((l >> OP_SH_CUSTOM_IMM) & OP_MASK_CUSTOM_IMM)); 145 break; 146 } 147 break; 148 149 /* Xhwacha */ 150 case '#': 151 switch ( *++d ) { 152 case 'g': 153 (*info->fprintf_func) 154 ( info->stream, "%d", 155 (int)((l >> OP_SH_IMMNGPR) & OP_MASK_IMMNGPR)); 156 break; 157 case 'f': 158 (*info->fprintf_func) 159 ( info->stream, "%d", 160 (int)((l >> OP_SH_IMMNFPR) & OP_MASK_IMMNFPR)); 161 break; 162 case 'p': 163 (*info->fprintf_func) 164 ( info->stream, "%d", 165 (int)((l >> OP_SH_CUSTOM_IMM) & OP_MASK_CUSTOM_IMM)); 166 break; 167 case 'n': 168 (*info->fprintf_func) 169 ( info->stream, "%d", 170 (int)(((l >> OP_SH_IMMSEGNELM) & OP_MASK_IMMSEGNELM) + 1)); 171 break; 172 case 'd': 173 (*info->fprintf_func) 174 ( info->stream, "%s", 175 riscv_vec_gpr_names[(l >> OP_SH_VRD) & OP_MASK_VRD]); 176 break; 177 case 's': 178 (*info->fprintf_func) 179 ( info->stream, "%s", 180 riscv_vec_gpr_names[(l >> OP_SH_VRS) & OP_MASK_VRS]); 181 break; 182 case 't': 183 (*info->fprintf_func) 184 ( info->stream, "%s", 185 riscv_vec_gpr_names[(l >> OP_SH_VRT) & OP_MASK_VRT]); 186 break; 187 case 'r': 188 (*info->fprintf_func) 189 ( info->stream, "%s", 190 riscv_vec_gpr_names[(l >> OP_SH_VRR) & OP_MASK_VRR]); 191 break; 192 case 'D': 193 (*info->fprintf_func) 194 ( info->stream, "%s", 195 riscv_vec_fpr_names[(l >> OP_SH_VFD) & OP_MASK_VFD]); 196 break; 197 case 'S': 198 (*info->fprintf_func) 199 ( info->stream, "%s", 200 riscv_vec_fpr_names[(l >> OP_SH_VFS) & OP_MASK_VFS]); 201 break; 202 case 'T': 203 (*info->fprintf_func) 204 ( info->stream, "%s", 205 riscv_vec_fpr_names[(l >> OP_SH_VFT) & OP_MASK_VFT]); 206 break; 207 case 'R': 208 (*info->fprintf_func) 209 ( info->stream, "%s", 210 riscv_vec_fpr_names[(l >> OP_SH_VFR) & OP_MASK_VFR]); 211 break; 212 } 213 break; 214 215 case ',': 216 case '(': 217 case ')': 218 case '[': 219 case ']': 220 (*info->fprintf_func) (info->stream, "%c", *d); 221 break; 222 223 case '0': 224 break; 225 226 case 'b': 227 case 's': 228 (*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[rs1]); 229 break; 230 231 case 't': 232 (*info->fprintf_func) (info->stream, "%s", 233 riscv_gpr_names[(l >> OP_SH_RS2) & OP_MASK_RS2]); 234 break; 235 236 case 'u': 237 (*info->fprintf_func) (info->stream, "0x%x", (unsigned)EXTRACT_UTYPE_IMM (l) >> RISCV_IMM_BITS); 238 break; 239 240 case 'm': 241 arg_print(info, (l >> OP_SH_RM) & OP_MASK_RM, 242 riscv_rm, ARRAY_SIZE(riscv_rm)); 243 break; 244 245 case 'P': 246 arg_print(info, (l >> OP_SH_PRED) & OP_MASK_PRED, 247 riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ)); 248 break; 249 250 case 'Q': 251 arg_print(info, (l >> OP_SH_SUCC) & OP_MASK_SUCC, 252 riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ)); 253 break; 254 255 case 'o': 256 maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l)); 257 case 'j': 258 if ((l & MASK_ADDI) == MATCH_ADDI || (l & MASK_JALR) == MATCH_JALR) 259 maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l)); 260 (*info->fprintf_func) (info->stream, "%d", (int)EXTRACT_ITYPE_IMM (l)); 261 break; 262 263 case 'q': 264 maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l)); 265 (*info->fprintf_func) (info->stream, "%d", (int)EXTRACT_STYPE_IMM (l)); 266 break; 267 268 case 'a': 269 info->target = EXTRACT_UJTYPE_IMM (l) + pc; 270 (*info->print_address_func) (info->target, info); 271 break; 272 273 case 'p': 274 info->target = EXTRACT_SBTYPE_IMM (l) + pc; 275 (*info->print_address_func) (info->target, info); 276 break; 277 278 case 'd': 279 if ((l & MASK_AUIPC) == MATCH_AUIPC) 280 pd->hi_addr[rd] = pc + EXTRACT_UTYPE_IMM (l); 281 else if ((l & MASK_LUI) == MATCH_LUI) 282 pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l); 283 (*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[rd]); 284 break; 285 286 case 'z': 287 (*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[0]); 288 break; 289 290 case '>': 291 (*info->fprintf_func) (info->stream, "0x%x", 292 (unsigned)((l >> OP_SH_SHAMT) & OP_MASK_SHAMT)); 293 break; 294 295 case '<': 296 (*info->fprintf_func) (info->stream, "0x%x", 297 (unsigned)((l >> OP_SH_SHAMTW) & OP_MASK_SHAMTW)); 298 break; 299 300 case 'S': 301 case 'U': 302 (*info->fprintf_func) (info->stream, "%s", riscv_fpr_names[rs1]); 303 break; 304 305 case 'T': 306 (*info->fprintf_func) (info->stream, "%s", 307 riscv_fpr_names[(l >> OP_SH_RS2) & OP_MASK_RS2]); 308 break; 309 310 case 'D': 311 (*info->fprintf_func) (info->stream, "%s", riscv_fpr_names[rd]); 312 break; 313 314 case 'R': 315 (*info->fprintf_func) (info->stream, "%s", 316 riscv_fpr_names[(l >> OP_SH_RS3) & OP_MASK_RS3]); 317 break; 318 319 case 'E': 320 { 321 const char* csr_name = NULL; 322 unsigned int csr = (l >> OP_SH_CSR) & OP_MASK_CSR; 323 switch (csr) 324 { 325 #define DECLARE_CSR(name, num) case num: csr_name = #name; break; 326 #include "opcode/riscv-opc.h" 327 #undef DECLARE_CSR 328 } 329 if (csr_name) 330 (*info->fprintf_func) (info->stream, "%s", csr_name); 331 else 332 (*info->fprintf_func) (info->stream, "0x%x", csr); 333 break; 334 } 335 336 case 'Z': 337 (*info->fprintf_func) (info->stream, "%d", rs1); 338 break; 339 340 default: 341 /* xgettext:c-format */ 342 (*info->fprintf_func) (info->stream, 343 _("# internal error, undefined modifier (%c)"), 344 *d); 345 return; 346 } 347 } 348 } 349 350 /* Print the RISC-V instruction at address MEMADDR in debugged memory, 351 on using INFO. Returns length of the instruction, in bytes. 352 BIGENDIAN must be 1 if this is big-endian code, 0 if 353 this is little-endian code. */ 354 355 static int 356 riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info) 357 { 358 const struct riscv_opcode *op; 359 static bfd_boolean init = 0; 360 static const char *extension = NULL; 361 static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1]; 362 struct riscv_private_data *pd; 363 int insnlen; 364 365 /* Build a hash table to shorten the search time. */ 366 if (! init) 367 { 368 unsigned int i; 369 unsigned int e_flags = elf_elfheader (info->section->owner)->e_flags; 370 extension = riscv_elf_flag_to_name(EF_GET_RISCV_EXT(e_flags)); 371 372 for (i = 0; i <= OP_MASK_OP; i++) 373 for (op = riscv_opcodes; op < &riscv_opcodes[NUMOPCODES]; op++) 374 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP)) 375 { 376 riscv_hash[i] = op; 377 break; 378 } 379 380 init = 1; 381 } 382 383 if (info->private_data == NULL) 384 { 385 int i; 386 387 pd = info->private_data = calloc(1, sizeof (struct riscv_private_data)); 388 pd->gp = -1; 389 pd->print_addr = -1; 390 for (i = 0; i < (int) ARRAY_SIZE(pd->hi_addr); i++) 391 pd->hi_addr[i] = -1; 392 393 for (i = 0; i < info->symtab_size; i++) 394 if (strcmp (bfd_asymbol_name (info->symtab[i]), "_gp") == 0) 395 pd->gp = bfd_asymbol_value (info->symtab[i]); 396 } 397 else 398 pd = info->private_data; 399 400 insnlen = riscv_insn_length (word); 401 402 info->bytes_per_chunk = insnlen % 4 == 0 ? 4 : 2; 403 info->bytes_per_line = 8; 404 info->display_endian = info->endian; 405 info->insn_info_valid = 1; 406 info->branch_delay_insns = 0; 407 info->data_size = 0; 408 info->insn_type = dis_nonbranch; 409 info->target = 0; 410 info->target2 = 0; 411 412 op = riscv_hash[(word >> OP_SH_OP) & OP_MASK_OP]; 413 if (op != NULL) 414 { 415 for (; op < &riscv_opcodes[NUMOPCODES]; op++) 416 { 417 if ((op->match_func) (op, word) 418 && !(no_aliases && (op->pinfo & INSN_ALIAS)) 419 && !(op->subset[0] == 'X' && strcmp(op->subset, extension))) 420 { 421 (*info->fprintf_func) (info->stream, "%s", op->name); 422 print_insn_args (op->args, word, memaddr, info); 423 if (pd->print_addr != (bfd_vma)-1) 424 { 425 info->target = pd->print_addr; 426 (*info->fprintf_func) (info->stream, " # "); 427 (*info->print_address_func) (info->target, info); 428 pd->print_addr = -1; 429 } 430 return insnlen; 431 } 432 } 433 } 434 435 /* Handle undefined instructions. */ 436 info->insn_type = dis_noninsn; 437 (*info->fprintf_func) (info->stream, "0x%llx", (unsigned long long)word); 438 return insnlen; 439 } 440 441 int 442 print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info) 443 { 444 uint16_t i2; 445 insn_t insn = 0; 446 bfd_vma n; 447 int status; 448 449 if (info->disassembler_options != NULL) 450 { 451 parse_riscv_dis_options (info->disassembler_options); 452 /* Avoid repeatedly parsing the options. */ 453 info->disassembler_options = NULL; 454 } 455 else if (riscv_gpr_names == NULL) 456 set_default_riscv_dis_options (); 457 458 /* Instructions are a sequence of 2-byte packets in little-endian order. */ 459 for (n = 0; n < sizeof(insn) && n < riscv_insn_length (insn); n += 2) 460 { 461 status = (*info->read_memory_func) (memaddr + n, (bfd_byte*)&i2, 2, info); 462 if (status != 0) 463 { 464 if (n > 0) /* Don't fail just because we fell off the end. */ 465 break; 466 (*info->memory_error_func) (status, memaddr, info); 467 return status; 468 } 469 470 i2 = bfd_getl16 (&i2); 471 insn |= (insn_t)i2 << (8*n); 472 } 473 474 return riscv_disassemble_insn (memaddr, insn, info); 475 } 476 477 void 478 print_riscv_disassembler_options (FILE *stream) 479 { 480 fprintf (stream, _("\n\ 481 The following RISC-V-specific disassembler options are supported for use\n\ 482 with the -M switch (multiple options should be separated by commas):\n")); 483 484 fprintf (stream, _("\n\ 485 numeric Print numeric reigster names, rather than ABI names.\n")); 486 487 fprintf (stream, _("\n\ 488 no-aliases Disassemble only into canonical instructions, rather\n\ 489 than into pseudoinstructions.\n")); 490 491 fprintf (stream, _("\n")); 492 } 493