riscv-dis.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197
  1. /* RISC-V disassembler
  2. Copyright (C) 2011-2022 Free Software Foundation, Inc.
  3. Contributed by Andrew Waterman (andrew@sifive.com).
  4. Based on MIPS target.
  5. This file is part of the GNU opcodes library.
  6. This library 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, or (at your option)
  9. any later version.
  10. It is distributed in the hope that it will be useful, but WITHOUT
  11. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  13. License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; see the file COPYING3. If not,
  16. see <http://www.gnu.org/licenses/>. */
  17. #include "sysdep.h"
  18. #include "disassemble.h"
  19. #include "libiberty.h"
  20. #include "opcode/riscv.h"
  21. #include "opintl.h"
  22. #include "elf-bfd.h"
  23. #include "elf/riscv.h"
  24. #include "elfxx-riscv.h"
  25. #include <stdint.h>
  26. #include <ctype.h>
  27. static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_DRAFT - 1;
  28. static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
  29. unsigned xlen = 0;
  30. static riscv_subset_list_t riscv_subsets;
  31. static riscv_parse_subset_t riscv_rps_dis =
  32. {
  33. &riscv_subsets, /* subset_list. */
  34. opcodes_error_handler,/* error_handler. */
  35. &xlen, /* xlen. */
  36. &default_isa_spec, /* isa_spec. */
  37. false, /* check_unknown_prefixed_ext. */
  38. };
  39. struct riscv_private_data
  40. {
  41. bfd_vma gp;
  42. bfd_vma print_addr;
  43. bfd_vma hi_addr[OP_MASK_RD + 1];
  44. };
  45. /* Used for mapping symbols. */
  46. static int last_map_symbol = -1;
  47. static bfd_vma last_stop_offset = 0;
  48. enum riscv_seg_mstate last_map_state;
  49. static const char * const *riscv_gpr_names;
  50. static const char * const *riscv_fpr_names;
  51. /* If set, disassemble as most general instruction. */
  52. static int no_aliases;
  53. static void
  54. set_default_riscv_dis_options (void)
  55. {
  56. riscv_gpr_names = riscv_gpr_names_abi;
  57. riscv_fpr_names = riscv_fpr_names_abi;
  58. no_aliases = 0;
  59. }
  60. static bool
  61. parse_riscv_dis_option_without_args (const char *option)
  62. {
  63. if (strcmp (option, "no-aliases") == 0)
  64. no_aliases = 1;
  65. else if (strcmp (option, "numeric") == 0)
  66. {
  67. riscv_gpr_names = riscv_gpr_names_numeric;
  68. riscv_fpr_names = riscv_fpr_names_numeric;
  69. }
  70. else
  71. return false;
  72. return true;
  73. }
  74. static void
  75. parse_riscv_dis_option (const char *option)
  76. {
  77. char *equal, *value;
  78. if (parse_riscv_dis_option_without_args (option))
  79. return;
  80. equal = strchr (option, '=');
  81. if (equal == NULL)
  82. {
  83. /* The option without '=' should be defined above. */
  84. opcodes_error_handler (_("unrecognized disassembler option: %s"), option);
  85. return;
  86. }
  87. if (equal == option
  88. || *(equal + 1) == '\0')
  89. {
  90. /* Invalid options with '=', no option name before '=',
  91. and no value after '='. */
  92. opcodes_error_handler (_("unrecognized disassembler option with '=': %s"),
  93. option);
  94. return;
  95. }
  96. *equal = '\0';
  97. value = equal + 1;
  98. if (strcmp (option, "priv-spec") == 0)
  99. {
  100. enum riscv_spec_class priv_spec = PRIV_SPEC_CLASS_NONE;
  101. const char *name = NULL;
  102. RISCV_GET_PRIV_SPEC_CLASS (value, priv_spec);
  103. if (priv_spec == PRIV_SPEC_CLASS_NONE)
  104. opcodes_error_handler (_("unknown privileged spec set by %s=%s"),
  105. option, value);
  106. else if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
  107. default_priv_spec = priv_spec;
  108. else if (default_priv_spec != priv_spec)
  109. {
  110. RISCV_GET_PRIV_SPEC_NAME (name, default_priv_spec);
  111. opcodes_error_handler (_("mis-matched privilege spec set by %s=%s, "
  112. "the elf privilege attribute is %s"),
  113. option, value, name);
  114. }
  115. }
  116. else
  117. {
  118. /* xgettext:c-format */
  119. opcodes_error_handler (_("unrecognized disassembler option: %s"), option);
  120. }
  121. }
  122. static void
  123. parse_riscv_dis_options (const char *opts_in)
  124. {
  125. char *opts = xstrdup (opts_in), *opt = opts, *opt_end = opts;
  126. set_default_riscv_dis_options ();
  127. for ( ; opt_end != NULL; opt = opt_end + 1)
  128. {
  129. if ((opt_end = strchr (opt, ',')) != NULL)
  130. *opt_end = 0;
  131. parse_riscv_dis_option (opt);
  132. }
  133. free (opts);
  134. }
  135. /* Print one argument from an array. */
  136. static void
  137. arg_print (struct disassemble_info *info, unsigned long val,
  138. const char* const* array, size_t size)
  139. {
  140. const char *s = val >= size || array[val] == NULL ? "unknown" : array[val];
  141. (*info->fprintf_styled_func) (info->stream, dis_style_text, "%s", s);
  142. }
  143. static void
  144. maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
  145. int wide)
  146. {
  147. if (pd->hi_addr[base_reg] != (bfd_vma)-1)
  148. {
  149. pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) + offset;
  150. pd->hi_addr[base_reg] = -1;
  151. }
  152. else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
  153. pd->print_addr = pd->gp + offset;
  154. else if (base_reg == X_TP || base_reg == 0)
  155. pd->print_addr = offset;
  156. /* Sign-extend a 32-bit value to a 64-bit value. */
  157. if (wide)
  158. pd->print_addr = (bfd_vma)(int32_t) pd->print_addr;
  159. }
  160. /* Print insn arguments for 32/64-bit code. */
  161. static void
  162. print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info)
  163. {
  164. struct riscv_private_data *pd = info->private_data;
  165. int rs1 = (l >> OP_SH_RS1) & OP_MASK_RS1;
  166. int rd = (l >> OP_SH_RD) & OP_MASK_RD;
  167. fprintf_styled_ftype print = info->fprintf_styled_func;
  168. const char *opargStart;
  169. if (*oparg != '\0')
  170. print (info->stream, dis_style_text, "\t");
  171. for (; *oparg != '\0'; oparg++)
  172. {
  173. opargStart = oparg;
  174. switch (*oparg)
  175. {
  176. case 'C': /* RVC */
  177. switch (*++oparg)
  178. {
  179. case 's': /* RS1 x8-x15. */
  180. case 'w': /* RS1 x8-x15. */
  181. print (info->stream, dis_style_register, "%s",
  182. riscv_gpr_names[EXTRACT_OPERAND (CRS1S, l) + 8]);
  183. break;
  184. case 't': /* RS2 x8-x15. */
  185. case 'x': /* RS2 x8-x15. */
  186. print (info->stream, dis_style_register, "%s",
  187. riscv_gpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]);
  188. break;
  189. case 'U': /* RS1, constrained to equal RD. */
  190. print (info->stream, dis_style_register,
  191. "%s", riscv_gpr_names[rd]);
  192. break;
  193. case 'c': /* RS1, constrained to equal sp. */
  194. print (info->stream, dis_style_register, "%s",
  195. riscv_gpr_names[X_SP]);
  196. break;
  197. case 'V': /* RS2 */
  198. print (info->stream, dis_style_register, "%s",
  199. riscv_gpr_names[EXTRACT_OPERAND (CRS2, l)]);
  200. break;
  201. case 'o':
  202. case 'j':
  203. if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
  204. maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
  205. if (info->mach == bfd_mach_riscv64
  206. && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
  207. maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
  208. print (info->stream, dis_style_immediate, "%d",
  209. (int)EXTRACT_CITYPE_IMM (l));
  210. break;
  211. case 'k':
  212. print (info->stream, dis_style_address_offset, "%d",
  213. (int)EXTRACT_CLTYPE_LW_IMM (l));
  214. break;
  215. case 'l':
  216. print (info->stream, dis_style_address_offset, "%d",
  217. (int)EXTRACT_CLTYPE_LD_IMM (l));
  218. break;
  219. case 'm':
  220. print (info->stream, dis_style_address_offset, "%d",
  221. (int)EXTRACT_CITYPE_LWSP_IMM (l));
  222. break;
  223. case 'n':
  224. print (info->stream, dis_style_address_offset, "%d",
  225. (int)EXTRACT_CITYPE_LDSP_IMM (l));
  226. break;
  227. case 'K':
  228. print (info->stream, dis_style_immediate, "%d",
  229. (int)EXTRACT_CIWTYPE_ADDI4SPN_IMM (l));
  230. break;
  231. case 'L':
  232. print (info->stream, dis_style_immediate, "%d",
  233. (int)EXTRACT_CITYPE_ADDI16SP_IMM (l));
  234. break;
  235. case 'M':
  236. print (info->stream, dis_style_address_offset, "%d",
  237. (int)EXTRACT_CSSTYPE_SWSP_IMM (l));
  238. break;
  239. case 'N':
  240. print (info->stream, dis_style_address_offset, "%d",
  241. (int)EXTRACT_CSSTYPE_SDSP_IMM (l));
  242. break;
  243. case 'p':
  244. info->target = EXTRACT_CBTYPE_IMM (l) + pc;
  245. (*info->print_address_func) (info->target, info);
  246. break;
  247. case 'a':
  248. info->target = EXTRACT_CJTYPE_IMM (l) + pc;
  249. (*info->print_address_func) (info->target, info);
  250. break;
  251. case 'u':
  252. print (info->stream, dis_style_immediate, "0x%x",
  253. (int)(EXTRACT_CITYPE_IMM (l) & (RISCV_BIGIMM_REACH-1)));
  254. break;
  255. case '>':
  256. print (info->stream, dis_style_immediate, "0x%x",
  257. (int)EXTRACT_CITYPE_IMM (l) & 0x3f);
  258. break;
  259. case '<':
  260. print (info->stream, dis_style_immediate, "0x%x",
  261. (int)EXTRACT_CITYPE_IMM (l) & 0x1f);
  262. break;
  263. case 'T': /* Floating-point RS2. */
  264. print (info->stream, dis_style_register, "%s",
  265. riscv_fpr_names[EXTRACT_OPERAND (CRS2, l)]);
  266. break;
  267. case 'D': /* Floating-point RS2 x8-x15. */
  268. print (info->stream, dis_style_register, "%s",
  269. riscv_fpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]);
  270. break;
  271. }
  272. break;
  273. case 'V': /* RVV */
  274. switch (*++oparg)
  275. {
  276. case 'd':
  277. case 'f':
  278. print (info->stream, dis_style_register, "%s",
  279. riscv_vecr_names_numeric[EXTRACT_OPERAND (VD, l)]);
  280. break;
  281. case 'e':
  282. if (!EXTRACT_OPERAND (VWD, l))
  283. print (info->stream, dis_style_register, "%s",
  284. riscv_gpr_names[0]);
  285. else
  286. print (info->stream, dis_style_register, "%s",
  287. riscv_vecr_names_numeric[EXTRACT_OPERAND (VD, l)]);
  288. break;
  289. case 's':
  290. print (info->stream, dis_style_register, "%s",
  291. riscv_vecr_names_numeric[EXTRACT_OPERAND (VS1, l)]);
  292. break;
  293. case 't':
  294. case 'u': /* VS1 == VS2 already verified at this point. */
  295. case 'v': /* VD == VS1 == VS2 already verified at this point. */
  296. print (info->stream, dis_style_register, "%s",
  297. riscv_vecr_names_numeric[EXTRACT_OPERAND (VS2, l)]);
  298. break;
  299. case '0':
  300. print (info->stream, dis_style_register, "%s",
  301. riscv_vecr_names_numeric[0]);
  302. break;
  303. case 'b':
  304. case 'c':
  305. {
  306. int imm = (*oparg == 'b') ? EXTRACT_RVV_VB_IMM (l)
  307. : EXTRACT_RVV_VC_IMM (l);
  308. unsigned int imm_vlmul = EXTRACT_OPERAND (VLMUL, imm);
  309. unsigned int imm_vsew = EXTRACT_OPERAND (VSEW, imm);
  310. unsigned int imm_vta = EXTRACT_OPERAND (VTA, imm);
  311. unsigned int imm_vma = EXTRACT_OPERAND (VMA, imm);
  312. unsigned int imm_vtype_res = (imm >> 8);
  313. if (imm_vsew < ARRAY_SIZE (riscv_vsew)
  314. && imm_vlmul < ARRAY_SIZE (riscv_vlmul)
  315. && imm_vta < ARRAY_SIZE (riscv_vta)
  316. && imm_vma < ARRAY_SIZE (riscv_vma)
  317. && !imm_vtype_res
  318. && riscv_vsew[imm_vsew] != NULL
  319. && riscv_vlmul[imm_vlmul] != NULL)
  320. print (info->stream, dis_style_text, "%s,%s,%s,%s",
  321. riscv_vsew[imm_vsew],
  322. riscv_vlmul[imm_vlmul], riscv_vta[imm_vta],
  323. riscv_vma[imm_vma]);
  324. else
  325. print (info->stream, dis_style_immediate, "%d", imm);
  326. }
  327. break;
  328. case 'i':
  329. print (info->stream, dis_style_immediate, "%d",
  330. (int)EXTRACT_RVV_VI_IMM (l));
  331. break;
  332. case 'j':
  333. print (info->stream, dis_style_immediate, "%d",
  334. (int)EXTRACT_RVV_VI_UIMM (l));
  335. break;
  336. case 'k':
  337. print (info->stream, dis_style_immediate, "%d",
  338. (int)EXTRACT_RVV_OFFSET (l));
  339. break;
  340. case 'm':
  341. if (! EXTRACT_OPERAND (VMASK, l))
  342. print (info->stream, dis_style_register, ",%s",
  343. riscv_vecm_names_numeric[0]);
  344. break;
  345. }
  346. break;
  347. case ',':
  348. case '(':
  349. case ')':
  350. case '[':
  351. case ']':
  352. print (info->stream, dis_style_text, "%c", *oparg);
  353. break;
  354. case '0':
  355. /* Only print constant 0 if it is the last argument. */
  356. if (!oparg[1])
  357. print (info->stream, dis_style_immediate, "0");
  358. break;
  359. case 'b':
  360. case 's':
  361. if ((l & MASK_JALR) == MATCH_JALR)
  362. maybe_print_address (pd, rs1, 0, 0);
  363. print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
  364. break;
  365. case 't':
  366. print (info->stream, dis_style_register, "%s",
  367. riscv_gpr_names[EXTRACT_OPERAND (RS2, l)]);
  368. break;
  369. case 'u':
  370. print (info->stream, dis_style_immediate, "0x%x",
  371. (unsigned)EXTRACT_UTYPE_IMM (l) >> RISCV_IMM_BITS);
  372. break;
  373. case 'm':
  374. arg_print (info, EXTRACT_OPERAND (RM, l),
  375. riscv_rm, ARRAY_SIZE (riscv_rm));
  376. break;
  377. case 'P':
  378. arg_print (info, EXTRACT_OPERAND (PRED, l),
  379. riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ));
  380. break;
  381. case 'Q':
  382. arg_print (info, EXTRACT_OPERAND (SUCC, l),
  383. riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ));
  384. break;
  385. case 'o':
  386. maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
  387. /* Fall through. */
  388. case 'j':
  389. if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
  390. || (l & MASK_JALR) == MATCH_JALR)
  391. maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
  392. if (info->mach == bfd_mach_riscv64
  393. && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
  394. maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
  395. print (info->stream, dis_style_immediate, "%d",
  396. (int)EXTRACT_ITYPE_IMM (l));
  397. break;
  398. case 'q':
  399. maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
  400. print (info->stream, dis_style_address_offset, "%d",
  401. (int)EXTRACT_STYPE_IMM (l));
  402. break;
  403. case 'f':
  404. print (info->stream, dis_style_address_offset, "%d",
  405. (int)EXTRACT_STYPE_IMM (l));
  406. break;
  407. case 'a':
  408. info->target = EXTRACT_JTYPE_IMM (l) + pc;
  409. (*info->print_address_func) (info->target, info);
  410. break;
  411. case 'p':
  412. info->target = EXTRACT_BTYPE_IMM (l) + pc;
  413. (*info->print_address_func) (info->target, info);
  414. break;
  415. case 'd':
  416. if ((l & MASK_AUIPC) == MATCH_AUIPC)
  417. pd->hi_addr[rd] = pc + EXTRACT_UTYPE_IMM (l);
  418. else if ((l & MASK_LUI) == MATCH_LUI)
  419. pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l);
  420. else if ((l & MASK_C_LUI) == MATCH_C_LUI)
  421. pd->hi_addr[rd] = EXTRACT_CITYPE_LUI_IMM (l);
  422. print (info->stream, dis_style_register, "%s", riscv_gpr_names[rd]);
  423. break;
  424. case 'y':
  425. print (info->stream, dis_style_text, "0x%x",
  426. (int)EXTRACT_OPERAND (BS, l));
  427. break;
  428. case 'z':
  429. print (info->stream, dis_style_register, "%s", riscv_gpr_names[0]);
  430. break;
  431. case '>':
  432. print (info->stream, dis_style_immediate, "0x%x",
  433. (int)EXTRACT_OPERAND (SHAMT, l));
  434. break;
  435. case '<':
  436. print (info->stream, dis_style_immediate, "0x%x",
  437. (int)EXTRACT_OPERAND (SHAMTW, l));
  438. break;
  439. case 'S':
  440. case 'U':
  441. print (info->stream, dis_style_register, "%s", riscv_fpr_names[rs1]);
  442. break;
  443. case 'T':
  444. print (info->stream, dis_style_register, "%s",
  445. riscv_fpr_names[EXTRACT_OPERAND (RS2, l)]);
  446. break;
  447. case 'D':
  448. print (info->stream, dis_style_register, "%s", riscv_fpr_names[rd]);
  449. break;
  450. case 'R':
  451. print (info->stream, dis_style_register, "%s",
  452. riscv_fpr_names[EXTRACT_OPERAND (RS3, l)]);
  453. break;
  454. case 'E':
  455. {
  456. static const char *riscv_csr_hash[4096]; /* Total 2^12 CSRs. */
  457. static bool init_csr = false;
  458. unsigned int csr = EXTRACT_OPERAND (CSR, l);
  459. if (!init_csr)
  460. {
  461. unsigned int i;
  462. for (i = 0; i < 4096; i++)
  463. riscv_csr_hash[i] = NULL;
  464. /* Set to the newest privileged version. */
  465. if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
  466. default_priv_spec = PRIV_SPEC_CLASS_DRAFT - 1;
  467. #define DECLARE_CSR(name, num, class, define_version, abort_version) \
  468. if (riscv_csr_hash[num] == NULL \
  469. && ((define_version == PRIV_SPEC_CLASS_NONE \
  470. && abort_version == PRIV_SPEC_CLASS_NONE) \
  471. || (default_priv_spec >= define_version \
  472. && default_priv_spec < abort_version))) \
  473. riscv_csr_hash[num] = #name;
  474. #define DECLARE_CSR_ALIAS(name, num, class, define_version, abort_version) \
  475. DECLARE_CSR (name, num, class, define_version, abort_version)
  476. #include "opcode/riscv-opc.h"
  477. #undef DECLARE_CSR
  478. }
  479. if (riscv_csr_hash[csr] != NULL)
  480. print (info->stream, dis_style_text, "%s", riscv_csr_hash[csr]);
  481. else
  482. print (info->stream, dis_style_text, "0x%x", csr);
  483. break;
  484. }
  485. case 'Y':
  486. print (info->stream, dis_style_text, "0x%x",
  487. (int) EXTRACT_OPERAND (RNUM, l));
  488. break;
  489. case 'Z':
  490. print (info->stream, dis_style_text, "%d", rs1);
  491. break;
  492. default:
  493. /* xgettext:c-format */
  494. print (info->stream, dis_style_text,
  495. _("# internal error, undefined modifier (%c)"),
  496. *opargStart);
  497. return;
  498. }
  499. }
  500. }
  501. /* Print the RISC-V instruction at address MEMADDR in debugged memory,
  502. on using INFO. Returns length of the instruction, in bytes.
  503. BIGENDIAN must be 1 if this is big-endian code, 0 if
  504. this is little-endian code. */
  505. static int
  506. riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
  507. {
  508. const struct riscv_opcode *op;
  509. static bool init = 0;
  510. static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1];
  511. struct riscv_private_data *pd;
  512. int insnlen;
  513. #define OP_HASH_IDX(i) ((i) & (riscv_insn_length (i) == 2 ? 0x3 : OP_MASK_OP))
  514. /* Build a hash table to shorten the search time. */
  515. if (! init)
  516. {
  517. for (op = riscv_opcodes; op->name; op++)
  518. if (!riscv_hash[OP_HASH_IDX (op->match)])
  519. riscv_hash[OP_HASH_IDX (op->match)] = op;
  520. init = 1;
  521. }
  522. if (info->private_data == NULL)
  523. {
  524. int i;
  525. pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
  526. pd->gp = -1;
  527. pd->print_addr = -1;
  528. for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
  529. pd->hi_addr[i] = -1;
  530. for (i = 0; i < info->symtab_size; i++)
  531. if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
  532. pd->gp = bfd_asymbol_value (info->symtab[i]);
  533. }
  534. else
  535. pd = info->private_data;
  536. insnlen = riscv_insn_length (word);
  537. /* RISC-V instructions are always little-endian. */
  538. info->endian_code = BFD_ENDIAN_LITTLE;
  539. info->bytes_per_chunk = insnlen % 4 == 0 ? 4 : 2;
  540. info->bytes_per_line = 8;
  541. /* We don't support constant pools, so this must be code. */
  542. info->display_endian = info->endian_code;
  543. info->insn_info_valid = 1;
  544. info->branch_delay_insns = 0;
  545. info->data_size = 0;
  546. info->insn_type = dis_nonbranch;
  547. info->target = 0;
  548. info->target2 = 0;
  549. op = riscv_hash[OP_HASH_IDX (word)];
  550. if (op != NULL)
  551. {
  552. /* If XLEN is not known, get its value from the ELF class. */
  553. if (info->mach == bfd_mach_riscv64)
  554. xlen = 64;
  555. else if (info->mach == bfd_mach_riscv32)
  556. xlen = 32;
  557. else if (info->section != NULL)
  558. {
  559. Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner);
  560. xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32;
  561. }
  562. /* If arch has ZFINX flags, use gpr for disassemble. */
  563. if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
  564. riscv_fpr_names = riscv_gpr_names_abi;
  565. for (; op->name; op++)
  566. {
  567. /* Does the opcode match? */
  568. if (! (op->match_func) (op, word))
  569. continue;
  570. /* Is this a pseudo-instruction and may we print it as such? */
  571. if (no_aliases && (op->pinfo & INSN_ALIAS))
  572. continue;
  573. /* Is this instruction restricted to a certain value of XLEN? */
  574. if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
  575. continue;
  576. if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class))
  577. continue;
  578. /* It's a match. */
  579. (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
  580. "%s", op->name);
  581. print_insn_args (op->args, word, memaddr, info);
  582. /* Try to disassemble multi-instruction addressing sequences. */
  583. if (pd->print_addr != (bfd_vma)-1)
  584. {
  585. info->target = pd->print_addr;
  586. (*info->fprintf_styled_func)
  587. (info->stream, dis_style_comment_start, " # ");
  588. (*info->print_address_func) (info->target, info);
  589. pd->print_addr = -1;
  590. }
  591. /* Finish filling out insn_info fields. */
  592. switch (op->pinfo & INSN_TYPE)
  593. {
  594. case INSN_BRANCH:
  595. info->insn_type = dis_branch;
  596. break;
  597. case INSN_CONDBRANCH:
  598. info->insn_type = dis_condbranch;
  599. break;
  600. case INSN_JSR:
  601. info->insn_type = dis_jsr;
  602. break;
  603. case INSN_DREF:
  604. info->insn_type = dis_dref;
  605. break;
  606. default:
  607. break;
  608. }
  609. if (op->pinfo & INSN_DATA_SIZE)
  610. {
  611. int size = ((op->pinfo & INSN_DATA_SIZE)
  612. >> INSN_DATA_SIZE_SHIFT);
  613. info->data_size = 1 << (size - 1);
  614. }
  615. return insnlen;
  616. }
  617. }
  618. /* We did not find a match, so just print the instruction bits. */
  619. info->insn_type = dis_noninsn;
  620. switch (insnlen)
  621. {
  622. case 2:
  623. case 4:
  624. case 8:
  625. (*info->fprintf_styled_func)
  626. (info->stream, dis_style_assembler_directive, ".%dbyte\t", insnlen);
  627. (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
  628. "0x%llx", (unsigned long long) word);
  629. break;
  630. default:
  631. {
  632. int i;
  633. (*info->fprintf_styled_func)
  634. (info->stream, dis_style_assembler_directive, ".byte\t");
  635. for (i = 0; i < insnlen; ++i)
  636. {
  637. if (i > 0)
  638. (*info->fprintf_styled_func) (info->stream, dis_style_text,
  639. ", ");
  640. (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
  641. "0x%02x",
  642. (unsigned int) (word & 0xff));
  643. word >>= 8;
  644. }
  645. }
  646. break;
  647. }
  648. return insnlen;
  649. }
  650. /* Return true if we find the suitable mapping symbol,
  651. and also update the STATE. Otherwise, return false. */
  652. static bool
  653. riscv_get_map_state (int n,
  654. enum riscv_seg_mstate *state,
  655. struct disassemble_info *info)
  656. {
  657. const char *name;
  658. /* If the symbol is in a different section, ignore it. */
  659. if (info->section != NULL
  660. && info->section != info->symtab[n]->section)
  661. return false;
  662. name = bfd_asymbol_name(info->symtab[n]);
  663. if (strcmp (name, "$x") == 0)
  664. *state = MAP_INSN;
  665. else if (strcmp (name, "$d") == 0)
  666. *state = MAP_DATA;
  667. else
  668. return false;
  669. return true;
  670. }
  671. /* Check the sorted symbol table (sorted by the symbol value), find the
  672. suitable mapping symbols. */
  673. static enum riscv_seg_mstate
  674. riscv_search_mapping_symbol (bfd_vma memaddr,
  675. struct disassemble_info *info)
  676. {
  677. enum riscv_seg_mstate mstate;
  678. bool from_last_map_symbol;
  679. bool found = false;
  680. int symbol = -1;
  681. int n;
  682. /* Decide whether to print the data or instruction by default, in case
  683. we can not find the corresponding mapping symbols. */
  684. mstate = MAP_DATA;
  685. if ((info->section
  686. && info->section->flags & SEC_CODE)
  687. || !info->section)
  688. mstate = MAP_INSN;
  689. if (info->symtab_size == 0
  690. || bfd_asymbol_flavour (*info->symtab) != bfd_target_elf_flavour)
  691. return mstate;
  692. /* Reset the last_map_symbol if we start to dump a new section. */
  693. if (memaddr <= 0)
  694. last_map_symbol = -1;
  695. /* If the last stop offset is different from the current one, then
  696. don't use the last_map_symbol to search. We usually reset the
  697. info->stop_offset when handling a new section. */
  698. from_last_map_symbol = (last_map_symbol >= 0
  699. && info->stop_offset == last_stop_offset);
  700. /* Start scanning at the start of the function, or wherever
  701. we finished last time. */
  702. n = info->symtab_pos + 1;
  703. if (from_last_map_symbol && n >= last_map_symbol)
  704. n = last_map_symbol;
  705. /* Find the suitable mapping symbol to dump. */
  706. for (; n < info->symtab_size; n++)
  707. {
  708. bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
  709. /* We have searched all possible symbols in the range. */
  710. if (addr > memaddr)
  711. break;
  712. if (riscv_get_map_state (n, &mstate, info))
  713. {
  714. symbol = n;
  715. found = true;
  716. /* Do not stop searching, in case there are some mapping
  717. symbols have the same value, but have different names.
  718. Use the last one. */
  719. }
  720. }
  721. /* We can not find the suitable mapping symbol above. Therefore, we
  722. look forwards and try to find it again, but don't go pass the start
  723. of the section. Otherwise a data section without mapping symbols
  724. can pick up a text mapping symbol of a preceeding section. */
  725. if (!found)
  726. {
  727. n = info->symtab_pos;
  728. if (from_last_map_symbol && n >= last_map_symbol)
  729. n = last_map_symbol;
  730. for (; n >= 0; n--)
  731. {
  732. bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
  733. /* We have searched all possible symbols in the range. */
  734. if (addr < (info->section ? info->section->vma : 0))
  735. break;
  736. /* Stop searching once we find the closed mapping symbol. */
  737. if (riscv_get_map_state (n, &mstate, info))
  738. {
  739. symbol = n;
  740. found = true;
  741. break;
  742. }
  743. }
  744. }
  745. /* Save the information for next use. */
  746. last_map_symbol = symbol;
  747. last_stop_offset = info->stop_offset;
  748. return mstate;
  749. }
  750. /* Decide which data size we should print. */
  751. static bfd_vma
  752. riscv_data_length (bfd_vma memaddr,
  753. disassemble_info *info)
  754. {
  755. bfd_vma length;
  756. bool found = false;
  757. length = 4;
  758. if (info->symtab_size != 0
  759. && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour
  760. && last_map_symbol >= 0)
  761. {
  762. int n;
  763. enum riscv_seg_mstate m = MAP_NONE;
  764. for (n = last_map_symbol + 1; n < info->symtab_size; n++)
  765. {
  766. bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
  767. if (addr > memaddr
  768. && riscv_get_map_state (n, &m, info))
  769. {
  770. if (addr - memaddr < length)
  771. length = addr - memaddr;
  772. found = true;
  773. break;
  774. }
  775. }
  776. }
  777. if (!found)
  778. {
  779. /* Do not set the length which exceeds the section size. */
  780. bfd_vma offset = info->section->vma + info->section->size;
  781. offset -= memaddr;
  782. length = (offset < length) ? offset : length;
  783. }
  784. length = length == 3 ? 2 : length;
  785. return length;
  786. }
  787. /* Dump the data contents. */
  788. static int
  789. riscv_disassemble_data (bfd_vma memaddr ATTRIBUTE_UNUSED,
  790. insn_t data,
  791. disassemble_info *info)
  792. {
  793. info->display_endian = info->endian;
  794. switch (info->bytes_per_chunk)
  795. {
  796. case 1:
  797. info->bytes_per_line = 6;
  798. (*info->fprintf_styled_func)
  799. (info->stream, dis_style_assembler_directive, ".byte\t");
  800. (*info->fprintf_styled_func)
  801. (info->stream, dis_style_assembler_directive, "0x%02llx",
  802. (unsigned long long) data);
  803. break;
  804. case 2:
  805. info->bytes_per_line = 8;
  806. (*info->fprintf_styled_func)
  807. (info->stream, dis_style_assembler_directive, ".short\t");
  808. (*info->fprintf_styled_func)
  809. (info->stream, dis_style_immediate, "0x%04llx",
  810. (unsigned long long) data);
  811. break;
  812. case 4:
  813. info->bytes_per_line = 8;
  814. (*info->fprintf_styled_func)
  815. (info->stream, dis_style_assembler_directive, ".word\t");
  816. (*info->fprintf_styled_func)
  817. (info->stream, dis_style_immediate, "0x%08llx",
  818. (unsigned long long) data);
  819. break;
  820. case 8:
  821. info->bytes_per_line = 8;
  822. (*info->fprintf_styled_func)
  823. (info->stream, dis_style_assembler_directive, ".dword\t");
  824. (*info->fprintf_styled_func)
  825. (info->stream, dis_style_immediate, "0x%016llx",
  826. (unsigned long long) data);
  827. break;
  828. default:
  829. abort ();
  830. }
  831. return info->bytes_per_chunk;
  832. }
  833. int
  834. print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
  835. {
  836. bfd_byte packet[8];
  837. insn_t insn = 0;
  838. bfd_vma dump_size;
  839. int status;
  840. enum riscv_seg_mstate mstate;
  841. int (*riscv_disassembler) (bfd_vma, insn_t, struct disassemble_info *);
  842. if (info->disassembler_options != NULL)
  843. {
  844. parse_riscv_dis_options (info->disassembler_options);
  845. /* Avoid repeatedly parsing the options. */
  846. info->disassembler_options = NULL;
  847. }
  848. else if (riscv_gpr_names == NULL)
  849. set_default_riscv_dis_options ();
  850. mstate = riscv_search_mapping_symbol (memaddr, info);
  851. /* Save the last mapping state. */
  852. last_map_state = mstate;
  853. /* Set the size to dump. */
  854. if (mstate == MAP_DATA
  855. && (info->flags & DISASSEMBLE_DATA) == 0)
  856. {
  857. dump_size = riscv_data_length (memaddr, info);
  858. info->bytes_per_chunk = dump_size;
  859. riscv_disassembler = riscv_disassemble_data;
  860. }
  861. else
  862. {
  863. /* Get the first 2-bytes to check the lenghth of instruction. */
  864. status = (*info->read_memory_func) (memaddr, packet, 2, info);
  865. if (status != 0)
  866. {
  867. (*info->memory_error_func) (status, memaddr, info);
  868. return status;
  869. }
  870. insn = (insn_t) bfd_getl16 (packet);
  871. dump_size = riscv_insn_length (insn);
  872. riscv_disassembler = riscv_disassemble_insn;
  873. }
  874. /* Fetch the instruction to dump. */
  875. status = (*info->read_memory_func) (memaddr, packet, dump_size, info);
  876. if (status != 0)
  877. {
  878. (*info->memory_error_func) (status, memaddr, info);
  879. return status;
  880. }
  881. insn = (insn_t) bfd_get_bits (packet, dump_size * 8, false);
  882. return (*riscv_disassembler) (memaddr, insn, info);
  883. }
  884. disassembler_ftype
  885. riscv_get_disassembler (bfd *abfd)
  886. {
  887. const char *default_arch = "rv64gc";
  888. if (abfd)
  889. {
  890. const struct elf_backend_data *ebd = get_elf_backend_data (abfd);
  891. if (ebd)
  892. {
  893. const char *sec_name = ebd->obj_attrs_section;
  894. if (bfd_get_section_by_name (abfd, sec_name) != NULL)
  895. {
  896. obj_attribute *attr = elf_known_obj_attributes_proc (abfd);
  897. unsigned int Tag_a = Tag_RISCV_priv_spec;
  898. unsigned int Tag_b = Tag_RISCV_priv_spec_minor;
  899. unsigned int Tag_c = Tag_RISCV_priv_spec_revision;
  900. riscv_get_priv_spec_class_from_numbers (attr[Tag_a].i,
  901. attr[Tag_b].i,
  902. attr[Tag_c].i,
  903. &default_priv_spec);
  904. default_arch = attr[Tag_RISCV_arch].s;
  905. }
  906. }
  907. }
  908. riscv_release_subset_list (&riscv_subsets);
  909. riscv_parse_subset (&riscv_rps_dis, default_arch);
  910. return print_insn_riscv;
  911. }
  912. /* Prevent use of the fake labels that are generated as part of the DWARF
  913. and for relaxable relocations in the assembler. */
  914. bool
  915. riscv_symbol_is_valid (asymbol * sym,
  916. struct disassemble_info * info ATTRIBUTE_UNUSED)
  917. {
  918. const char * name;
  919. if (sym == NULL)
  920. return false;
  921. name = bfd_asymbol_name (sym);
  922. return (strcmp (name, RISCV_FAKE_LABEL_NAME) != 0
  923. && !riscv_elf_is_mapping_symbols (name));
  924. }
  925. /* Indices into option argument vector for options accepting an argument.
  926. Use RISCV_OPTION_ARG_NONE for options accepting no argument. */
  927. typedef enum
  928. {
  929. RISCV_OPTION_ARG_NONE = -1,
  930. RISCV_OPTION_ARG_PRIV_SPEC,
  931. RISCV_OPTION_ARG_COUNT
  932. } riscv_option_arg_t;
  933. /* Valid RISCV disassembler options. */
  934. static struct
  935. {
  936. const char *name;
  937. const char *description;
  938. riscv_option_arg_t arg;
  939. } riscv_options[] =
  940. {
  941. { "numeric",
  942. N_("Print numeric register names, rather than ABI names."),
  943. RISCV_OPTION_ARG_NONE },
  944. { "no-aliases",
  945. N_("Disassemble only into canonical instructions."),
  946. RISCV_OPTION_ARG_NONE },
  947. { "priv-spec=",
  948. N_("Print the CSR according to the chosen privilege spec."),
  949. RISCV_OPTION_ARG_PRIV_SPEC }
  950. };
  951. /* Build the structure representing valid RISCV disassembler options.
  952. This is done dynamically for maintenance ease purpose; a static
  953. initializer would be unreadable. */
  954. const disasm_options_and_args_t *
  955. disassembler_options_riscv (void)
  956. {
  957. static disasm_options_and_args_t *opts_and_args;
  958. if (opts_and_args == NULL)
  959. {
  960. size_t num_options = ARRAY_SIZE (riscv_options);
  961. size_t num_args = RISCV_OPTION_ARG_COUNT;
  962. disasm_option_arg_t *args;
  963. disasm_options_t *opts;
  964. size_t i, priv_spec_count;
  965. args = XNEWVEC (disasm_option_arg_t, num_args + 1);
  966. args[RISCV_OPTION_ARG_PRIV_SPEC].name = "SPEC";
  967. priv_spec_count = PRIV_SPEC_CLASS_DRAFT - PRIV_SPEC_CLASS_NONE - 1;
  968. args[RISCV_OPTION_ARG_PRIV_SPEC].values
  969. = XNEWVEC (const char *, priv_spec_count + 1);
  970. for (i = 0; i < priv_spec_count; i++)
  971. args[RISCV_OPTION_ARG_PRIV_SPEC].values[i]
  972. = riscv_priv_specs[i].name;
  973. /* The array we return must be NULL terminated. */
  974. args[RISCV_OPTION_ARG_PRIV_SPEC].values[i] = NULL;
  975. /* The array we return must be NULL terminated. */
  976. args[num_args].name = NULL;
  977. args[num_args].values = NULL;
  978. opts_and_args = XNEW (disasm_options_and_args_t);
  979. opts_and_args->args = args;
  980. opts = &opts_and_args->options;
  981. opts->name = XNEWVEC (const char *, num_options + 1);
  982. opts->description = XNEWVEC (const char *, num_options + 1);
  983. opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
  984. for (i = 0; i < num_options; i++)
  985. {
  986. opts->name[i] = riscv_options[i].name;
  987. opts->description[i] = _(riscv_options[i].description);
  988. if (riscv_options[i].arg != RISCV_OPTION_ARG_NONE)
  989. opts->arg[i] = &args[riscv_options[i].arg];
  990. else
  991. opts->arg[i] = NULL;
  992. }
  993. /* The array we return must be NULL terminated. */
  994. opts->name[i] = NULL;
  995. opts->description[i] = NULL;
  996. opts->arg[i] = NULL;
  997. }
  998. return opts_and_args;
  999. }
  1000. void
  1001. print_riscv_disassembler_options (FILE *stream)
  1002. {
  1003. const disasm_options_and_args_t *opts_and_args;
  1004. const disasm_option_arg_t *args;
  1005. const disasm_options_t *opts;
  1006. size_t max_len = 0;
  1007. size_t i;
  1008. size_t j;
  1009. opts_and_args = disassembler_options_riscv ();
  1010. opts = &opts_and_args->options;
  1011. args = opts_and_args->args;
  1012. fprintf (stream, _("\n\
  1013. The following RISC-V specific disassembler options are supported for use\n\
  1014. with the -M switch (multiple options should be separated by commas):\n"));
  1015. fprintf (stream, "\n");
  1016. /* Compute the length of the longest option name. */
  1017. for (i = 0; opts->name[i] != NULL; i++)
  1018. {
  1019. size_t len = strlen (opts->name[i]);
  1020. if (opts->arg[i] != NULL)
  1021. len += strlen (opts->arg[i]->name);
  1022. if (max_len < len)
  1023. max_len = len;
  1024. }
  1025. for (i = 0, max_len++; opts->name[i] != NULL; i++)
  1026. {
  1027. fprintf (stream, " %s", opts->name[i]);
  1028. if (opts->arg[i] != NULL)
  1029. fprintf (stream, "%s", opts->arg[i]->name);
  1030. if (opts->description[i] != NULL)
  1031. {
  1032. size_t len = strlen (opts->name[i]);
  1033. if (opts->arg != NULL && opts->arg[i] != NULL)
  1034. len += strlen (opts->arg[i]->name);
  1035. fprintf (stream, "%*c %s", (int) (max_len - len), ' ',
  1036. opts->description[i]);
  1037. }
  1038. fprintf (stream, "\n");
  1039. }
  1040. for (i = 0; args[i].name != NULL; i++)
  1041. {
  1042. fprintf (stream, _("\n\
  1043. For the options above, the following values are supported for \"%s\":\n "),
  1044. args[i].name);
  1045. for (j = 0; args[i].values[j] != NULL; j++)
  1046. fprintf (stream, " %s", args[i].values[j]);
  1047. fprintf (stream, _("\n"));
  1048. }
  1049. fprintf (stream, _("\n"));
  1050. }