forked from auracaster/openocd
target/aarch64: a64 disassembler
Add A64 (AArch64) Disassembler using Capstone framework. Change-Id: Ia92b57001843b11a818af940a468b131e42a03fd Signed-off-by: Mete Balci <metebalci@gmail.com> [Antonio Borneo: Rebased on current HEAD] Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/5004 Tested-by: jenkins
This commit is contained in:
committed by
Antonio Borneo
parent
a31e579e87
commit
d7d70c2719
145
src/target/a64_disassembler.c
Normal file
145
src/target/a64_disassembler.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2019 by Mete Balci *
|
||||
* metebalci@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <helper/log.h>
|
||||
#include "target.h"
|
||||
#include "a64_disassembler.h"
|
||||
|
||||
#if HAVE_CAPSTONE
|
||||
|
||||
#include <capstone/capstone.h>
|
||||
|
||||
static void print_opcode(struct command_invocation *cmd, const cs_insn *insn)
|
||||
{
|
||||
uint32_t opcode = 0;
|
||||
|
||||
memcpy(&opcode, insn->bytes, insn->size);
|
||||
|
||||
if (insn->size == 4) {
|
||||
|
||||
uint16_t opcode_high = opcode >> 16;
|
||||
|
||||
opcode = opcode & 0xffff;
|
||||
|
||||
command_print(cmd,
|
||||
"0x%08" PRIx64" %04x %04x\t%s\t%s",
|
||||
insn->address,
|
||||
opcode,
|
||||
opcode_high,
|
||||
insn->mnemonic,
|
||||
insn->op_str);
|
||||
|
||||
} else {
|
||||
|
||||
command_print(
|
||||
cmd,
|
||||
"0x%08" PRIx64" %04x\t%s\t%s",
|
||||
insn->address,
|
||||
opcode,
|
||||
insn->mnemonic,
|
||||
insn->op_str);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int a64_disassemble(struct command_invocation *cmd, struct target *target, target_addr_t address, size_t count)
|
||||
{
|
||||
int ret;
|
||||
int csret;
|
||||
csh handle;
|
||||
|
||||
csret = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle);
|
||||
|
||||
if (csret != CS_ERR_OK) {
|
||||
|
||||
LOG_ERROR("cs_open() failed: %s", cs_strerror(csret));
|
||||
return ERROR_FAIL;
|
||||
|
||||
}
|
||||
|
||||
csret = cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
|
||||
|
||||
if (csret != CS_ERR_OK) {
|
||||
|
||||
LOG_ERROR("cs_option() failed: %s", cs_strerror(csret));
|
||||
cs_close(&handle);
|
||||
return ERROR_FAIL;
|
||||
|
||||
}
|
||||
|
||||
cs_insn *insn = cs_malloc(handle);
|
||||
|
||||
if (csret != CS_ERR_OK) {
|
||||
|
||||
LOG_ERROR("cs_malloc() failed: %s", cs_strerror(csret));
|
||||
cs_close(&handle);
|
||||
return ERROR_FAIL;
|
||||
|
||||
}
|
||||
|
||||
while (count > 0) {
|
||||
|
||||
uint8_t buffer[4];
|
||||
|
||||
ret = target_read_buffer(target, address, sizeof(buffer), buffer);
|
||||
|
||||
if (ret != ERROR_OK) {
|
||||
cs_free(insn, 1);
|
||||
cs_close(&handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t size = sizeof(buffer);
|
||||
const uint8_t *tmp = buffer;
|
||||
|
||||
ret = cs_disasm_iter(handle, &tmp, &size, &address, insn);
|
||||
|
||||
if (!ret) {
|
||||
|
||||
LOG_ERROR("cs_disasm_iter() failed: %s", cs_strerror(cs_errno(handle)));
|
||||
cs_free(insn, 1);
|
||||
cs_close(&handle);
|
||||
return ERROR_FAIL;
|
||||
|
||||
}
|
||||
|
||||
print_opcode(cmd, insn);
|
||||
count--;
|
||||
|
||||
}
|
||||
|
||||
cs_free(insn, 1);
|
||||
cs_close(&handle);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int a64_disassemble(struct command_invocation *cmd, struct target *target, target_addr_t address, size_t count)
|
||||
{
|
||||
command_print(cmd, "capstone disassembly framework required");
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user