Files
kaizen/cstool/cstool_aarch64.c
Simone 3621a6c080 Squashed 'external/capstone/' changes from 5430745e..b102f1b8
b102f1b8 Update Actions (#2593)
86293136 Fix LoongArch aliases and CS_OPT_SYNTAX_NO_DOLLAR support (#2594)
27da950c Clarify between machine used vs. Capstone module affected. (#2586)
186f7aa0 Fix linking issue on Windows. (#2587)
e160cbc5 Fix complex atomic instructions handling (#2584)
9907b22d Update v6 to have Debian Packages (#2579)
efbbc3bb cstest: use DOWNLOAD_EXTRACT_TIMESTAMP conditionally (#2581)
be6be784 x86: update read/write registers for transfer instructions (#2578)
812e654c Update BPF arch (#2568)
2c4b05f6 Clean up the cstest documentation and build instructions. (#2580)
4dc14ba1 Fix 2572 (#2574)
b25aa841 PPC regressions (#2575)
0a29bf80 Small arm64 compat header fixes (#2563)
b42e0903 Make thumb, v8 and m-class positional cstool arguments. (#2557)
89aee400 Add arm64 and sysz compatibility layer to Python bindings (#2559)
a4281337 Python bindings: Enable more archs + bump cibuildwheel action to the v2.22.0 (#2558)
ef74d449 Arm regressions (#2556)
93a104c0 PPC LLVM 18 (#2540)
e46838ed Merge branch 'v6' into next
cf3600e7 Update Changelog Version to 6.0.0-Alpha2 (#2553)
b295cf57 Prepare for update (#2552)
fc59da4d fix xtensa DecodeMR23RegisterClass and add tests for MAC16 instru… (#2551)
7d01d7e7 Auto-Sync reproducability + ARM update (#2532)
6ad2608d Python package building rework (#2538)
e3bc578d Move debian package generation to a dispatch only workflow (#2543)
abbf32b4 fix coverity (#2546)
1ecfb5b0 xtensa: update to espressif/llvm-project (#2533)
379e2a41 Rename build arguments: (#2534)
d7be5f9f Change CI to create Debian Package to Release (#2521)
f6f96796 tricore: fixes #2474 (#2523)
09f35961 This time actually fix big endian issue. (#2530)
306d5716 Fix endianess issue during assignment. (#2528)
2cfca35e Add CC and VAS compatibility macros (#2525)
32519c01 Fix stringop-truncation warning some compilers raise. (#2522)
5026c2c4 Merge pull request #2507 from thestr4ng3r/no-varargs-aarch64
cecb5ede Fix #2509. (#2510)
f97e2705 xtensa: Fix Branch Target (#2516)
1d13a12f AArch64: Replace vararg add_cs_detail by multiple concrete functions
8b618528 Update libcyaml dependency in cstest to 1.4.2 (#2508)
ea081286 Tricore EA calculation (#2504)
7db9a080 Fix cstest build with Ninja (#2506)
76242699 Only trigger on released action. (#2497)
981d648b Add hard asserts to all SStream functions and memset MCInst. (#2501)
d667a627 Update labeler with Xtensa and v6 files. (#2500)
52b54ee3 Fixing UB santizer, `LITBASE` and assert errors. (#2499)
97db712c Remove irrelevant changes. (#2496)
5bd05e34 Remove irrelevant changes. (#2495)
616488c7 Update changelog for V6.0.0-Alpha1 (#2493) (#2494)
c5955b92 Update changelog for V6.0.0-Alpha1 (#2493)
a424e709 Be ready for V6-Alpha1 (#2492)
235ba8e0 SystemZ fixes (#2488)
5dffa75b Fix LDR not assigning immediate as memory offset. (#2487)
21f7bc85 Xtensa Support (#2380)
29d87734 Several small fixups (#2489)
a34901e9 Update sponsors and remove empty file. (#2485)
3120932d Fix Coverity CID 509730: overflow before widen (#2486)
1014864d Rename CS_OPT_NO_BRANCH_OFFSET and corresponding flag to better name. (#2482)
0c90fe13 Replace `assert` with `CS_ASSERT` in modules (#2478)
823bfd53 AArch64 issues (#2473)

git-subtree-dir: external/capstone
git-subtree-split: b102f1b89e0455c072a751d287ab64378c14205f
2025-01-07 15:08:55 +00:00

247 lines
8.4 KiB
C

/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
#include "capstone/aarch64.h"
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_aarch64(csh handle, cs_insn *ins)
{
cs_aarch64 *aarch64;
int i;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
uint8_t access;
// detail can be NULL if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
aarch64 = &(ins->detail->aarch64);
if (aarch64->op_count)
printf("\top_count: %u\n", aarch64->op_count);
for (i = 0; i < aarch64->op_count; i++) {
cs_aarch64_op *op = &(aarch64->operands[i]);
switch(op->type) {
default:
printf("\t\tOperand type %" PRId32 " not handled\n", op->type);
break;
case AARCH64_OP_REG:
printf("\t\toperands[%u].type: REG = %s%s\n", i, cs_reg_name(handle, op->reg), op->is_vreg ? " (vreg)" : "");
if (op->is_list_member) {
printf("\t\toperands[%u].is_list_member: true\n", i);
}
break;
case AARCH64_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
break;
case AARCH64_OP_FP:
#if defined(_KERNEL_MODE)
// Issue #681: Windows kernel does not support formatting float point
printf("\t\toperands[%u].type: FP = <float_point_unsupported>\n", i);
#else
printf("\t\toperands[%u].type: FP = %f\n", i, op->fp);
#endif
break;
case AARCH64_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != AARCH64_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(handle, op->mem.base));
if (op->mem.index != AARCH64_REG_INVALID)
printf("\t\t\toperands[%u].mem.index: REG = %s\n", i, cs_reg_name(handle, op->mem.index));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
if (ins->detail->aarch64.post_index)
printf("\t\t\tpost-indexed: true\n");
break;
case AARCH64_OP_SME:
printf("\t\toperands[%u].type: SME_MATRIX\n", i);
printf("\t\toperands[%u].sme.type: %d\n", i, op->sme.type);
if (op->sme.tile != AARCH64_REG_INVALID)
printf("\t\toperands[%u].sme.tile: %s\n", i, cs_reg_name(handle, op->sme.tile));
if (op->sme.slice_reg != AARCH64_REG_INVALID)
printf("\t\toperands[%u].sme.slice_reg: %s\n", i, cs_reg_name(handle, op->sme.slice_reg));
if (op->sme.slice_offset.imm != AARCH64_SLICE_IMM_INVALID || op->sme.slice_offset.imm_range.first != AARCH64_SLICE_IMM_RANGE_INVALID) {
printf("\t\toperands[%u].sme.slice_offset: ", i);
if (op->sme.has_range_offset)
printf("%hhd:%hhd\n", op->sme.slice_offset.imm_range.first, op->sme.slice_offset.imm_range.offset);
else
printf("%d\n", op->sme.slice_offset.imm);
}
if (op->sme.slice_reg != AARCH64_REG_INVALID || op->sme.slice_offset.imm != AARCH64_SLICE_IMM_INVALID)
printf("\t\toperands[%u].sme.is_vertical: %s\n", i, (op->sme.is_vertical ? "true" : "false"));
break;
case AARCH64_OP_PRED:
printf("\t\toperands[%u].type: PREDICATE\n", i);
if (op->pred.reg != AARCH64_REG_INVALID)
printf("\t\toperands[%u].pred.reg: %s\n", i, cs_reg_name(handle, op->pred.reg));
if (op->pred.vec_select != AARCH64_REG_INVALID)
printf("\t\toperands[%u].pred.vec_select: %s\n", i, cs_reg_name(handle, op->pred.vec_select));
if (op->pred.imm_index != -1)
printf("\t\toperands[%u].pred.imm_index: %d\n", i, op->pred.imm_index);
break;
case AARCH64_OP_CIMM:
printf("\t\toperands[%u].type: C-IMM = %u\n", i, (int)op->imm);
break;
case AARCH64_OP_SYSREG:
printf("\t\toperands[%u].type: SYS REG:\n", i);
switch (op->sysop.sub_type) {
default:
printf("Sub type %d not handled.\n", op->sysop.sub_type);
break;
case AARCH64_OP_REG_MRS:
printf("\t\toperands[%u].subtype: REG_MRS = 0x%x\n", i, op->sysop.reg.sysreg);
break;
case AARCH64_OP_REG_MSR:
printf("\t\toperands[%u].subtype: REG_MSR = 0x%x\n", i, op->sysop.reg.sysreg);
break;
case AARCH64_OP_TLBI:
printf("\t\toperands[%u].subtype TLBI = 0x%x\n", i, op->sysop.reg.tlbi);
break;
case AARCH64_OP_IC:
printf("\t\toperands[%u].subtype IC = 0x%x\n", i, op->sysop.reg.ic);
break;
}
break;
case AARCH64_OP_SYSALIAS:
printf("\t\toperands[%u].type: SYS ALIAS:\n", i);
switch (op->sysop.sub_type) {
default:
printf("Sub type %d not handled.\n", op->sysop.sub_type);
break;
case AARCH64_OP_SVCR:
if(op->sysop.alias.svcr == AARCH64_SVCR_SVCRSM)
printf("\t\t\toperands[%u].svcr: BIT = SM\n", i);
else if(op->sysop.alias.svcr == AARCH64_SVCR_SVCRZA)
printf("\t\t\toperands[%u].svcr: BIT = ZA\n", i);
else if(op->sysop.alias.svcr == AARCH64_SVCR_SVCRSMZA)
printf("\t\t\toperands[%u].svcr: BIT = SM & ZA\n", i);
break;
case AARCH64_OP_AT:
printf("\t\toperands[%u].subtype AT = 0x%x\n", i, op->sysop.alias.at);
break;
case AARCH64_OP_DB:
printf("\t\toperands[%u].subtype DB = 0x%x\n", i, op->sysop.alias.db);
break;
case AARCH64_OP_DC:
printf("\t\toperands[%u].subtype DC = 0x%x\n", i, op->sysop.alias.dc);
break;
case AARCH64_OP_ISB:
printf("\t\toperands[%u].subtype ISB = 0x%x\n", i, op->sysop.alias.isb);
break;
case AARCH64_OP_TSB:
printf("\t\toperands[%u].subtype TSB = 0x%x\n", i, op->sysop.alias.tsb);
break;
case AARCH64_OP_PRFM:
printf("\t\toperands[%u].subtype PRFM = 0x%x\n", i, op->sysop.alias.prfm);
break;
case AARCH64_OP_SVEPRFM:
printf("\t\toperands[%u].subtype SVEPRFM = 0x%x\n", i, op->sysop.alias.sveprfm);
break;
case AARCH64_OP_RPRFM:
printf("\t\toperands[%u].subtype RPRFM = 0x%x\n", i, op->sysop.alias.rprfm);
break;
case AARCH64_OP_PSTATEIMM0_15:
printf("\t\toperands[%u].subtype PSTATEIMM0_15 = 0x%x\n", i, op->sysop.alias.pstateimm0_15);
break;
case AARCH64_OP_PSTATEIMM0_1:
printf("\t\toperands[%u].subtype PSTATEIMM0_1 = 0x%x\n", i, op->sysop.alias.pstateimm0_1);
break;
case AARCH64_OP_PSB:
printf("\t\toperands[%u].subtype PSB = 0x%x\n", i, op->sysop.alias.psb);
break;
case AARCH64_OP_BTI:
printf("\t\toperands[%u].subtype BTI = 0x%x\n", i, op->sysop.alias.bti);
break;
case AARCH64_OP_SVEPREDPAT:
printf("\t\toperands[%u].subtype SVEPREDPAT = 0x%x\n", i, op->sysop.alias.svepredpat);
break;
case AARCH64_OP_SVEVECLENSPECIFIER:
printf("\t\toperands[%u].subtype SVEVECLENSPECIFIER = 0x%x\n", i, op->sysop.alias.sveveclenspecifier);
break;
}
break;
case AARCH64_OP_SYSIMM:
printf("\t\toperands[%u].type: SYS IMM:\n", i);
switch(op->sysop.sub_type) {
default:
printf("Sub type %d not handled.\n", op->sysop.sub_type);
break;
case AARCH64_OP_EXACTFPIMM:
printf("\t\toperands[%u].subtype EXACTFPIMM = %d\n", i, op->sysop.imm.exactfpimm);
printf("\t\toperands[%u].fp = %.1f\n", i, op->fp);
break;
case AARCH64_OP_DBNXS:
printf("\t\toperands[%u].subtype DBNXS = %d\n", i, op->sysop.imm.dbnxs);
break;
}
break;
}
access = op->access;
switch(access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
if (op->shift.type != AARCH64_SFT_INVALID &&
op->shift.value)
printf("\t\t\tShift: type = %u, value = %u\n",
op->shift.type, op->shift.value);
if (op->ext != AARCH64_EXT_INVALID)
printf("\t\t\tExt: %u\n", op->ext);
if (op->vas != AARCH64LAYOUT_INVALID)
printf("\t\t\tVector Arrangement Specifier: 0x%x\n", op->vas);
if (op->vector_index != -1)
printf("\t\t\tVector Index: %u\n", op->vector_index);
}
if (aarch64->update_flags)
printf("\tUpdate-flags: True\n");
if (ins->detail->writeback)
printf("\tWrite-back: True\n");
if (aarch64->cc != AArch64CC_Invalid)
printf("\tCode-condition: %u\n", aarch64->cc);
// Print out all registers accessed by this instruction (either implicit or explicit)
if (!cs_regs_access(handle, ins,
regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for(i = 0; i < regs_read_count; i++) {
printf(" %s", cs_reg_name(handle, regs_read[i]));
}
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for(i = 0; i < regs_write_count; i++) {
printf(" %s", cs_reg_name(handle, regs_write[i]));
}
printf("\n");
}
}
}