Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HP PA-RISC: Migrate to Capstone and add basic analysis #4469

Draft
wants to merge 2 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions librz/arch/isa/hppa/hppa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2024 Anton Kochkov <[email protected]>
// SPDX-License-Identifier: LGPL-3.0-only

#include <rz_types.h>
#include <capstone.h>

#ifndef RZ_HPPA_H
#define RZ_HPPA_H

typedef struct {
csh h;
cs_mode mode;
cs_insn *insn;
ut32 count;
ut32 word;
RzPVector /*<RzAsmTokenPattern *>*/ *token_patterns;
} RzAsmHPPAContext;

#endif // RZ_HPPA_H
116 changes: 116 additions & 0 deletions librz/arch/isa/hppa/hppa.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// SPDX-FileCopyrightText: 2023 billow <[email protected]>
// SPDX-FileCopyrightText: 2024 Anton Kochkov <[email protected]>
// SPDX-License-Identifier: LGPL-3.0-only

#include <capstone/capstone.h>
#include <capstone/hppa.h>
#include "hppa.h"

static inline cs_mode hppa_cpu_to_cs_mode(const char *cpu_type) {
if (RZ_STR_ISNOTEMPTY(cpu_type)) {
if (!strcmp(cpu_type, "hppa1.1")) {
return CS_MODE_HPPA_11;
}
if (!strcmp(cpu_type, "hppa2.0")) {
return CS_MODE_HPPA_20;
}
if (!strcmp(cpu_type, "hppa2.0w")) {
return CS_MODE_HPPA_20W;
}
}
return CS_MODE_HPPA_11;
}

static inline bool hppa_setup_cs_handle(RzAsmHPPAContext *ctx, const char *cpu, const char *features, bool big_endian) {
const cs_mode mode = hppa_cpu_to_cs_mode(cpu) | (big_endian ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN);
if (mode != ctx->mode) {
cs_close(&ctx->h);
ctx->h = 0;
ctx->mode = mode;
}

if (ctx->h != 0) {
return true;
}
cs_err err = cs_open(CS_ARCH_HPPA, mode, &ctx->h);
if (err) {
RZ_LOG_ERROR("Failed on cs_open() with error returned: %u\n", err);
return false;
}
err = cs_option(ctx->h, CS_OPT_DETAIL,
RZ_STR_ISNOTEMPTY(features) || features == NULL ? CS_OPT_ON : CS_OPT_OFF);
if (err) {
RZ_LOG_ERROR("Failed on cs_open() with error returned: %u\n", err);
return false;
}
return true;
}

static inline ut8 hppa_op_count(cs_insn *insn) {
return insn->detail->hppa.op_count;
}

static inline cs_hppa_op *hppa_op_get(cs_insn *insn, int idx) {
if (idx >= hppa_op_count(insn)) {
RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\"\n",
idx, hppa_op_count(insn), insn->mnemonic, insn->op_str);
rz_warn_if_reached();
return NULL;
}
return &insn->detail->hppa.operands[idx];
}

static inline const char *hppa_op_as_reg(RzAsmHPPAContext *ctx, int idx) {
const cs_hppa_op *op = hppa_op_get(ctx->insn, idx);
if (op->type != HPPA_OP_REG) {
RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [reg]\n",
idx, hppa_op_count(ctx->insn), ctx->insn->mnemonic, ctx->insn->op_str);
rz_warn_if_reached();
return NULL;
}
return cs_reg_name(ctx->h, op->reg);
}

static inline const char *hppa_op_as_mem(RzAsmHPPAContext *ctx, int idx) {
const cs_hppa_op *op = hppa_op_get(ctx->insn, idx);
if (op->type != HPPA_OP_MEM) {
RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [reg]\n",
idx, hppa_op_count(ctx->insn), ctx->insn->mnemonic, ctx->insn->op_str);
rz_warn_if_reached();
return NULL;
}
return cs_reg_name(ctx->h, op->reg);
}

static inline st64 hppa_op_as_imm(RzAsmHPPAContext *ctx, int idx) {
const cs_hppa_op *op = hppa_op_get(ctx->insn, idx);
if (op->type != HPPA_OP_IMM) {
RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [imm]\n",
idx, hppa_op_count(ctx->insn), ctx->insn->mnemonic, ctx->insn->op_str);
rz_warn_if_reached();
return 0;
}
return op->imm;
}

static inline st64 hppa_op_as_disp(RzAsmHPPAContext *ctx, int idx) {
const cs_hppa_op *op = hppa_op_get(ctx->insn, idx);
if (op->type != HPPA_OP_DISP) {
RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [imm]\n",
idx, hppa_op_count(ctx->insn), ctx->insn->mnemonic, ctx->insn->op_str);
rz_warn_if_reached();
return 0;
}
return op->imm;
}

static inline st64 hppa_op_as_target(RzAsmHPPAContext *ctx, int idx) {
const cs_hppa_op *op = hppa_op_get(ctx->insn, idx);
if (op->type != HPPA_OP_TARGET) {
RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [imm]\n",
idx, hppa_op_count(ctx->insn), ctx->insn->mnemonic, ctx->insn->op_str);
rz_warn_if_reached();
return 0;
}
return op->imm;
}
Loading
Loading