analysis: add enum immediate hints with ahie command (#6052)

This commit is contained in:
Alok Kumar Mishra 2026-03-21 13:22:21 +05:30 committed by GitHub
parent 964335bcf6
commit c10d9c4a34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 349 additions and 58 deletions

View file

@ -9,6 +9,7 @@
#include <rz_util/rz_regex.h>
#include <rz_types.h>
#include <rz_arch.h>
#include <rz_type.h>
#define isx86separator(x) ( \
(x) == ' ' || (x) == '\t' || (x) == '\n' || (x) == '\r' || (x) == ' ' || \
@ -42,6 +43,39 @@ static void insert(char *dst, const char *src) {
free(endNum);
}
static void replace_number_token(char *out, size_t out_len, char *data, char *num_start, char *num_end, const char *value) {
*num_start = 0;
snprintf(out, out_len, "%s%s%s", data, value, (num_start != num_end) ? num_end : "");
}
static bool replace_enum_hint(RzParse *p, RzAnalysisHint *hint, ut64 off, char *data, char *out, size_t out_len, char *num_start, char *num_end) {
if (RZ_STR_ISEMPTY(hint->enum_name) || !p->analb.analysis || !p->analb.analysis->typedb) {
return false;
}
const char *member = rz_type_db_enum_member_by_val(
p->analb.analysis->typedb, hint->enum_name, off);
if (!member) {
return false;
}
char ename[512] = "";
size_t ename_len = strlen(hint->enum_name) + strlen(member) + 2;
if (ename_len <= sizeof(ename)) {
rz_strf(ename, "%s.%s", hint->enum_name, member);
replace_number_token(out, out_len, data, num_start, num_end, ename);
return true;
}
char *ename_dyn = rz_str_newf("%s.%s", hint->enum_name, member);
if (!ename_dyn) {
return false;
}
replace_number_token(out, out_len, data, num_start, num_end, ename_dyn);
free(ename_dyn);
return true;
}
static int parse_number(const char *str) {
const char *p = str;
// Parse as hexadecmial (0x notation)
@ -405,6 +439,8 @@ static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char
}
}
if (hint) {
char *num_start = ptr;
char *num_end = ptr2;
const int nw = hint->nword;
if (count != nw) {
ptr = ptr2;
@ -414,11 +450,13 @@ static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char
char num[256] = { 0 }, *pnum, *tmp;
int tmp_count;
if (hint->offset) {
*ptr = 0;
snprintf(str, len, "%s%s%s", data, hint->offset, (ptr != ptr2) ? ptr2 : "");
replace_number_token(str, len, data, num_start, num_end, hint->offset);
return true;
}
strncpy(num, ptr, sizeof(num) - 2);
if (replace_enum_hint(p, hint, off, data, str, len, num_start, num_end)) {
return true;
}
strncpy(num, num_start, sizeof(num) - 2);
pnum = num + parse_number(num);
*pnum = 0;
switch (immbase) {
@ -427,9 +465,9 @@ static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char
break;
case 1: // hack for ascii
tmp_count = 0;
for (tmp = data; tmp < ptr; tmp++) {
for (tmp = data; tmp < num_start; tmp++) {
if (*tmp == 0x1b) {
while (tmp < ptr - 1 && *tmp != 'm') {
while (tmp < num_start - 1 && *tmp != 'm') {
tmp++;
}
continue;
@ -545,8 +583,7 @@ static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char
snprintf(num, sizeof(num), "0x%" PFMT64x, (ut64)off);
break;
}
*ptr = 0;
snprintf(str, len, "%s%s%s", data, num, (ptr != ptr2) ? ptr2 : "");
replace_number_token(str, len, data, num_start, num_end, num);
return true;
}
ptr = ptr2;

View file

@ -49,6 +49,9 @@ static void addr_hint_record_fini(void *element, void *user) {
case RZ_ANALYSIS_ADDR_HINT_TYPE_ESIL:
free(record->esil);
break;
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
free(record->enum_name);
break;
default:
break;
}
@ -230,6 +233,16 @@ RZ_API void rz_analysis_hint_set_immbase(RzAnalysis *a, ut64 addr, int base) {
}
}
RZ_API void rz_analysis_hint_set_enum(RzAnalysis *a, ut64 addr, const char *enum_name) {
if (RZ_STR_ISEMPTY(enum_name)) {
rz_analysis_hint_unset_enum(a, addr);
return;
}
SET_HINT(RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM,
free(r->enum_name);
r->enum_name = rz_str_dup(enum_name););
}
RZ_API void rz_analysis_hint_set_pointer(RzAnalysis *a, ut64 addr, ut64 ptr) {
SET_HINT(RZ_ANALYSIS_ADDR_HINT_TYPE_PTR, r->ptr = ptr;);
}
@ -312,6 +325,10 @@ RZ_API void rz_analysis_hint_unset_immbase(RzAnalysis *a, ut64 addr) {
unset_addr_hint_record(a, RZ_ANALYSIS_ADDR_HINT_TYPE_IMMBASE, addr);
}
RZ_API void rz_analysis_hint_unset_enum(RzAnalysis *a, ut64 addr) {
unset_addr_hint_record(a, RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM, addr);
}
RZ_API void rz_analysis_hint_unset_nword(RzAnalysis *a, ut64 addr) {
unset_addr_hint_record(a, RZ_ANALYSIS_ADDR_HINT_TYPE_NWORD, addr);
}
@ -371,6 +388,7 @@ RZ_API void rz_analysis_hint_free(RzAnalysisHint *h) {
free(h->opcode);
free(h->syntax);
free(h->offset);
free(h->enum_name);
free(h);
}
}
@ -496,6 +514,10 @@ static void hint_merge(RzAnalysisHint *hint, RzAnalysisAddrHintRecord *record) {
case RZ_ANALYSIS_ADDR_HINT_TYPE_VAL:
hint->val = record->val;
break;
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
free(hint->enum_name);
hint->enum_name = rz_str_dup(record->enum_name);
break;
}
}

View file

@ -1848,6 +1848,11 @@ static bool hints_acc_store_cb(void *user, const ut64 addr, const void *v) {
case RZ_ANALYSIS_ADDR_HINT_TYPE_VAL:
pj_kn(j, "val", record->val);
break;
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
if (!RZ_STR_ISEMPTY(record->enum_name)) {
pj_ks(j, "enum", record->enum_name);
}
break;
}
}
}
@ -1884,7 +1889,8 @@ enum {
HINTS_FIELD_TYPE_OFFSET,
HINTS_FIELD_ESIL,
HINTS_FIELD_HIGH,
HINTS_FIELD_VAL
HINTS_FIELD_VAL,
HINTS_FIELD_ENUM
};
typedef struct {
@ -2015,6 +2021,12 @@ static bool hints_load_cb(void *user, const SdbKv *kv) {
}
rz_analysis_hint_set_val(analysis, addr, child->num.u_value);
break;
case HINTS_FIELD_ENUM:
if (child->type != RZ_JSON_STRING) {
break;
}
rz_analysis_hint_set_enum(analysis, addr, child->str_value);
break;
default:
break;
})
@ -2054,6 +2066,7 @@ RZ_API bool rz_serialize_analysis_hints_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAn
rz_key_parser_add(ctx.parser, "esil", HINTS_FIELD_ESIL);
rz_key_parser_add(ctx.parser, "high", HINTS_FIELD_HIGH);
rz_key_parser_add(ctx.parser, "val", HINTS_FIELD_VAL);
rz_key_parser_add(ctx.parser, "enum", HINTS_FIELD_ENUM);
ret = sdb_foreach(db, hints_load_cb, &ctx);
if (!ret) {
RZ_SERIALIZE_ERR(res, "hints parsing failed");

View file

@ -1118,6 +1118,9 @@ static void print_hint_h_format(HintNode *node) {
case RZ_ANALYSIS_ADDR_HINT_TYPE_VAL:
rz_cons_printf(" val=0x%08" PFMT64x, record->val);
break;
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
rz_cons_printf(" enum='%s'", rz_str_get(record->enum_name));
break;
}
}
break;
@ -1199,6 +1202,9 @@ static void hint_node_print(HintNode *node, RzOutputMode mode, PJ *pj) {
case RZ_ANALYSIS_ADDR_HINT_TYPE_VAL:
pj_kn(pj, "val", record->val);
break;
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
pj_ks(pj, "enum", rz_str_get(record->enum_name));
break;
}
}
break;

