bpf.opc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* EBPF opcode support. -*- c -*-
  2. Copyright (C) 2019 Free Software Foundation, Inc.
  3. Contributed by Oracle, Inc.
  4. This file is part of the GNU Binutils and of GDB.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. MA 02110-1301, USA. */
  17. /*
  18. Each section is delimited with start and end markers.
  19. <arch>-opc.h additions use: "-- opc.h"
  20. <arch>-opc.c additions use: "-- opc.c"
  21. <arch>-asm.c additions use: "-- asm.c"
  22. <arch>-dis.c additions use: "-- dis.c"
  23. <arch>-ibd.h additions use: "-- ibd.h". */
  24. /* -- opc.h */
  25. #undef CGEN_DIS_HASH_SIZE
  26. #define CGEN_DIS_HASH_SIZE 1
  27. #undef CGEN_DIS_HASH
  28. #define CGEN_DIS_HASH(buffer, value) 0
  29. /* Allows reason codes to be output when assembler errors occur. */
  30. #define CGEN_VERBOSE_ASSEMBLER_ERRORS
  31. #define CGEN_VALIDATE_INSN_SUPPORTED
  32. extern int bpf_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
  33. /* -- opc.c */
  34. /* -- asm.c */
  35. /* Parse a signed 64-bit immediate. */
  36. static const char *
  37. parse_imm64 (CGEN_CPU_DESC cd,
  38. const char **strp,
  39. int opindex,
  40. int64_t *valuep)
  41. {
  42. bfd_vma value;
  43. enum cgen_parse_operand_result result;
  44. const char *errmsg;
  45. errmsg = (* cd->parse_operand_fn)
  46. (cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
  47. &result, &value);
  48. if (!errmsg)
  49. *valuep = value;
  50. return errmsg;
  51. }
  52. /* Endianness size operands are integer immediates whose values can be
  53. 16, 32 or 64. */
  54. static const char *
  55. parse_endsize (CGEN_CPU_DESC cd,
  56. const char **strp,
  57. int opindex,
  58. unsigned long *valuep)
  59. {
  60. const char *errmsg;
  61. errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
  62. if (errmsg)
  63. return errmsg;
  64. switch (*valuep)
  65. {
  66. case 16:
  67. case 32:
  68. case 64:
  69. break;
  70. default:
  71. return _("expected 16, 32 or 64 in");
  72. }
  73. return NULL;
  74. }
  75. /* Special check to ensure that the right instruction variant is used
  76. for the given endianness induced by the ISA selected in the CPU.
  77. See bpf.cpu for a discussion on how eBPF is really two instruction
  78. sets. */
  79. int
  80. bpf_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
  81. {
  82. CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
  83. return cgen_bitset_intersect_p (&isas, cd->isas);
  84. }
  85. /* -- dis.c */
  86. /* We need to customize the disassembler a bit:
  87. - Use 8 bytes per line by default.
  88. */
  89. #define CGEN_PRINT_INSN bpf_print_insn
  90. static int
  91. bpf_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
  92. {
  93. bfd_byte buf[CGEN_MAX_INSN_SIZE];
  94. int buflen;
  95. int status;
  96. info->bytes_per_chunk = 1;
  97. info->bytes_per_line = 8;
  98. /* Attempt to read the base part of the insn. */
  99. buflen = cd->base_insn_bitsize / 8;
  100. status = (*info->read_memory_func) (pc, buf, buflen, info);
  101. /* Try again with the minimum part, if min < base. */
  102. if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
  103. {
  104. buflen = cd->min_insn_bitsize / 8;
  105. status = (*info->read_memory_func) (pc, buf, buflen, info);
  106. }
  107. if (status != 0)
  108. {
  109. (*info->memory_error_func) (status, pc, info);
  110. return -1;
  111. }
  112. return print_insn (cd, pc, info, buf, buflen);
  113. }
  114. /* Signed immediates should be printed in hexadecimal. */
  115. static void
  116. print_immediate (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  117. void *dis_info,
  118. int64_t value,
  119. unsigned int attrs ATTRIBUTE_UNUSED,
  120. bfd_vma pc ATTRIBUTE_UNUSED,
  121. int length ATTRIBUTE_UNUSED)
  122. {
  123. disassemble_info *info = (disassemble_info *) dis_info;
  124. if (value <= 9)
  125. (*info->fprintf_func) (info->stream, "%" PRId64, value);
  126. else
  127. (*info->fprintf_func) (info->stream, "%#" PRIx64, value);
  128. /* This is to avoid -Wunused-function for print_normal. */
  129. if (0)
  130. print_normal (cd, dis_info, value, attrs, pc, length);
  131. }
  132. /* Endianness bit sizes should be printed in decimal. */
  133. static void
  134. print_endsize (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  135. void *dis_info,
  136. unsigned long value,
  137. unsigned int attrs ATTRIBUTE_UNUSED,
  138. bfd_vma pc ATTRIBUTE_UNUSED,
  139. int length ATTRIBUTE_UNUSED)
  140. {
  141. disassemble_info *info = (disassemble_info *) dis_info;
  142. (*info->fprintf_func) (info->stream, "%lu", value);
  143. }
  144. /* -- */