OpenOCD
a64_disassembler.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2019 by Mete Balci *
5  * metebalci@gmail.com *
6  ***************************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 #include <helper/log.h>
13 #include "target.h"
14 #include "a64_disassembler.h"
15 
16 #if HAVE_CAPSTONE
17 
18 #include <capstone.h>
19 
20 static void print_opcode(struct command_invocation *cmd, const cs_insn *insn)
21 {
22  uint32_t opcode = 0;
23 
24  memcpy(&opcode, insn->bytes, insn->size);
25 
26  if (insn->size == 4) {
27 
28  uint16_t opcode_high = opcode >> 16;
29 
30  opcode = opcode & 0xffff;
31 
33  "0x%08" PRIx64" %04x %04x\t%s\t%s",
34  insn->address,
35  opcode,
36  opcode_high,
37  insn->mnemonic,
38  insn->op_str);
39 
40  } else {
41 
43  cmd,
44  "0x%08" PRIx64" %04x\t%s\t%s",
45  insn->address,
46  opcode,
47  insn->mnemonic,
48  insn->op_str);
49 
50  }
51 }
52 
53 int a64_disassemble(struct command_invocation *cmd, struct target *target, target_addr_t address, size_t count)
54 {
55  int ret;
56  int csret;
57  csh handle;
58 
59  csret = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle);
60 
61  if (csret != CS_ERR_OK) {
62 
63  LOG_ERROR("cs_open() failed: %s", cs_strerror(csret));
64  return ERROR_FAIL;
65 
66  }
67 
68  csret = cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
69 
70  if (csret != CS_ERR_OK) {
71 
72  LOG_ERROR("cs_option() failed: %s", cs_strerror(csret));
73  cs_close(&handle);
74  return ERROR_FAIL;
75 
76  }
77 
78  cs_insn *insn = cs_malloc(handle);
79 
80  if (csret != CS_ERR_OK) {
81 
82  LOG_ERROR("cs_malloc() failed: %s", cs_strerror(csret));
83  cs_close(&handle);
84  return ERROR_FAIL;
85 
86  }
87 
88  while (count > 0) {
89 
90  uint8_t buffer[4];
91 
92  ret = target_read_buffer(target, address, sizeof(buffer), buffer);
93 
94  if (ret != ERROR_OK) {
95  cs_free(insn, 1);
96  cs_close(&handle);
97  return ret;
98  }
99 
100  size_t size = sizeof(buffer);
101  const uint8_t *tmp = buffer;
102 
103  ret = cs_disasm_iter(handle, &tmp, &size, &address, insn);
104 
105  if (!ret) {
106 
107  LOG_ERROR("cs_disasm_iter() failed: %s", cs_strerror(cs_errno(handle)));
108  cs_free(insn, 1);
109  cs_close(&handle);
110  return ERROR_FAIL;
111 
112  }
113 
114  print_opcode(cmd, insn);
115  count--;
116 
117  }
118 
119  cs_free(insn, 1);
120  cs_close(&handle);
121 
122  return ERROR_OK;
123 }
124 
125 #else
126 
127 int a64_disassemble(struct command_invocation *cmd, struct target *target, target_addr_t address, size_t count)
128 {
129  command_print(cmd, "capstone disassembly framework required");
130 
131  return ERROR_FAIL;
132 }
133 
134 #endif
int a64_disassemble(struct command_invocation *cmd, struct target *target, target_addr_t address, size_t count)
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:473
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define ERROR_OK
Definition: log.h:155
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
Definition: target.h:120
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
Definition: target.c:2473
uint64_t target_addr_t
Definition: types.h:335
uint8_t cmd
Definition: vdebug.c:1
uint8_t count[4]
Definition: vdebug.c:22