View file

@ -4601,7 +4601,7 @@ RZ_IPI RzCmdStatus rz_analysis_hint_del_optype_handler(RzCore *core, int argc, c
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_analysis_hint_set_immbase_handler(RzCore *core, int argc, const char **argv) {
RZ_IPI RzCmdStatus rz_analysis_hint_set_immbase_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode RZ_UNUSED) {
int base = rz_num_base_of_string(core->num, argv[1]);
if (argc == 3) {
ut64 nword = rz_num_math(core->num, argv[2]);
@ -4616,6 +4616,20 @@ RZ_IPI RzCmdStatus rz_analysis_hint_del_immbase_handler(RzCore *core, int argc,
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_analysis_hint_set_enum_handler(RzCore *core, int argc, const char **argv) {
if (argc == 3) {
ut64 nword = rz_num_math(core->num, argv[2]);
rz_analysis_hint_set_nword(core->analysis, core->offset, (int)(nword));
}
rz_analysis_hint_set_enum(core->analysis, core->offset, argv[1]);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_analysis_hint_del_enum_handler(RzCore *core, int argc, const char **argv) {
rz_analysis_hint_unset_enum(core->analysis, core->offset);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_analysis_hint_set_offset_handler(RzCore *core, int argc, const char **argv) {
return bool2status(rz_core_analysis_hint_set_offset(core, argv[1]));
}

View file

@ -1980,47 +1980,65 @@ commands:
cname: analysis_hint_del_optype
args: []
- name: ahi
summary: Set immediate base hint
cname: analysis_hint_set_immbase
args:
- name: type
type: RZ_CMD_ARG_TYPE_CHOICES
choices: ["2", "8", "10", "10u", "16", "b", "o", "h", "i", "p", "S", "s"]
- name: nword
type: RZ_CMD_ARG_TYPE_NUM
optional: true
details:
- name: ""
entries:
- text: "ahi "
arg_str: <base>
comment: Set numeric <base> (2, 8, 10, 16)
- text: ahi 10|d
comment: Set base to signed decimal (10), sign bit should depend on receiver size
- text: ahi 10u|du
comment: Set base to unsigned decimal (11)
- text: ahi b
comment: Set base to binary (2)
- text: ahi o
comment: Set base to octal (8)
- text: ahi h
comment: Set base to hexadecimal (16)
- text: ahi i
comment: Set base to IP address (32)
- text: ahi p
comment: Set base to htons(port) (3)
- text: ahi S
comment: Set base to syscall (80)
- text: ahi s
comment: Set base to string (1)
- name: Set base of the N-th immediate (indexing starts from 0)
entries:
- text: ahi 16 1
comment: Set base of the 1-st immediate to hexadecimal
- name: ahi-
summary: Delete immediate base hint
cname: analysis_hint_del_immbase
args: []
summary: Manage immediate operand hints
subcommands:
- name: ahi
summary: Set immediate base hint
cname: analysis_hint_set_immbase
modes:
- RZ_OUTPUT_MODE_STANDARD
args:
- name: type
type: RZ_CMD_ARG_TYPE_CHOICES
choices: ["2", "8", "10", "10u", "16", "b", "o", "h", "i", "p", "S", "s"]
- name: nword
type: RZ_CMD_ARG_TYPE_NUM
optional: true
details:
- name: ""
entries:
- text: "ahi "
arg_str: <base>
comment: Set numeric <base> (2, 8, 10, 16)
- text: ahi 10|d
comment: Set base to signed decimal (10), sign bit should depend on receiver size
- text: ahi 10u|du
comment: Set base to unsigned decimal (11)
- text: ahi b
comment: Set base to binary (2)
- text: ahi o
comment: Set base to octal (8)
- text: ahi h
comment: Set base to hexadecimal (16)
- text: ahi i
comment: Set base to IP address (32)
- text: ahi p
comment: Set base to htons(port) (3)
- text: ahi S
comment: Set base to syscall (80)
- text: ahi s
comment: Set base to string (1)
- name: Set base of the N-th immediate (indexing starts from 0)
entries:
- text: ahi 16 1
comment: Set base of the 1-st immediate to hexadecimal
- name: ahi-
summary: Delete immediate base hint
cname: analysis_hint_del_immbase
args: []
- name: ahie
summary: Set enum type hint for operand
cname: analysis_hint_set_enum
args:
- name: enum
type: RZ_CMD_ARG_TYPE_ENUM_TYPE
- name: nword
type: RZ_CMD_ARG_TYPE_NUM
optional: true
- name: ahie-
summary: Delete enum type hint
cname: analysis_hint_del_enum
args: []
- name: aht
summary: Set structure offset hint
cname: analysis_hint_set_offset

View file

@ -356,6 +356,7 @@ static const RzCmdDescArg analysis_hint_set_ret_args[2];
static const RzCmdDescArg analysis_hint_set_val_args[2];
static const RzCmdDescArg analysis_hint_set_optype_args[2];
static const RzCmdDescArg analysis_hint_set_immbase_args[3];
static const RzCmdDescArg analysis_hint_set_enum_args[3];
static const RzCmdDescArg analysis_hint_set_offset_args[2];
static const RzCmdDescArg analysis_list_struct_offsets_args[2];
static const RzCmdDescArg analysis_class_add_args[2];
@ -6996,6 +6997,9 @@ static const RzCmdDescHelp analysis_hint_del_optype_help = {
.args = analysis_hint_del_optype_args,
};
static const RzCmdDescHelp ahi_help = {
.summary = "Manage immediate operand hints",
};
static const RzCmdDescDetailEntry analysis_hint_set_immbase_empty_detail_entries[] = {
{ .text = "ahi ", .arg_str = "<base>", .comment = "Set numeric <base> (2, 8, 10, 16)" },
{ .text = "ahi 10|d", .arg_str = NULL, .comment = "Set base to signed decimal (10), sign bit should depend on receiver size" },
@ -7049,6 +7053,33 @@ static const RzCmdDescHelp analysis_hint_del_immbase_help = {
.args = analysis_hint_del_immbase_args,
};
static const RzCmdDescArg analysis_hint_set_enum_args[] = {
{
.name = "enum",
.type = RZ_CMD_ARG_TYPE_ENUM_TYPE,
},
{
.name = "nword",
.type = RZ_CMD_ARG_TYPE_NUM,
.optional = true,
},
{ 0 },
};
static const RzCmdDescHelp analysis_hint_set_enum_help = {
.summary = "Set enum type hint for operand",
.args = analysis_hint_set_enum_args,
};
static const RzCmdDescArg analysis_hint_del_enum_args[] = {
{ 0 },
};
static const RzCmdDescHelp analysis_hint_del_enum_help = {
.summary = "Delete enum type hint",
.args = analysis_hint_del_enum_args,
};
static const RzCmdDescDetailEntry analysis_hint_set_offset_empty_detail_entries[] = {
{ .text = "aht ", .arg_str = "struct.member", .comment = "Replace immediate with <struct.member>" },
{ 0 },
@ -22654,12 +22685,17 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
RzCmdDesc *analysis_hint_del_optype_cd = rz_cmd_desc_argv_new(core->rcmd, ah_cd, "aho-", rz_analysis_hint_del_optype_handler, &analysis_hint_del_optype_help);
rz_warn_if_fail(analysis_hint_del_optype_cd);
RzCmdDesc *analysis_hint_set_immbase_cd = rz_cmd_desc_argv_new(core->rcmd, ah_cd, "ahi", rz_analysis_hint_set_immbase_handler, &analysis_hint_set_immbase_help);
rz_warn_if_fail(analysis_hint_set_immbase_cd);
RzCmdDesc *analysis_hint_del_immbase_cd = rz_cmd_desc_argv_new(core->rcmd, ah_cd, "ahi-", rz_analysis_hint_del_immbase_handler, &analysis_hint_del_immbase_help);
RzCmdDesc *ahi_cd = rz_cmd_desc_group_modes_new(core->rcmd, ah_cd, "ahi", RZ_OUTPUT_MODE_STANDARD, rz_analysis_hint_set_immbase_handler, &analysis_hint_set_immbase_help, &ahi_help);
rz_warn_if_fail(ahi_cd);
RzCmdDesc *analysis_hint_del_immbase_cd = rz_cmd_desc_argv_new(core->rcmd, ahi_cd, "ahi-", rz_analysis_hint_del_immbase_handler, &analysis_hint_del_immbase_help);
rz_warn_if_fail(analysis_hint_del_immbase_cd);
RzCmdDesc *analysis_hint_set_enum_cd = rz_cmd_desc_argv_new(core->rcmd, ahi_cd, "ahie", rz_analysis_hint_set_enum_handler, &analysis_hint_set_enum_help);
rz_warn_if_fail(analysis_hint_set_enum_cd);
RzCmdDesc *analysis_hint_del_enum_cd = rz_cmd_desc_argv_new(core->rcmd, ahi_cd, "ahie-", rz_analysis_hint_del_enum_handler, &analysis_hint_del_enum_help);
rz_warn_if_fail(analysis_hint_del_enum_cd);
RzCmdDesc *analysis_hint_set_offset_cd = rz_cmd_desc_argv_new(core->rcmd, ah_cd, "aht", rz_analysis_hint_set_offset_handler, &analysis_hint_set_offset_help);
rz_warn_if_fail(analysis_hint_set_offset_cd);

View file

@ -800,9 +800,13 @@ RZ_IPI RzCmdStatus rz_analysis_hint_set_optype_handler(RzCore *core, int argc, c
// "aho-"
RZ_IPI RzCmdStatus rz_analysis_hint_del_optype_handler(RzCore *core, int argc, const char **argv);
// "ahi"
RZ_IPI RzCmdStatus rz_analysis_hint_set_immbase_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_analysis_hint_set_immbase_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
// "ahi-"
RZ_IPI RzCmdStatus rz_analysis_hint_del_immbase_handler(RzCore *core, int argc, const char **argv);
// "ahie"
RZ_IPI RzCmdStatus rz_analysis_hint_set_enum_handler(RzCore *core, int argc, const char **argv);
// "ahie-"
RZ_IPI RzCmdStatus rz_analysis_hint_del_enum_handler(RzCore *core, int argc, const char **argv);
// "aht"
RZ_IPI RzCmdStatus rz_analysis_hint_set_offset_handler(RzCore *core, int argc, const char **argv);
// "aht-"

View file

@ -571,7 +571,8 @@ typedef enum rz_analysis_addr_hint_type_t {
RZ_ANALYSIS_ADDR_HINT_TYPE_TYPE_OFFSET,
RZ_ANALYSIS_ADDR_HINT_TYPE_ESIL,
RZ_ANALYSIS_ADDR_HINT_TYPE_HIGH,
RZ_ANALYSIS_ADDR_HINT_TYPE_VAL
RZ_ANALYSIS_ADDR_HINT_TYPE_VAL,
RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM
} RzAnalysisAddrHintType;
typedef struct rz_analysis_addr_hint_record_t {
@ -592,6 +593,7 @@ typedef struct rz_analysis_addr_hint_record_t {
ut64 size;
ut64 stackframe;
ut64 val;
char *enum_name;
};
} RzAnalysisAddrHintRecord;
@ -615,6 +617,7 @@ typedef struct rz_analysis_hint_t {
bool high; // highlight hint
int nword;
ut64 stackframe;
char *enum_name;
} RzAnalysisHint;
typedef RzAnalysisFunction *(*RzAnalysisGetFcnIn)(RzAnalysis *analysis, ut64 addr, int type);
@ -2179,6 +2182,7 @@ RZ_API void rz_analysis_hint_set_newbits(RzAnalysis *a, ut64 addr, int bits);
RZ_API void rz_analysis_hint_set_nword(RzAnalysis *a, ut64 addr, int nword);
RZ_API void rz_analysis_hint_set_offset(RzAnalysis *a, ut64 addr, const char *typeoff);
RZ_API void rz_analysis_hint_set_immbase(RzAnalysis *a, ut64 addr, int base);
RZ_API void rz_analysis_hint_set_enum(RzAnalysis *a, ut64 addr, const char *enum_name);
RZ_API void rz_analysis_hint_set_size(RzAnalysis *a, ut64 addr, ut64 size);
RZ_API void rz_analysis_hint_set_opcode(RzAnalysis *a, ut64 addr, const char *str);
RZ_API void rz_analysis_hint_set_esil(RzAnalysis *a, ut64 addr, const char *str);
@ -2192,6 +2196,7 @@ RZ_API void rz_analysis_hint_set_bits(RzAnalysis *a, ut64 addr, int bits); // bi
RZ_API void rz_analysis_hint_unset_val(RzAnalysis *a, ut64 addr);
RZ_API void rz_analysis_hint_unset_high(RzAnalysis *a, ut64 addr);
RZ_API void rz_analysis_hint_unset_immbase(RzAnalysis *a, ut64 addr);
RZ_API void rz_analysis_hint_unset_enum(RzAnalysis *a, ut64 addr);
RZ_API void rz_analysis_hint_unset_nword(RzAnalysis *a, ut64 addr);
RZ_API void rz_analysis_hint_unset_size(RzAnalysis *a, ut64 addr);
RZ_API void rz_analysis_hint_unset_type(RzAnalysis *a, ut64 addr);

View file

@ -114,6 +114,12 @@ int parse_primitive_type(CParserState *state, TSNode node, const char *text, Par
free(real_type);
return 0;
}
if ((*tpair = c_parser_get_typedef(state, real_type))) {
(*tpair)->type->identifier.is_const = is_const;
parser_debug(state, "Fetched type alias: \"%s\"\n", real_type);
free(real_type);
return 0;
}
// If not - we form both RzType and RzBaseType to store in the Types database
ParserTypePair *type_pair = c_parser_new_primitive_type(state, real_type, is_const);
if (!type_pair) {
@ -150,6 +156,12 @@ int parse_sized_primitive_type(CParserState *state, TSNode node, const char *tex
free(real_type);
return 0;
}
if ((*tpair = c_parser_get_typedef(state, real_type))) {
(*tpair)->type->identifier.is_const = is_const;
parser_debug(state, "Fetched type alias: \"%s\"\n", real_type);
free(real_type);
return 0;
}
// If not - we form both RzType and RzBaseType to store in the Types database
ParserTypePair *type_pair = c_parser_new_primitive_type(state, real_type, is_const);
if (!type_pair) {

View file

@ -380,3 +380,87 @@ EXPECT=<<EOF
0x00000000 cmp rax, 18446744073709551615
EOF
RUN
NAME=ahie enum operands
FILE==
CMDS=<<EOF
o malloc://256
td "enum E { SEVEN = 7, EIGHT = 8, MASK = 0x100, WORD = 0xffc643 };"
e asm.arch=x86
e asm.bits=64
e cfg.bigendian=false
s 0
wx 4180fc07
ahie E
pi 1
ahie-
pi 1
wx 4883f803
ahie E
pi 1
s 0x10
wx c7458843c6ff00
ahie E 1
pdq 1
e asm.arch=arm
e asm.bits=32
e cfg.bigendian=false
s 0x20
wx 0700a0e3
ahie E
pi 1
e asm.arch=arm
e asm.bits=64
s 0x30
wx e00080d2
ahie E
pi 1
e asm.arch=ppc
e asm.bits=32
e cfg.bigendian=true
s 0x40
wx 38600007
ahie E
pi 1
e asm.arch=mips
e asm.bits=32
e cfg.bigendian=true
s 0x50
wx 20020007
ahie E
pi 1
e asm.arch=8051
e asm.bits=8
s 0x60
wx 7407
ahie E
pi 1
e asm.arch=tricore
e asm.bits=32
e cfg.bigendian=true
s 0x70
wx 8f005001
ahie E
pi 1
e asm.arch=hexagon
e asm.bits=32
e cfg.bigendian=false
s 0x80
wx 01c09da0
ahie E
pi 1
EOF
EXPECT=<<EOF
cmp r12b, E.SEVEN
cmp r12b, 0x07
cmp rax, 0x03
0x00000010 mov dword [rbp-0x78], E.WORD
mov r0, E.SEVEN
mov x0, E.SEVEN
li r3, E.SEVEN
addi v0, zero, E.SEVEN
mov a, #E.SEVEN
or d0, d0, #E.MASK
[ allocframe(SP,#E.EIGHT):raw
EOF
RUN

View file

@ -25,6 +25,7 @@ const RzAnalysisHint empty_hint = {
.high = 0,
.nword = 0,
.stackframe = UT64_MAX,
.enum_name = NULL,
};
bool hint_equals(const RzAnalysisHint *a, const RzAnalysisHint *b) {
@ -49,6 +50,7 @@ bool hint_equals(const RzAnalysisHint *a, const RzAnalysisHint *b) {
CHECK_STREQ(syntax);
CHECK_STREQ(esil);
CHECK_STREQ(offset);
CHECK_STREQ(enum_name);
#undef CHECK_STREQ
return true;
}
@ -109,6 +111,10 @@ bool test_rz_analysis_addr_hints() {
cur.immbase = 7;
CHECK
rz_analysis_hint_set_enum(analysis, 0x1337, "BLA");
cur.enum_name = "BLA";
CHECK
rz_analysis_hint_set_size(analysis, 0x1337, 0x123);
cur.size = 0x123;
CHECK
@ -175,6 +181,10 @@ bool test_rz_analysis_addr_hints() {
cur.immbase = 0;
CHECK
rz_analysis_hint_unset_enum(analysis, 0x1337);
cur.enum_name = NULL;
CHECK
rz_analysis_hint_unset_size(analysis, 0x1337);
cur.size = 0;
CHECK
@ -343,4 +353,4 @@ bool all_tests() {
return tests_passed != tests_run;
}
mu_main(all_tests)
mu_main(all_tests)

View file

@ -979,6 +979,7 @@ Sdb *hints_ref_db() {
sdb_set(db, "0x2b0", "{\"esil\":\"13,29,+\"}");
sdb_set(db, "0x2c0", "{\"high\":true}");
sdb_set(db, "0x2d0", "{\"val\":54323}");
sdb_set(db, "0x2e0", "{\"enum\":\"BLA\"}");
return db;
}
@ -1026,6 +1027,7 @@ bool test_analysis_hints_save() {
rz_analysis_hint_set_esil(analysis, 0x2b0, "13,29,+");
rz_analysis_hint_set_high(analysis, 0x2c0);
rz_analysis_hint_set_val(analysis, 0x2d0, 54323);
rz_analysis_hint_set_enum(analysis, 0x2e0, "BLA");
size_t i;
for (i = 0; i < ALL_OPTYPES_COUNT; i++) {
@ -1070,7 +1072,7 @@ bool test_analysis_hints_load() {
rz_analysis_addr_hints_foreach(analysis, addr_hints_count_cb, &count);
rz_analysis_arch_hints_foreach(analysis, arch_hints_count_cb, &count);
rz_analysis_bits_hints_foreach(analysis, bits_hints_count_cb, &count);
mu_assert_eq(count, 19 + ALL_OPTYPES_COUNT, "hints count");
mu_assert_eq(count, 20 + ALL_OPTYPES_COUNT, "hints count");
ut64 addr;
const char *arch = rz_analysis_hint_arch_at(analysis, 0x100, &addr);
@ -1116,6 +1118,7 @@ bool test_analysis_hints_load() {
assert_addr_hint(0x2b0, ESIL, mu_assert_streq(record->esil, "13,29,+", "esil hint"));
assert_addr_hint(0x2c0, HIGH, );
assert_addr_hint(0x2d0, VAL, mu_assert_eq(record->val, 54323, "val hint"));
assert_addr_hint(0x2e0, ENUM, mu_assert_streq(record->enum_name, "BLA", "enum hint"));
size_t i;
for (i = 0; i < ALL_OPTYPES_COUNT; i++) {

View file

@ -762,6 +762,32 @@ static bool test_array_types(void) {
mu_end;
}
static bool test_single_typedef_aliases(void) {
RzTypeDB *typedb = rz_type_db_new();
mu_assert_notnull(typedb, "Couldn't create new RzTypeDB");
mu_assert_notnull(typedb->types, "Couldn't create new types hashtable");
const char *types_dir = TEST_BUILD_TYPES_DIR;
const char *src[] = { "size_t", "uint32_t", "uint64_t", "const size_t" };
const char *name[] = { "size_t", "uint32_t", "uint64_t", "size_t" };
const bool cnst[] = { false, false, false, true };
rz_type_db_init(typedb, types_dir, "x86", 64, "linux");
rz_type_db_set_bits(typedb, 64);
for (size_t i = 0; i < RZ_ARRAY_SIZE(src); i++) {
char *error_msg = NULL;
RzType *ttype = rz_type_parse_string_single(typedb->parser, src[i], &error_msg);
mu_assert_notnull(ttype, "typedef alias parse successful");
mu_assert_null(error_msg, "parsing errors");
mu_assert_eq(ttype->kind, RZ_TYPE_KIND_IDENTIFIER, "parsed type");
mu_assert_streq(ttype->identifier.name, name[i], "parsed type");
mu_assert_eq(ttype->identifier.is_const, cnst[i], "parsed const");
rz_type_free(ttype);
}
rz_type_db_free(typedb);
mu_end;
}
static char *func_ptr_struct = "struct bla { int a; wchar_t (*func)(int a, const char *b); }";
static char *func_double_ptr_struct = "struct blabla { int a; wchar_t (**funk)(int a, const char *b); }";
@ -1866,6 +1892,7 @@ int all_tests() {
mu_run_test(test_enum_types);
mu_run_test(test_const_types);
mu_run_test(test_array_types);
mu_run_test(test_single_typedef_aliases);
mu_run_test(test_struct_func_types);
mu_run_test(test_struct_array_types);
mu_run_test(test_struct_identifier_without_specifier);