Use a hashtable fo the .equ rasm2 directive ##asm

This commit is contained in:
pancake 2023-09-08 19:15:44 +02:00 committed by GitHub
parent 3dfa5a7a63
commit ba6103455c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 60 deletions

View File

@ -8,53 +8,39 @@ R_API RAsmCode *r_asm_code_new(void) {
R_API void r_asm_code_free(RAsmCode *acode) {
if (acode) {
r_list_free (acode->equs);
ht_pp_free (acode->equs);
free (acode->bytes);
free (acode->assembly);
free (acode);
}
}
R_API void r_asm_equ_item_free(RAsmEqu *equ) {
if (equ) {
free (equ->key);
free (equ->value);
free (equ);
}
}
static RAsmEqu *__asm_equ_new(const char *key, const char *value) {
r_return_val_if_fail (key && value, NULL);
RAsmEqu *equ = R_NEW0 (RAsmEqu);
if (equ) {
equ->key = strdup (key);
equ->value = strdup (value);
}
return equ;
}
R_API void r_asm_code_set_equ(RAsmCode *code, const char *key, const char *value) {
r_return_if_fail (code && key && value);
if (code->equs) {
RAsmEqu *equ = r_asm_code_equ_get (code, key);
if (equ) {
free (equ->value);
equ->value = strdup (value);
}
} else {
code->equs = r_list_newf ((RListFree)r_asm_equ_item_free);
if (!code->equs) {
code->equs = ht_pp_new0 ();
}
r_list_append (code->equs, __asm_equ_new (key, value));
ht_pp_insert (code->equs, key, strdup (value));
}
typedef struct {
RAsmCode *code;
char *str;
} UserData;
static bool replace_cb(void *user, const void *key, const void *value) {
UserData *data = user;
data->str = r_str_replace (data->str, key, value, true);
return true;
}
R_API char *r_asm_code_equ_replace(RAsmCode *code, char *str) {
r_return_val_if_fail (code && str, NULL);
RAsmEqu *equ;
RListIter *iter;
r_list_foreach (code->equs, iter, equ) {
str = r_str_replace (str, equ->key, equ->value, true);
}
UserData data = {
.code = code,
.str = str
};
ht_pp_foreach (code->equs, replace_cb, &data);
return str;
}
@ -67,15 +53,8 @@ R_API char* r_asm_code_get_hex(RAsmCode *acode) {
return str;
}
R_API RAsmEqu *r_asm_code_equ_get(RAsmCode *code, const char *key) { // R2_590
// TODO: use a hashtable or sdb
void *equ;
RListIter *iter;
r_list_foreach (code->equs, iter, equ) {
RAsmEqu *e = (RAsmEqu*) equ;
if (!strcmp (e->key, key)) {
return e;
}
}
return NULL;
R_API char *r_asm_code_equ_get(RAsmCode *code, const char *key) {
r_return_val_if_fail (code && key, NULL);
bool found = false;
return ht_pp_find (code->equs, key, &found);
}

View File

@ -694,19 +694,21 @@ static int parse_asm_directive(RAsm *a, RAnalOp *op, RAsmCode *acode, char *ptr_
R_LOG_DEBUG (".global directive does nothing for now");
ret = 0;
} else if (r_str_startswith (ptr, ".equ ")) {
ptr2 = strchr (ptr + 5, ',');
char *arg = (char *)r_str_trim_head_ro (ptr + 5);
ptr2 = strchr (arg, ',');
if (!ptr2) {
ptr2 = strchr (ptr + 5, '=');
ptr2 = strchr (arg, '=');
}
if (!ptr2) {
ptr2 = strchr (ptr + 5, ' ');
ptr2 = strchr (arg, ' ');
}
if (ptr2) {
*ptr2 = '\0';
r_asm_code_set_equ (acode, ptr + 5, ptr2 + 1);
r_asm_code_set_equ (acode, arg, ptr2 + 1);
*ptr2 = ' ';
ret = 0;
} else {
R_LOG_ERROR ("Invalid syntax for '.equ': Use '.equ <word> <word>'");
R_LOG_ERROR ("Invalid syntax for '.equ': Use '.equ <word>=<word>'");
}
} else if (r_str_startswith (ptr, ".org ")) {
if (r_asm_pseudo_org (a, ptr + 5)) {

View File

@ -25,18 +25,12 @@ typedef struct r_asm_code_t {
// imho this asmcode should contain multiple archops
RAnalOp op; // we have those fields already inside RAnalOp
#endif
RList *equs; // TODO: must be a hash
HtPP *equs;
ut64 code_offset;
ut64 data_offset;
int code_align;
} RAsmCode;
// TODO: use a hashtable instead of an rlist
typedef struct {
char *key;
char *value;
} RAsmEqu;
typedef struct r_asm_t {
RArch *arch;
RArchConfig *config;
@ -100,11 +94,10 @@ R_API RList *r_asm_cpus(RAsm *a);
/* code.c */
R_API RAsmCode *r_asm_code_new(void);
R_API void r_asm_code_free(RAsmCode *acode);
R_API void r_asm_equ_item_free(RAsmEqu *equ);
R_API void r_asm_code_set_equ(RAsmCode *code, const char *key, const char *value);
R_API char *r_asm_code_equ_replace(RAsmCode *code, char *str);
R_API char* r_asm_code_get_hex(RAsmCode *acode);
R_API RAsmEqu *r_asm_code_equ_get(RAsmCode *code, const char *key);
R_API char *r_asm_code_equ_get(RAsmCode *code, const char *key);
/* op.c XXX Deprecate the use of all those apis and just use RArchOp */
R_API RAnalOp *r_asm_op_new(void);

View File

@ -431,7 +431,7 @@ NAME=rasm2 x86.asm.32
FILE=-
CMDS=!rasm2 -f bins/elf/analysis/hello.asm
EXPECT=<<EOF
ba0e000000b91d000000bb01000000b804000000cd80b801000000cd8048656c6c6f2c20776f726c64210a00
ba0e000000b917000000bb01000000b804000000cd80b801000000cd8048656c6c6f2c20776f726c64210a00
EOF
RUN
@ -703,3 +703,11 @@ EXPECT=<<EOF
ff4300d1
EOF
RUN
NAME=rasm2 -a x86 -b 64 -f equ.asm
FILE=-
CMDS=!rasm2 -a x86 -b 64 -f bins/src/equ.asm
EXPECT=<<EOF
48c7c003000000
EOF
RUN