drivers/ftdi: prevent misleading error msg when more vid/pids configured
[openocd.git] / src / target / a64_disassembler.c
blobca3d3ea7a90eded8d044794f57e903b1985c29b8
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2019 by Mete Balci *
5 * metebalci@gmail.com *
6 ***************************************************************************/
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
12 #include <helper/log.h>
13 #include "target.h"
14 #include "a64_disassembler.h"
16 #if HAVE_CAPSTONE
18 #include <capstone.h>
20 static void print_opcode(struct command_invocation *cmd, const cs_insn *insn)
22 uint32_t opcode = 0;
24 memcpy(&opcode, insn->bytes, insn->size);
26 if (insn->size == 4) {
28 uint16_t opcode_high = opcode >> 16;
30 opcode = opcode & 0xffff;
32 command_print(cmd,
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);
40 } else {
42 command_print(
43 cmd,
44 "0x%08" PRIx64" %04x\t%s\t%s",
45 insn->address,
46 opcode,
47 insn->mnemonic,
48 insn->op_str);
53 int a64_disassemble(struct command_invocation *cmd, struct target *target, target_addr_t address, size_t count)
55 int ret;
56 int csret;
57 csh handle;
59 csret = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle);
61 if (csret != CS_ERR_OK) {
63 LOG_ERROR("cs_open() failed: %s", cs_strerror(csret));
64 return ERROR_FAIL;
68 csret = cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
70 if (csret != CS_ERR_OK) {
72 LOG_ERROR("cs_option() failed: %s", cs_strerror(csret));
73 cs_close(&handle);
74 return ERROR_FAIL;
78 cs_insn *insn = cs_malloc(handle);
80 if (csret != CS_ERR_OK) {
82 LOG_ERROR("cs_malloc() failed: %s", cs_strerror(csret));
83 cs_close(&handle);
84 return ERROR_FAIL;
88 while (count > 0) {
90 uint8_t buffer[4];
92 ret = target_read_buffer(target, address, sizeof(buffer), buffer);
94 if (ret != ERROR_OK) {
95 cs_free(insn, 1);
96 cs_close(&handle);
97 return ret;
100 size_t size = sizeof(buffer);
101 const uint8_t *tmp = buffer;
103 ret = cs_disasm_iter(handle, &tmp, &size, &address, insn);
105 if (!ret) {
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;
114 print_opcode(cmd, insn);
115 count--;
119 cs_free(insn, 1);
120 cs_close(&handle);
122 return ERROR_OK;
125 #else
127 int a64_disassemble(struct command_invocation *cmd, struct target *target, target_addr_t address, size_t count)
129 command_print(cmd, "capstone disassembly framework required");
131 return ERROR_FAIL;
134 #endif