disasm-selftests.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* Self tests for disassembler for GDB, the GNU debugger.
  2. Copyright (C) 2017-2022 Free Software Foundation, Inc.
  3. This file is part of GDB.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. #include "defs.h"
  15. #include "disasm.h"
  16. #include "gdbsupport/selftest.h"
  17. #include "selftest-arch.h"
  18. #include "gdbarch.h"
  19. namespace selftests {
  20. /* Test disassembly of one instruction. */
  21. static void
  22. print_one_insn_test (struct gdbarch *gdbarch)
  23. {
  24. size_t len = 0;
  25. const gdb_byte *insn = NULL;
  26. switch (gdbarch_bfd_arch_info (gdbarch)->arch)
  27. {
  28. case bfd_arch_bfin:
  29. /* M3.L = 0xe117 */
  30. static const gdb_byte bfin_insn[] = {0x17, 0xe1, 0xff, 0xff};
  31. insn = bfin_insn;
  32. len = sizeof (bfin_insn);
  33. break;
  34. case bfd_arch_arm:
  35. /* mov r0, #0 */
  36. static const gdb_byte arm_insn[] = {0x0, 0x0, 0xa0, 0xe3};
  37. insn = arm_insn;
  38. len = sizeof (arm_insn);
  39. break;
  40. case bfd_arch_ia64:
  41. case bfd_arch_mep:
  42. case bfd_arch_mips:
  43. case bfd_arch_tic6x:
  44. case bfd_arch_xtensa:
  45. return;
  46. case bfd_arch_s390:
  47. /* nopr %r7 */
  48. static const gdb_byte s390_insn[] = {0x07, 0x07};
  49. insn = s390_insn;
  50. len = sizeof (s390_insn);
  51. break;
  52. case bfd_arch_xstormy16:
  53. /* nop */
  54. static const gdb_byte xstormy16_insn[] = {0x0, 0x0};
  55. insn = xstormy16_insn;
  56. len = sizeof (xstormy16_insn);
  57. break;
  58. case bfd_arch_nios2:
  59. case bfd_arch_score:
  60. case bfd_arch_riscv:
  61. /* nios2, riscv, and score need to know the current instruction
  62. to select breakpoint instruction. Give the breakpoint
  63. instruction kind explicitly. */
  64. {
  65. int bplen;
  66. insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 4, &bplen);
  67. len = bplen;
  68. }
  69. break;
  70. case bfd_arch_arc:
  71. /* PR 21003 */
  72. if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601)
  73. return;
  74. goto generic_case;
  75. case bfd_arch_i386:
  76. {
  77. const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
  78. /* The disassembly tests will fail on x86-linux because
  79. opcodes rejects an attempt to disassemble for an arch with
  80. a 64-bit address size when bfd_vma is 32-bit. */
  81. if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT)
  82. return;
  83. }
  84. /* fall through */
  85. default:
  86. generic_case:
  87. {
  88. /* Test disassemble breakpoint instruction. */
  89. CORE_ADDR pc = 0;
  90. int kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc);
  91. int bplen;
  92. insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen);
  93. len = bplen;
  94. break;
  95. }
  96. }
  97. SELF_CHECK (len > 0);
  98. /* Test gdb_disassembler for a given gdbarch by reading data from a
  99. pre-allocated buffer. If you want to see the disassembled
  100. instruction printed to gdb_stdout, use maint selftest -verbose. */
  101. class gdb_disassembler_test : public gdb_disassembler
  102. {
  103. public:
  104. explicit gdb_disassembler_test (struct gdbarch *gdbarch,
  105. const gdb_byte *insn,
  106. size_t len)
  107. : gdb_disassembler (gdbarch,
  108. (run_verbose () ? gdb_stdout : &null_stream),
  109. gdb_disassembler_test::read_memory),
  110. m_insn (insn), m_len (len)
  111. {
  112. }
  113. int
  114. print_insn (CORE_ADDR memaddr)
  115. {
  116. if (run_verbose ())
  117. {
  118. gdb_printf (stream (), "%s ",
  119. gdbarch_bfd_arch_info (arch ())->arch_name);
  120. }
  121. int len = gdb_disassembler::print_insn (memaddr);
  122. if (run_verbose ())
  123. gdb_printf (stream (), "\n");
  124. return len;
  125. }
  126. private:
  127. /* A buffer contain one instruction. */
  128. const gdb_byte *m_insn;
  129. /* Length of the buffer. */
  130. size_t m_len;
  131. static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
  132. unsigned int len, struct disassemble_info *info)
  133. {
  134. gdb_disassembler_test *self
  135. = static_cast<gdb_disassembler_test *>(info->application_data);
  136. /* The disassembler in opcodes may read more data than one
  137. instruction. Supply infinite consecutive copies
  138. of the same instruction. */
  139. for (size_t i = 0; i < len; i++)
  140. myaddr[i] = self->m_insn[(memaddr + i) % self->m_len];
  141. return 0;
  142. }
  143. };
  144. gdb_disassembler_test di (gdbarch, insn, len);
  145. SELF_CHECK (di.print_insn (0) == len);
  146. }
  147. /* Test disassembly on memory error. */
  148. static void
  149. memory_error_test (struct gdbarch *gdbarch)
  150. {
  151. class gdb_disassembler_test : public gdb_disassembler
  152. {
  153. public:
  154. gdb_disassembler_test (struct gdbarch *gdbarch)
  155. : gdb_disassembler (gdbarch, &null_stream,
  156. gdb_disassembler_test::read_memory)
  157. {
  158. }
  159. static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
  160. unsigned int len,
  161. struct disassemble_info *info)
  162. {
  163. /* Always return an error. */
  164. return -1;
  165. }
  166. };
  167. if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_i386)
  168. {
  169. const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
  170. /* This test will fail on x86-linux because opcodes rejects an
  171. attempt to disassemble for an arch with a 64-bit address size
  172. when bfd_vma is 32-bit. */
  173. if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT)
  174. return;
  175. }
  176. gdb_disassembler_test di (gdbarch);
  177. bool saw_memory_error = false;
  178. try
  179. {
  180. di.print_insn (0);
  181. }
  182. catch (const gdb_exception_error &ex)
  183. {
  184. if (ex.error == MEMORY_ERROR)
  185. saw_memory_error = true;
  186. }
  187. /* Expect MEMORY_ERROR. */
  188. SELF_CHECK (saw_memory_error);
  189. }
  190. } // namespace selftests
  191. void _initialize_disasm_selftests ();
  192. void
  193. _initialize_disasm_selftests ()
  194. {
  195. selftests::register_test_foreach_arch ("print_one_insn",
  196. selftests::print_one_insn_test);
  197. selftests::register_test_foreach_arch ("memory_error",
  198. selftests::memory_error_test);
  199. }