Refactor Meta out of SDB (#16716)

This commit is contained in:
Florian Märkl 2020-05-09 20:49:28 +02:00 committed by GitHub
parent 9a1842924c
commit edf1be10d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 1545 additions and 1389 deletions

1
.gitignore vendored
View File

@ -123,3 +123,4 @@ __pycache__
# Dynamic docker building folder to minimize docker context
.docker_alpine
.ccls-cache/
vgcore.*

View File

@ -64,6 +64,18 @@ static void zign_rename_for(REvent *ev, int type, void *user, void *data) {
void r_anal_hint_storage_init(RAnal *a);
void r_anal_hint_storage_fini(RAnal *a);
static void r_meta_item_fini(RAnalMetaItem *item) {
free (item->str);
}
static void r_meta_item_free(void *_item) {
if (_item) {
RAnalMetaItem *item = _item;
r_meta_item_fini (item);
free (item);
}
}
R_API RAnal *r_anal_new(void) {
int i;
RAnal *anal = R_NEW0 (RAnal);
@ -95,8 +107,8 @@ R_API RAnal *r_anal_new(void) {
r_event_hook (anal->zign_spaces.event, R_SPACE_EVENT_COUNT, zign_count_for, NULL);
r_event_hook (anal->zign_spaces.event, R_SPACE_EVENT_RENAME, zign_rename_for, NULL);
anal->sdb_fcns = sdb_ns (anal->sdb, "fcns", 1);
anal->sdb_meta = sdb_ns (anal->sdb, "meta", 1);
r_anal_hint_storage_init (anal);
r_interval_tree_init (&anal->meta, r_meta_item_free);
anal->sdb_types = sdb_ns (anal->sdb, "types", 1);
anal->sdb_fmts = sdb_ns (anal->sdb, "spec", 1);
anal->sdb_cc = sdb_ns (anal->sdb, "cc", 1);
@ -147,6 +159,7 @@ R_API RAnal *r_anal_free(RAnal *a) {
ht_pp_free (a->ht_name_fun);
set_u_free (a->visited);
r_anal_hint_storage_fini (a);
r_interval_tree_fini (&a->meta);
free (a->cpu);
free (a->os);
free (a->zign_path);
@ -428,8 +441,9 @@ R_API bool r_anal_op_is_eob(RAnalOp *op) {
R_API int r_anal_purge (RAnal *anal) {
sdb_reset (anal->sdb_fcns);
sdb_reset (anal->sdb_meta);
r_anal_hint_clear (anal);
r_interval_tree_fini (&anal->meta);
r_interval_tree_init (&anal->meta, r_meta_item_free);
sdb_reset (anal->sdb_types);
sdb_reset (anal->sdb_zigns);
sdb_reset (anal->sdb_classes);

View File

@ -817,7 +817,7 @@ repeat:
case R_ANAL_OP_TYPE_LOAD:
if (anal->opt.loads) {
if (anal->iob.is_valid_offset (anal->iob.io, op.ptr, 0)) {
r_meta_add (anal, R_META_TYPE_DATA, op.ptr, op.ptr + 4, "");
r_meta_set (anal, R_META_TYPE_DATA, op.ptr, 4, "");
}
}
break;
@ -1249,20 +1249,21 @@ R_API void r_anal_del_jmprefs(RAnal *anal, RAnalFunction *fcn) {
/* Does NOT invalidate read-ahead cache. */
R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int reftype) {
RListIter *iter;
RAnalMetaItem *meta;
RList *list = r_meta_find_list_in (anal, addr, -1, 4);
r_list_foreach (list, iter, meta) {
RPVector *metas = r_meta_get_all_in(anal, addr, R_META_TYPE_ANY);
void **it;
r_pvector_foreach (metas, it) {
RAnalMetaItem *meta = ((RIntervalNode *)*it)->data;
switch (meta->type) {
case R_META_TYPE_DATA:
case R_META_TYPE_STRING:
case R_META_TYPE_FORMAT:
r_list_free (list);
r_pvector_free (metas);
return 0;
default:
break;
}
}
r_list_free (list);
r_pvector_free (metas);
if (anal->opt.norevisit) {
if (!anal->visited) {
anal->visited = set_u_new ();

File diff suppressed because it is too large Load Diff

View File

@ -122,12 +122,32 @@ R_API RList *r_anal_reflines_get(RAnal *anal, ut64 addr, const ut8 *buf, ut64 le
}
addr += sz;
{
RAnalMetaItem *mi = r_meta_find_any_except (anal, addr, R_META_TYPE_COMMENT, 0);
if (mi) {
ptr += mi->size;
addr += mi->size;
r_meta_item_free (mi);
goto __next;
RPVector *metas = r_meta_get_all_at (anal, addr);
if (metas) {
void **it;
ut64 skip = 0;
r_pvector_foreach (metas, it) {
RIntervalNode *node = *it;
RAnalMetaItem *meta = node->data;
switch (meta->type) {
case R_META_TYPE_DATA:
case R_META_TYPE_STRING:
case R_META_TYPE_HIDE:
case R_META_TYPE_FORMAT:
case R_META_TYPE_MAGIC:
skip = r_meta_node_size (node);
goto do_skip;
default:
break;
}
}
do_skip:
r_pvector_free (metas);
if (skip) {
ptr += skip;
addr += skip;
goto __next;
}
}
}
if (!anal->iob.is_valid_offset (anal->iob.io, addr, 1)) {

View File

@ -228,7 +228,7 @@ static bool objc_find_refs(RCore *core) {
total = 0;
ut64 a;
for (a = from; a < to; a += objc.word_size) {
r_meta_add (core->anal, R_META_TYPE_DATA, a, a + 8, NULL);
r_meta_set (core->anal, R_META_TYPE_DATA, a, 8, NULL);
total ++;
}
oldstr = r_print_rowlog (core->print, sdb_fmt ("Set %d dwords at 0x%08"PFMT64x, total, from));

View File

@ -49,21 +49,24 @@ static int __isdata(RCore *core, ut64 addr) {
return 1;
}
RList *list = r_meta_find_list_in (core->anal, addr, -1, 4);
RListIter *iter;
RAnalMetaItem *meta;
RPVector *list = r_meta_get_all_in (core->anal, addr, R_META_TYPE_ANY);
void **it;
int result = 0;
r_list_foreach (list, iter, meta) {
r_pvector_foreach (list, it) {
RIntervalNode *node = *it;
RAnalMetaItem *meta = node->data;
switch (meta->type) {
case R_META_TYPE_DATA:
case R_META_TYPE_STRING:
case R_META_TYPE_FORMAT:
result = meta->size - (addr - meta->from);
result = node->end - addr + 1;
goto exit;
default:
break;
}
}
exit:
r_list_free (list);
r_pvector_free (list);
return result;
}

View File

@ -876,12 +876,12 @@ static int __core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dep
if (i == nexti) {
ut64 at = r_anal_function_max_addr (fcn);
while (true) {
RAnalMetaItem *mi = r_meta_find (core->anal, at, R_META_TYPE_ANY, 0);
ut64 size;
RAnalMetaItem *mi = r_meta_get_at (core->anal, at, R_META_TYPE_ANY, &size);
if (!mi) {
break;
}
at += mi->size;
r_meta_item_free (mi);
at += size;
}
// TODO: ensure next address is function after padding (nop or trap or wat)
// XXX noisy for test cases because we want to clear the stderr
@ -3868,8 +3868,8 @@ static bool found_xref(RCore *core, ut64 at, ut64 xref_to, RAnalRefType type, in
r_flag_space_pop (core->flags);
free (str_flagname);
if (len > 0) {
r_meta_add (core->anal, R_META_TYPE_STRING, xref_to,
xref_to + len, (const char *)str_string);
r_meta_set (core->anal, R_META_TYPE_STRING, xref_to,
len, (const char *) str_string);
}
free (str_string);
}
@ -4275,25 +4275,29 @@ R_API RCoreAnalStats* r_core_anal_get_stats(RCore *core, ut64 from, ut64 to, ut6
piece = (S->vaddr - from) / step;
as->block[piece].symbols++;
}
RList *metas = r_meta_enumerate (core->anal, -1);
RAnalMetaItem *M;
r_list_foreach (metas, iter, M) {
if (M->from < from || M->to > to) {
continue;
}
piece = (M->from - from) / step;
switch (M->type) {
case R_META_TYPE_STRING:
as->block[piece].strings++;
break;
case R_META_TYPE_COMMENT:
as->block[piece].comments++;
break;
RPVector *metas = to > from ? r_meta_get_all_intersect (core->anal, from, to - from, R_META_TYPE_ANY) : NULL;
if (metas) {
void **it;
r_pvector_foreach (metas, it) {
RIntervalNode *node = *it;
RAnalMetaItem *mi = node->data;
if (node->start < from || node->end > to) {
continue;
}
piece = (node->start - from) / step;
switch (mi->type) {
case R_META_TYPE_STRING:
as->block[piece].strings++;
break;
case R_META_TYPE_COMMENT:
as->block[piece].comments++;
break;
default:
break;
}
}
r_pvector_free (metas);
}
r_list_free (metas);
// iter all comments
// iter all strings
return as;
}
@ -4574,7 +4578,7 @@ static void add_string_ref(RCore *core, ut64 xref_from, ut64 xref_to) {
r_flag_space_push (core->flags, R_FLAGS_FS_STRINGS);
r_flag_set (core->flags, flagname, xref_to, len);
r_flag_space_pop (core->flags);
r_meta_add (core->anal, 's', xref_to, xref_to + len, str_flagname);
r_meta_set (core->anal, 's', xref_to, len, str_flagname);
free (str_flagname);
}
}
@ -4936,22 +4940,23 @@ repeat:
break;
}
{
RList *list = r_meta_find_list_in (core->anal, cur, -1, 4);
RListIter *iter;
RAnalMetaItem *meta;
r_list_foreach (list, iter, meta) {
RPVector *list = r_meta_get_all_in (core->anal, cur, R_META_TYPE_ANY);
void **it;
r_pvector_foreach (list, it) {
RIntervalNode *node = *it;
RAnalMetaItem *meta = node->data;
switch (meta->type) {
case R_META_TYPE_DATA:
case R_META_TYPE_STRING:
case R_META_TYPE_FORMAT:
i += 4;
r_list_free (list);
r_pvector_free (list);
goto repeat;
default:
break;
}
}
if (list) {
r_list_free (list);
}
r_pvector_free (list);
}
/* realign address if needed */

View File

@ -292,7 +292,7 @@ static void _print_strings(RCore *r, RList *list, int mode, int va) {
if (r_cons_is_breaked ()) {
break;
}
r_meta_add (r->anal, R_META_TYPE_STRING, vaddr, vaddr + string->size, string->string);
r_meta_set (r->anal, R_META_TYPE_STRING, vaddr, string->size, string->string);
f_name = strdup (string->string);
r_name_filter (f_name, -1);
if (r->bin->prefix) {
@ -1236,8 +1236,7 @@ static int bin_entry(RCore *r, int mode, ut64 laddr, int va, bool inifin) {
}
r_flag_set (r->flags, str, at, 1);
if (is_initfini (entry) && hvaddr != UT64_MAX) {
r_meta_add (r->anal, R_META_TYPE_DATA, hvaddr,
hvaddr + entry->bits / 8, NULL);
r_meta_set (r->anal, R_META_TYPE_DATA, hvaddr, entry->bits / 8, NULL);
}
} else if (IS_MODE_SIMPLE (mode)) {
r_cons_printf ("0x%08"PFMT64x"\n", at);
@ -1427,7 +1426,7 @@ static void set_bin_relocs(RCore *r, RBinReloc *reloc, ut64 addr, Sdb **db, char
}
}
r_anal_hint_set_size (r->anal, reloc->vaddr, 4);
r_meta_add (r->anal, R_META_TYPE_DATA, reloc->vaddr, reloc->vaddr+4, NULL);
r_meta_set (r->anal, R_META_TYPE_DATA, reloc->vaddr, 4, NULL);
}
char flagname[R_FLAG_NAME_SIZE];
@ -1479,7 +1478,7 @@ static void add_metadata(RCore *r, RBinReloc *reloc, ut64 addr, int mode) {
return;
}
if (IS_MODE_SET (mode)) {
r_meta_add (r->anal, R_META_TYPE_DATA, reloc->vaddr, reloc->vaddr + cdsz, NULL);
r_meta_set (r->anal, R_META_TYPE_DATA, reloc->vaddr, cdsz, NULL);
} else if (IS_MODE_RAD (mode)) {
r_cons_printf ("Cd %d @ 0x%08" PFMT64x "\n", cdsz, addr);
}
@ -1836,7 +1835,7 @@ static int bin_imports(RCore *r, int mode, int va, const char *name) {
// TODO(eddyb) symbols that are imports.
// Add a dword/qword for PE imports
if (libname && strstr (libname, ".dll") && cdsz) {
r_meta_add (r->anal, R_META_TYPE_DATA, addr, addr + cdsz, NULL);
r_meta_set (r->anal, R_META_TYPE_DATA, addr, cdsz, NULL);
}
} else if (IS_MODE_SIMPLE (mode)) {
r_cons_printf ("%s%s%s\n",
@ -2205,8 +2204,8 @@ static int bin_symbols(RCore *r, int mode, ut64 laddr, int va, ut64 at, const ch
free (fnp);
}
if (sn.demname) {
r_meta_add (r->anal, R_META_TYPE_COMMENT,
addr, symbol->size, sn.demname);
r_meta_set (r->anal, R_META_TYPE_COMMENT,
addr, symbol->size, sn.demname);
}
r_flag_space_pop (r->flags);
} else if (IS_MODE_JSON (mode)) {
@ -2759,7 +2758,7 @@ static int bin_sections(RCore *r, int mode, ut64 laddr, int va, ut64 at, const c
str = r_str_newf ("[%02d] %s %s size %" PFMT64d" named %s%s%s",
i, perms, type, size,
pfx? pfx: "", pfx? ".": "", section->name);
r_meta_add (r->anal, R_META_TYPE_COMMENT, addr, addr, str);
r_meta_set (r->anal, R_META_TYPE_COMMENT, addr, 1, str);
R_FREE (str);
}
if (section->add) {

View File

@ -11,22 +11,25 @@ R_API RCoreItem *r_core_item_at (RCore *core, ut64 addr) {
// TODO: honor section perms too?
if (map->perm & R_PERM_X) {
// if theres a meta consider it data
RAnalMetaItem *item = r_meta_find (core->anal, addr, R_META_TYPE_ANY, 0);
ut64 size;
RAnalMetaItem *item = r_meta_get_at (core->anal, addr, R_META_TYPE_ANY, &size);
if (item) {
switch (item->type) {
case R_META_TYPE_DATA:
ci->type = "data";
ci->size = item->size;
ci->size = size;
ci->data = r_core_cmd_strf (core, "pdi 1 @e:asm.flags=0@e:asm.lines=0@e:scr.color=0@0x%08"PFMT64x, addr);
r_str_trim (ci->data);
break;
case R_META_TYPE_FORMAT:
ci->type = "format"; // struct :?
ci->size = item->size;
ci->size = size;
break;
case R_META_TYPE_STRING:
ci->type = "string";
ci->size = item->size;
ci->size = size;
break;
default:
break;
}
if (item->str) {
@ -34,7 +37,6 @@ R_API RCoreItem *r_core_item_at (RCore *core, ut64 addr) {
ci->data = strdup (item->str);
}
}
r_meta_item_free (item);
}
}
}

View File

@ -3803,21 +3803,6 @@ fail:
goto beach;
}
static int foreach_comment(void *user, const char *k, const char *v) {
RAnalMetaUserItem *ui = user;
RCore *core = ui->anal->user;
const char *cmd = ui->user;
if (!strncmp (k, "meta.C.", 7)) {
char *cmt = (char *)sdb_decode (v, 0);
if (cmt) {
r_core_cmdf (core, "s %s", k + 7);
r_core_cmd0 (core, cmd);
free (cmt);
}
}
return 1;
}
struct exec_command_t {
RCore *core;
const char *cmd;
@ -3881,9 +3866,22 @@ R_API int r_core_cmd_foreach3(RCore *core, const char *cmd, char *each) { // "@@
eprintf ("Usage: @@@c:command # same as @@@=`command`\n");
}
break;
case 'C':
r_meta_list_cb (core->anal, R_META_TYPE_COMMENT, 0, foreach_comment, (void*)cmd, UT64_MAX);
case 'C': {
char *glob = filter ? r_str_trim_dup (filter): NULL;
RIntervalTreeIter it;
RAnalMetaItem *meta;
r_interval_tree_foreach (&core->anal->meta, it, meta) {
if (meta->type != R_META_TYPE_COMMENT) {
continue;
}
if (!glob || (meta->str && r_str_glob (meta->str, glob))) {
r_core_seek (core, r_interval_tree_iter_get (&it)->start, true);
r_core_cmd0 (core, cmd);
}
}
free (glob);
break;
}
case 'm':
{
int fd = r_io_fd_get_current (core->io);
@ -4670,37 +4668,6 @@ static int cmdstatus2int(RCmdStatus s) {
}
}
struct foreach_comment_newshell_t {
TSNode *command;
struct tsr2cmd_state *state;
};
static int foreach_comment_newshell(void *user, const char *k, const char *v) {
RAnalMetaUserItem *ui = user;
RCore *core = ui->anal->user;
struct foreach_comment_newshell_t *cmt_t = ui->user;
TSNode *cmd = cmt_t->command;
struct tsr2cmd_state *state = cmt_t->state;
if (!strncmp (k, "meta.C.", 7)) {
char *ptr = strchr (v, ',');
if (R_STR_ISEMPTY (ptr)) {
return 1;
}
ptr = strchr (ptr + 1, ',');
if (R_STR_ISEMPTY (ptr)) {
return 1;
}
char *cmt = (char *)sdb_decode (ptr + 1, 0);
if (cmt) {
ut64 k_addr = r_num_math (state->core->num, k + 7);
r_core_seek (core, k_addr, false);
handle_ts_command_tmpseek (state, *cmd);
free (cmt);
}
}
return 1;
}
static struct tsr2cmd_edit *create_cmd_edit(struct tsr2cmd_state *state, TSNode arg, char *new_text) {
struct tsr2cmd_edit *e = R_NEW0 (struct tsr2cmd_edit);
ut32 command_start = ts_node_start_byte (state->substitute_cmd);
@ -6100,13 +6067,30 @@ DEFINE_HANDLE_TS_FCN_AND_SYMBOL(foreach_cmd_command) {
}
DEFINE_HANDLE_TS_FCN_AND_SYMBOL(foreach_comment_command) {
RCore *core = state->core;
TSNode command = ts_node_named_child (node, 0);
struct foreach_comment_newshell_t cmt_t = {
.command = &command,
.state = state,
};
r_meta_list_cb (state->core->anal, R_META_TYPE_COMMENT, 0, foreach_comment_newshell, (void *)&cmt_t, UT64_MAX);
return R_CMD_STATUS_OK;
TSNode filter_node = ts_node_named_child (node, 1);
char *glob = !ts_node_is_null (filter_node)
? ts_node_sub_string (filter_node, state->input)
: NULL;
ut64 off = core->offset;
RCmdStatus res = R_CMD_STATUS_OK;
RIntervalTreeIter it;
RAnalMetaItem *meta;
r_interval_tree_foreach (&core->anal->meta, it, meta) {
if (meta->type != R_META_TYPE_COMMENT) {
continue;
}
if (!glob || (meta->str && r_str_glob (meta->str, glob))) {
r_core_seek (core, r_interval_tree_iter_get (&it)->start, true);
RCmdStatus cmd_res = handle_ts_command_tmpseek (state, command);
UPDATE_CMD_STATUS_RES (res, cmd_res, err);
}
}
err:
r_core_seek (core, off, false);
free (glob);
return res;
}
DEFINE_HANDLE_TS_FCN_AND_SYMBOL(foreach_import_command) {

View File

@ -7265,14 +7265,19 @@ static bool cmd_anal_refs(RCore *core, const char *input) {
ref->addr, ref->type, addr, iter->n? ",": "");
} else { // axt
RAnalFunction *fcn;
char *comment;
r_list_foreach (list, iter, ref) {
fcn = r_anal_get_fcn_in (core->anal, ref->addr, 0);
char *buf_asm = get_buf_asm (core, addr, ref->addr, fcn, true);
comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ref->addr);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ref->addr);
char *print_comment = NULL;
const char *nl = comment ? strchr (comment, '\n') : NULL;
if (nl) { // display only until the first newline
comment = print_comment = r_str_ndup (comment, nl - comment);
}
char *buf_fcn = comment
? r_str_newf ("%s; %s", fcn ? fcn->name : "(nofunc)", strtok (comment, "\n"))
? r_str_newf ("%s; %s", fcn ? fcn->name : "(nofunc)", comment)
: r_str_newf ("%s", fcn ? fcn->name : "(nofunc)");
free (print_comment);
r_cons_printf ("%s 0x%" PFMT64x " [%s] %s\n",
buf_fcn, ref->addr, r_anal_xrefs_type_tostring (ref->type), buf_asm);
free (buf_asm);
@ -8711,7 +8716,7 @@ static void _CbInRangeAav(RCore *core, ut64 from, ut64 to, int vsize, int count,
r_cons_printf ("f+ aav.0x%08"PFMT64x "= 0x%08"PFMT64x, to, to);
} else {
r_anal_xrefs_set (core->anal, from, to, R_ANAL_REF_TYPE_NULL);
// r_meta_add (core->anal, 'd', from, from + vsize, NULL);
// r_meta_set (core->anal, 'd', from, from + vsize, NULL);
r_core_cmdf (core, "Cd %d @ 0x%"PFMT64x "\n", vsize, from);
if (!r_flag_get_at (core->flags, to, false)) {
char *name = r_str_newf ("aav.0x%08"PFMT64x, to);

View File

@ -473,19 +473,19 @@ static int cmd_eval(void *data, const char *input) {
r_str_argv_free (argv);
return false;
case '.':
r_meta_list_at (core->anal, R_META_TYPE_HIGHLIGHT, 0, core->offset);
r_meta_print_list_in_function (core->anal, R_META_TYPE_HIGHLIGHT, 0, core->offset);
r_str_argv_free (argv);
return false;
case '\0':
r_meta_list (core->anal, R_META_TYPE_HIGHLIGHT, 0);
r_meta_print_list_all (core->anal, R_META_TYPE_HIGHLIGHT, 0);
r_str_argv_free (argv);
return false;
case 'j':
r_meta_list (core->anal, R_META_TYPE_HIGHLIGHT, 'j');
r_meta_print_list_all (core->anal, R_META_TYPE_HIGHLIGHT, 'j');
r_str_argv_free (argv);
return false;
case '*':
r_meta_list (core->anal, R_META_TYPE_HIGHLIGHT, '*');
r_meta_print_list_all (core->anal, R_META_TYPE_HIGHLIGHT, '*');
r_str_argv_free (argv);
return false;
case ' ':
@ -526,7 +526,7 @@ static int cmd_eval(void *data, const char *input) {
return true;
}
r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, "");
char *str = r_meta_get_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset);
const char *str = r_meta_get_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset);
char *dup = r_str_newf ("%s \"%s%s\"", str?str:"", word?word:"", color_code?color_code:r_cons_singleton ()->context->pal.wordhl);
r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, dup);
r_str_argv_free (argv);

View File

@ -350,7 +350,7 @@ static int cmd_meta_comment(RCore *core, const char *input) {
eprintf ("Usage: CC, [file]\n");
} else if (input[2] == ' ') {
const char *fn = input+2;
char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
while (*fn== ' ')fn++;
if (comment && *comment) {
// append filename in current comment
@ -358,12 +358,12 @@ static int cmd_meta_comment(RCore *core, const char *input) {
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc);
free (nc);
} else {
char *comment = r_str_newf (",(%s)", fn);
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, comment);
free (comment);
char *newcomment = r_str_newf (",(%s)", fn);
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, newcomment);
free (newcomment);
}
} else {
char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
if (comment && *comment) {
char *cmtfile = r_str_between (comment, ",(", ")");
if (cmtfile && *cmtfile) {
@ -373,22 +373,19 @@ static int cmd_meta_comment(RCore *core, const char *input) {
}
free (cmtfile);
}
free (comment);
}
break;
case '.':
{
ut64 at = input[2]? r_num_math (core->num, input + 2): addr;
char *comment = r_meta_get_string (
core->anal, R_META_TYPE_COMMENT, at);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, at);
if (comment) {
r_cons_println (comment);
free (comment);
}
}
break;
case 0: // "CC"
r_meta_list (core->anal, R_META_TYPE_COMMENT, 0);
r_meta_print_list_all (core->anal, R_META_TYPE_COMMENT, 0);
break;
case 'f': // "CCf"
switch (input[2]) {
@ -413,50 +410,49 @@ static int cmd_meta_comment(RCore *core, const char *input) {
}
break;
case 'j': // "CCfj"
r_meta_list_at (core->anal, R_META_TYPE_COMMENT, 'j', core->offset);
r_meta_print_list_in_function (core->anal, R_META_TYPE_COMMENT, 'j', core->offset);
break;
case '*': // "CCf*"
r_meta_list_at (core->anal, R_META_TYPE_COMMENT, 1, core->offset);
r_meta_print_list_in_function (core->anal, R_META_TYPE_COMMENT, 1, core->offset);
break;
default:
r_meta_list_at (core->anal, R_META_TYPE_COMMENT, 0, core->offset);
r_meta_print_list_in_function (core->anal, R_META_TYPE_COMMENT, 0, core->offset);
break;
}
break;
case 'j': // "CCj"
r_meta_list (core->anal, R_META_TYPE_COMMENT, 'j');
r_meta_print_list_all (core->anal, R_META_TYPE_COMMENT, 'j');
break;
case '!':
{
char *out, *comment = r_meta_get_string (
core->anal, R_META_TYPE_COMMENT, addr);
char *out;
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
out = r_core_editor (core, NULL, comment);
if (out) {
//r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
//r_meta_set (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr);
//r_meta_del (core->anal->meta, input[0], addr, addr+1);
r_meta_set_string (core->anal,
R_META_TYPE_COMMENT, addr, out);
free (out);
}
free (comment);
}
break;
case '+':
case ' ':
{
const char* newcomment = r_str_trim_head_ro (input + 2);
char *text, *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
const char *newcomment = r_str_trim_head_ro (input + 2);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
char *text;
char *nc = strdup (newcomment);
r_str_unescape (nc);
if (comment) {
text = malloc (strlen (comment)+ strlen (newcomment)+2);
text = malloc (strlen (comment) + strlen (newcomment) + 2);
if (text) {
strcpy (text, comment);
strcat (text, " ");
strcat (text, nc);
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, text);
free (comment);
free (text);
} else {
r_sys_perror ("malloc");
@ -468,7 +464,7 @@ static int cmd_meta_comment(RCore *core, const char *input) {
}
break;
case '*': // "CC*"
r_meta_list (core->anal, R_META_TYPE_COMMENT, 1);
r_meta_print_list_all (core->anal, R_META_TYPE_COMMENT, 1);
break;
case '-': // "CC-"
if (input[2] == '*') { // "CC-*"
@ -497,13 +493,10 @@ static int cmd_meta_comment(RCore *core, const char *input) {
newcomment = strdup (arg);
}
if (newcomment) {
char *comment = r_meta_get_string (
core->anal, R_META_TYPE_COMMENT, addr);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
if (!comment || (comment && !strstr (comment, newcomment))) {
r_meta_set_string (core->anal, R_META_TYPE_COMMENT,
addr, newcomment);
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, newcomment);
}
free (comment);
free (newcomment);
}
}
@ -537,24 +530,16 @@ static int cmd_meta_comment(RCore *core, const char *input) {
// Comment at
if (p) {
if (input[2]=='+') {
char *comment = r_meta_get_string (
core->anal, R_META_TYPE_COMMENT,
addr);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
if (comment) {
char* text = r_str_newf ("%s\n%s", comment, p);
r_meta_add (core->anal,
R_META_TYPE_COMMENT,
addr, addr+1, text);
char *text = r_str_newf ("%s\n%s", comment, p);
r_meta_set (core->anal, R_META_TYPE_COMMENT, addr, 1, text);
free (text);
} else {
r_meta_add (core->anal,
R_META_TYPE_COMMENT,
addr, addr+1, p);
r_meta_set (core->anal, R_META_TYPE_COMMENT, addr, 1, p);
}
} else {
r_meta_add (core->anal,
R_META_TYPE_COMMENT,
addr, addr + 1, p);
r_meta_set (core->anal, R_META_TYPE_COMMENT, addr, 1, p);
}
} else {
eprintf ("Usage: CCa [address] [comment]\n");
@ -573,22 +558,18 @@ static int cmd_meta_vartype_comment(RCore *core, const char *input) {
r_core_cmd_help (core, help_msg_Ct);
break;
case 0: // "Ct"
r_meta_list (core->anal, R_META_TYPE_VARTYPE, 0);
r_meta_print_list_all (core->anal, R_META_TYPE_VARTYPE, 0);
break;
case ' ': // "Ct <vartype comment> @ addr"
{
const char* newcomment = r_str_trim_head_ro (input + 2);
char *text, *comment = r_meta_get_string (core->anal, R_META_TYPE_VARTYPE, addr);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_VARTYPE, addr);
char *nc = strdup (newcomment);
r_str_unescape (nc);
if (comment) {
text = malloc (strlen (comment)+ strlen (newcomment)+2);
char *text = r_str_newf ("%s %s", comment, nc);
if (text) {
strcpy (text, comment);
strcat (text, " ");
strcat (text, nc);
r_meta_set_string (core->anal, R_META_TYPE_VARTYPE, addr, text);
free (comment);
free (text);
} else {
r_sys_perror ("malloc");
@ -602,11 +583,9 @@ static int cmd_meta_vartype_comment(RCore *core, const char *input) {
case '.': // "Ct. @ addr"
{
ut64 at = input[2]? r_num_math (core->num, input + 2): addr;
char *comment = r_meta_get_string (
core->anal, R_META_TYPE_VARTYPE, at);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_VARTYPE, at);
if (comment) {
r_cons_println (comment);
free (comment);
}
}
break;
@ -625,7 +604,7 @@ static int cmd_meta_others(RCore *core, const char *input) {
int n, type = input[0], subtype;
char *t = 0, *p, *p2, name[256];
int repeat = 1;
ut64 addr_end = 0LL, addr = core->offset;
ut64 addr = core->offset;
switch (input[1]) {
case '?':
@ -651,8 +630,7 @@ static int cmd_meta_others(RCore *core, const char *input) {
case '-': // "Cf-", "Cd-", ...
switch (input[2]) {
case '*': // "Cf-*", "Cd-*", ...
core->num->value = r_meta_del (core->anal,
input[0], 0, UT64_MAX);
r_meta_del (core->anal, input[0], 0, UT64_MAX);
break;
case ' ':
p2 = strchr (input + 3, ' ');
@ -665,7 +643,7 @@ static int cmd_meta_others(RCore *core, const char *input) {
break;
}
for (i = 0; i < rep && UT64_MAX - cur_addr > size; i++, cur_addr += size) {
core->num->value = r_meta_del (core->anal, input[0], cur_addr, size);
r_meta_del (core->anal, input[0], cur_addr, size);
}
break;
} else {
@ -673,75 +651,60 @@ static int cmd_meta_others(RCore *core, const char *input) {
/* fallthrough */
}
default:
core->num->value = r_meta_del (core->anal,
input[0], addr, 1);
r_meta_del (core->anal, input[0], addr, 1);
break;
}
break;
case '*': // "Cf*", "Cd*", ...
r_meta_list (core->anal, input[0], 1);
r_meta_print_list_all (core->anal, input[0], 1);
break;
case 'j': // "Cfj", "Cdj", ...
r_meta_list (core->anal, input[0], 'j');
r_meta_print_list_all (core->anal, input[0], 'j');
break;
case '!': // "Cf!", "Cd!", ...
{
char *out, *comment = r_meta_get_string (
core->anal, R_META_TYPE_COMMENT, addr);
char *out;
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
out = r_core_editor (core, NULL, comment);
if (out) {
//r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
//r_meta_set (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr);
//r_meta_del (core->anal->meta, input[0], addr, addr+1);
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, out);
free (out);
}
free (comment);
}
break;
case '.': // "Cf.", "Cd.", ...
if (input[2] == '.') { // "Cs.."
RAnalMetaItem *mi = r_meta_find (core->anal, addr, type, R_META_WHERE_HERE);
ut64 size;
RAnalMetaItem *mi = r_meta_get_at (core->anal, addr, type, &size);
if (mi) {
r_meta_print (core->anal, mi, input[3], NULL, false);
r_meta_item_free (mi);
r_meta_print (core->anal, mi, addr, size, input[3], NULL, false);
}
break;
} else if (input[2] == 'j') { // "Cs.j"
RAnalMetaItem *mi = r_meta_find (core->anal, addr, type, R_META_WHERE_HERE);
ut64 size;
RAnalMetaItem *mi = r_meta_get_at (core->anal, addr, type, &size);
if (mi) {
r_meta_print (core->anal, mi, input[2], NULL, false);
r_meta_print (core->anal, mi, addr, size, input[2], NULL, false);
r_cons_newline ();
r_meta_item_free (mi);
}
break;
}
char key[100];
const char *val;
RAnalMetaItem mi;
Sdb *s = core->anal->sdb_meta;
bool esc_bslash = core->print->esc_bslash;
snprintf (key, sizeof (key), "meta.%c.0x%" PFMT64x, type, addr);
val = sdb_const_get (s, key, 0);
if (!val) {
break;
}
if (!r_meta_deserialize_val (core->anal, &mi, type, addr, val)) {
break;
}
if (!mi.str) {
break;
}
ut64 size;
RAnalMetaItem *mi = r_meta_get_at (core->anal, addr, type, &size);
if (type == 's') {
char *esc_str;
switch (mi.subtype) {
bool esc_bslash = core->print->esc_bslash;
switch (mi->subtype) {
case R_STRING_ENC_UTF8:
esc_str = r_str_escape_utf8 (mi.str, false, esc_bslash);
esc_str = r_str_escape_utf8 (mi->str, false, esc_bslash);
break;
case 0: /* temporary legacy workaround */
esc_bslash = false;
default:
esc_str = r_str_escape_latin1 (mi.str, false, esc_bslash, false);
esc_str = r_str_escape_latin1 (mi->str, false, esc_bslash, false);
}
if (esc_str) {
r_cons_printf ("\"%s\"\n", esc_str);
@ -750,11 +713,10 @@ static int cmd_meta_others(RCore *core, const char *input) {
r_cons_println ("<oom>");
}
} else if (type == 'd') {
r_cons_printf ("%"PFMT64u"\n", mi.size);
r_cons_printf ("%"PFMT64u"\n", size);
} else {
r_cons_println (mi.str);
r_cons_println (mi->str);
}
free (mi.str);
break;
case ' ': // "Cf", "Cd", ...
case '\0':
@ -762,7 +724,7 @@ static int cmd_meta_others(RCore *core, const char *input) {
case 'a':
case '8':
if (type != 'z' && !input[1] && !core->tmpseek) {
r_meta_list (core->anal, type, 0);
r_meta_print_list_all (core->anal, type, 0);
break;
}
if (type == 'z') {
@ -884,7 +846,6 @@ static int cmd_meta_others(RCore *core, const char *input) {
if (!n) {
n++;
}
addr_end = addr + n;
if (type == 's') {
switch (input[1]) {
case 'a':
@ -894,13 +855,13 @@ static int cmd_meta_others(RCore *core, const char *input) {
default:
subtype = R_STRING_ENC_GUESS;
}
r_meta_add_with_subtype (core->anal, type, subtype, addr, addr_end, name);
r_meta_set_with_subtype (core->anal, type, subtype, addr, n, name);
} else {
r_meta_add (core->anal, type, addr, addr_end, name);
r_meta_set (core->anal, type, addr, n, name);
}
free (t);
repcnt ++;
addr = addr_end;
addr += n;
}
//r_meta_cleanup (core->anal->meta, 0LL, UT64_MAX);
break;
@ -1045,19 +1006,19 @@ static int cmd_meta(void *data, const char *input) {
r_comment_vars (core, input + 1);
break;
case '\0': // "C"
r_meta_list (core->anal, R_META_TYPE_ANY, 0);
r_meta_print_list_all (core->anal, R_META_TYPE_ANY, 0);
break;
case 'j': // "Cj"
case '*': { // "C*"
if (!input[0] || input[1] == '.') {
r_meta_list_offset (core->anal, core->offset, *input);
r_meta_print_list_at (core->anal, core->offset, *input);
} else {
r_meta_list (core->anal, R_META_TYPE_ANY, *input);
r_meta_print_list_all (core->anal, R_META_TYPE_ANY, *input);
}
break;
}
case '.': { // "C."
r_meta_list_offset (core->anal, core->offset, 0);
r_meta_print_list_at (core->anal, core->offset, 0);
break;
}
case 'L': // "CL"
@ -1082,7 +1043,9 @@ static int cmd_meta(void *data, const char *input) {
if (input[1] != '*') {
i = input[1] ? r_num_math (core->num, input + (input[1] == ' ' ? 2 : 1)) : 1;
r_meta_del (core->anal, R_META_TYPE_ANY, core->offset, i);
} else r_meta_cleanup (core->anal, 0LL, UT64_MAX);
} else {
r_meta_del (core->anal, R_META_TYPE_ANY, 0, UT64_MAX);
}
break;
case '?': // "C?"
r_core_cmd_help (core, help_msg_C);

View File

@ -1019,14 +1019,7 @@ static void __rebase_everything(RCore *core, RList *old_sections, ut64 old_base)
r_flag_foreach (core->flags, __rebase_flags, &reb);
// META
RList *meta_list = r_meta_enumerate (core->anal, R_META_TYPE_ANY);
RAnalMetaItem *item;
r_list_foreach (meta_list, it, item) {
r_meta_del (core->anal, item->type, item->from, item->size);
item->from += diff;
r_meta_add_with_subtype (core->anal, item->type, item->subtype, item->from, item->from + item->size, item->str);
}
r_list_free (meta_list);
r_meta_rebase (core->anal, diff);
// REFS
HtUP *old_refs = core->anal->dict_refs;

View File

@ -1628,7 +1628,6 @@ static void annotated_hexdump(RCore *core, const char *str, int len) {
char *bytes, *chars;
char *ebytes, *echars; // They'll walk over the vars above
ut64 fend = UT64_MAX;
char *comment;
int i, j, low, max, here, rows;
bool marks = false, setcolor = true, hascolor = false;
ut8 ch = 0;
@ -1737,25 +1736,23 @@ static void annotated_hexdump(RCore *core, const char *str, int len) {
R_FREE (note[j]);
// TODO: in pava mode we should read addr or ea? // imho ea. but wat about hdrs and such
RAnalMetaItem *meta = r_meta_find_in (core->anal, ea + j,
R_META_TYPE_FORMAT, R_META_WHERE_HERE);
if (meta && meta->type == R_META_TYPE_FORMAT && meta->from == addr + j) {
RIntervalNode *meta_node = r_meta_get_in (core->anal, ea + j, R_META_TYPE_FORMAT);
RAnalMetaItem *meta = meta_node ? meta_node->data : NULL;
if (meta && meta->type == R_META_TYPE_FORMAT && meta_node->start == addr + j) {
r_cons_printf (".format %s ; size=", meta->str);
r_core_cmdf (core, "pfs %s", meta->str);
r_core_cmdf (core, "pf %s @ 0x%08"PFMT64x, meta->str, meta->from);
r_core_cmdf (core, "pf %s @ 0x%08"PFMT64x, meta->str, meta_node->start);
append (ebytes, Color_INVERT);
append (echars, Color_INVERT);
hadflag = true;
}
if (meta) {
r_meta_item_free (meta);
meta = NULL;
}
// collect comments
comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr + j);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr + j);
if (comment) {
comment = r_str_prepend (comment, ";");
note[j] = comment;
note[j] = r_str_newf (";", comment);
marks = true;
}
@ -1767,6 +1764,7 @@ static void annotated_hexdump(RCore *core, const char *str, int len) {
} else {
fend = addr + j + flag->size;
}
free (note[j]);
note[j] = r_str_prepend (strdup (flag->name), "/");
marks = true;
color_idx++;
@ -4652,7 +4650,7 @@ static void r_core_disasm_table(RCore * core, int l, const char *input) {
ea += minopsz;
continue;
}
char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ea);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ea);
// TODO parse/filter op->mnemonic for better disasm
ut8 *bytes = malloc (op->size);
if (!bytes) {
@ -4666,7 +4664,6 @@ static void r_core_disasm_table(RCore * core, int l, const char *input) {
char *refs = __op_refs (core, op, 0);
char *xrefs = __op_refs (core, op, 1);
r_table_add_rowf (t, "sXssssss", fn, ea, sbytes, op->mnemonic, comment? comment: "", esil, refs, xrefs);
free (comment);
free (sbytes);
free (bytes);
free (xrefs);

View File

@ -1245,8 +1245,7 @@ static void print_rop(RCore *core, RList *hitlist, char mode, bool *json_first)
default:
// Print gadgets with new instruction on a new line.
r_list_foreach (hitlist, iter, hit) {
char *comment = rop_comments? r_meta_get_string (core->anal,
R_META_TYPE_COMMENT, hit->addr): NULL;
const char *comment = rop_comments? r_meta_get_string (core->anal, R_META_TYPE_COMMENT, hit->addr): NULL;
if (hit->len < 0) {
eprintf ("Invalid hit length here\n");
continue;
@ -1907,7 +1906,6 @@ beach:
static void do_ref_search(RCore *core, ut64 addr,ut64 from, ut64 to, struct search_parameters *param) {
const int size = 12;
char str[512];
char *comment;
RAnalFunction *fcn;
RAnalRef *ref;
RListIter *iter;
@ -1924,10 +1922,16 @@ static void do_ref_search(RCore *core, ut64 addr,ut64 from, ut64 to, struct sear
r_parse_filter (core->parser, ref->addr, core->flags, hint, r_strbuf_get (&asmop.buf_asm),
str, sizeof (str), core->print->big_endian);
r_anal_hint_free (hint);
comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ref->addr);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ref->addr);
char *print_comment = NULL;
const char *nl = comment ? strchr (comment, '\n') : NULL;
if (nl) { // display only until the first newline
comment = print_comment = r_str_ndup (comment, nl - comment);
}
char *buf_fcn = comment
? r_str_newf ("%s; %s", fcn ? fcn->name : "(nofunc)", strtok (comment, "\n"))
? r_str_newf ("%s; %s", fcn ? fcn->name : "(nofunc)", comment)
: r_str_newf ("%s", fcn ? fcn->name : "(nofunc)");
free (print_comment);
if (from <= ref->addr && to >= ref->addr) {
r_cons_printf ("%s 0x%" PFMT64x " [%s] %s\n",
buf_fcn, ref->addr, r_anal_xrefs_type_tostring (ref->type), str);

View File

@ -380,66 +380,23 @@ static int cmd_seek(void *data, const char *input) {
if (input[1] == '*') { // "sC*"
r_core_cmd0 (core, "C*~^\"CC");
} else if (input[1] == ' ') {
typedef struct {
ut64 addr;
char *str;
} MetaCallback;
int count = 0;
MetaCallback cb = {
0, NULL
};
ut64 addr;
char key[128];
const char *val, *comma;
char *list = sdb_get (core->anal->sdb_meta, "meta.C", 0);
char *str, *next, *cur = list;
if (list) {
for (;;) {
cur = sdb_anext (cur, &next);
addr = sdb_atoi (cur);
snprintf (key, sizeof (key) - 1, "meta.C.0x%"PFMT64x, addr);
val = sdb_const_get (core->anal->sdb_meta, key, 0);
if (val) {
comma = strchr (val, ',');
if (comma) {
str = (char *) sdb_decode (comma + 1, 0);
if (strstr (str, input + 2)) {
r_cons_printf ("0x%08"PFMT64x " %s\n", addr, str);
count++;
cb.addr = addr;
free (cb.str);
cb.str = str;
} else {
free (str);
}
}
} else {
eprintf ("sdb_const_get key not found '%s'\n", key);
RIntervalTreeIter it;
RAnalMetaItem *meta;
bool seeked = false;
r_interval_tree_foreach (&core->anal->meta, it, meta) {
if (meta->type == R_META_TYPE_COMMENT && !strcmp (meta->str, input + 2)) {
if (!silent) {
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
}
if (!next) {
break;
}
cur = next;
r_core_seek (core, off, true);
r_core_block_read (core);
seeked = true;
break;
}
}
switch (count) {
case 0:
eprintf ("No matching comments\n");
break;
case 1:
off = cb.addr;
if (!silent) {
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
}
r_core_seek (core, off, true);
r_core_block_read (core);
break;
default:
eprintf ("Too many results\n");
break;
if (!seeked) {
eprintf ("No matching comment.\n");
}
free (cb.str);
} else {
r_core_cmd_help (core, help_msg_sC);
}

View File

@ -2232,17 +2232,14 @@ static char *r_core_anal_hasrefs_to_depth(RCore *core, ut64 value, int depth) {
R_API char *r_core_anal_get_comments(RCore *core, ut64 addr) {
if (core) {
char *type = r_meta_get_string (core->anal, R_META_TYPE_VARTYPE, addr);
char *cmt = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
const char *type = r_meta_get_string (core->anal, R_META_TYPE_VARTYPE, addr);
const char *cmt = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
if (type && cmt) {
char *ret = r_str_newf ("%s %s", type, cmt);
free (type);
free (cmt);
return ret;
return r_str_newf ("%s %s", type, cmt);
} else if (type) {
return type;
return strdup (type);
} else if (cmt) {
return cmt;
return strdup (cmt);
}
}
return NULL;

View File

@ -895,9 +895,8 @@ static void ds_free(RDisasmState *ds) {
/* XXX move to r_print */
static char *colorize_asm_string(RCore *core, RDisasmState *ds, bool print_color) {
char *source = ds->opstr? ds->opstr: r_asm_op_get_asm (&ds->asmop);
char *hlstr = r_meta_get_string (ds->core->anal, R_META_TYPE_HIGHLIGHT, ds->at);
const char *hlstr = r_meta_get_string (ds->core->anal, R_META_TYPE_HIGHLIGHT, ds->at);
bool partial_reset = line_highlighted (ds) ? true : ((hlstr && *hlstr) ? true : false);
free (hlstr);
RAnalFunction *f = ds->show_color_args ? fcnIn (ds, ds->vat, R_ANAL_FCN_TYPE_NULL) : NULL;
if (!ds->show_color || !ds->colorop) {
@ -1118,7 +1117,7 @@ static void ds_build_op_str(RDisasmState *ds, bool print_color) {
int i = 0;
char *word = NULL;
char *bgcolor = NULL;
char *wcdata = r_meta_get_string (ds->core->anal, R_META_TYPE_HIGHLIGHT, ds->at);
const char *wcdata = r_meta_get_string (ds->core->anal, R_META_TYPE_HIGHLIGHT, ds->at);
int argc = 0;
char **wc_array = r_str_argv (wcdata, &argc);
for (i = 0; i < argc; i++) {
@ -1239,7 +1238,7 @@ static void ds_show_refs(RDisasmState *ds) {
RList *list = r_anal_xrefs_get_from (ds->core->anal, ds->at);
r_list_foreach (list, iter, ref) {
char *cmt = r_meta_get_string (ds->core->anal, R_META_TYPE_COMMENT, ref->addr);
const char *cmt = r_meta_get_string (ds->core->anal, R_META_TYPE_COMMENT, ref->addr);
const RList *fls = r_flag_get_list (ds->core->flags, ref->addr);
RListIter *iter2;
RFlagItem *fis;
@ -1255,7 +1254,6 @@ static void ds_show_refs(RDisasmState *ds) {
if (cmt) {
ds_begin_comment (ds);
ds_comment (ds, true, "; (%s)", cmt);
free (cmt);
}
if (ref->type & R_ANAL_REF_TYPE_CALL) {
RAnalOp aop;
@ -2090,23 +2088,19 @@ static void ds_show_comments_right(RDisasmState *ds) {
return;
}
RFlagItem *item = r_flag_get_i (core->flags, ds->at);
char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ds->at);
char *vartype = r_meta_get_string (core->anal, R_META_TYPE_VARTYPE, ds->at);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ds->at);
const char *vartype = r_meta_get_string (core->anal, R_META_TYPE_VARTYPE, ds->at);
if (!comment) {
if (vartype) {
ds->comment = r_str_newf ("%s; %s", COLOR_ARG (ds, color_func_var_type), vartype);
free (vartype);
} else if (item && item->comment && *item->comment) {
ds->ocomment = item->comment;
ds->comment = strdup (item->comment);
}
} else if (vartype) {
ds->comment = r_str_newf ("%s; %s %s%s; %s", COLOR_ARG (ds, color_func_var_type), vartype, Color_RESET, COLOR (ds, color_usrcmt), comment);
free (vartype);
free (comment);
} else {
ds->comment = r_str_newf ("%s; %s", COLOR_ARG (ds, color_usrcmt), comment);
free (comment);
}
if (!ds->comment || !*ds->comment) {
return;
@ -2405,30 +2399,31 @@ static void ds_update_ref_lines(RDisasmState *ds) {
static int ds_disassemble(RDisasmState *ds, ut8 *buf, int len) {
RCore *core = ds->core;
int ret;
const char *info;
Sdb *s = core->anal->sdb_meta;
char key[100];
ut64 mt_sz = UT64_MAX;
//handle meta info to fix ds->oplen
snprintf (key, sizeof (key) - 1, "meta.0x%"PFMT64x, ds->at);
info = sdb_const_get (s, key, 0);
if (info) {
for (;*info; info++) {
switch (*info) {
// find the meta item at this offset if any
RPVector *metas = r_meta_get_all_at (ds->core->anal, ds->at); // TODO: do in range
RAnalMetaItem *meta = NULL;
ut64 meta_size = UT64_MAX;
if (metas) {
void **it;
r_pvector_foreach (metas, it) {
RIntervalNode *node = *it;
RAnalMetaItem *mi = node->data;
switch (mi->type) {
case R_META_TYPE_DATA:
case R_META_TYPE_STRING:
case R_META_TYPE_FORMAT:
case R_META_TYPE_MAGIC:
case R_META_TYPE_HIDE:
snprintf (key, sizeof (key) - 1,
"meta.%c.0x%"PFMT64x, *info, ds->at);
sdb_const_get (s, key, 0);
mt_sz = sdb_array_get_num (s, key, 0, 0);
//if (mt_sz) { break; }
case R_META_TYPE_RUN:
meta = mi;
meta_size = r_meta_item_size (node->start, node->end);
break;
default:
break;
}
}
r_pvector_free (metas);
}
if (ds->hint && ds->hint->bits) {
if (!ds->core->anal->opt.ignbithints) {
@ -2450,33 +2445,33 @@ static int ds_disassemble(RDisasmState *ds, ut8 *buf, int len) {
// handle meta here //
if (!ds->asm_meta) {
int i = 0;
// TODO: do in range
RAnalMetaItem *meta = r_meta_find_in (core->anal, ds->at, R_META_TYPE_ANY, R_META_WHERE_HERE);
if (meta && meta->size > 0) {
if (meta && meta_size > 0 && meta->type != R_META_TYPE_HIDE) {
// XXX this is just noise. should be rewritten
switch (meta->type) {
case R_META_TYPE_DATA:
if (meta->str) {
r_cons_printf (".data: %s\n", meta->str);
}
i += meta->size;
i += meta_size;
break;
case R_META_TYPE_STRING:
i += meta->size;
i += meta_size;
break;
case R_META_TYPE_FORMAT:
r_cons_printf (".format : %s\n", meta->str);
i += meta->size;
i += meta_size;
break;
case R_META_TYPE_MAGIC:
r_cons_printf (".magic : %s\n", meta->str);
i += meta->size;
i += meta_size;
break;
case R_META_TYPE_RUN:
r_core_cmd0 (core, meta->str);
break;
default:
break;
}
int sz = R_MIN (16, meta->size - (ds->at - meta->from));
int sz = R_MIN (16, meta_size);
ds->asmop.size = sz;
r_asm_op_set_hexbuf (&ds->asmop, buf, sz);
switch (meta->type) {
@ -2495,9 +2490,6 @@ static int ds_disassemble(RDisasmState *ds, ut8 *buf, int len) {
ds->oplen = sz; //ds->asmop.size;
return i;
}
if (meta) {
r_meta_item_free (meta);
}
}
if (ds->show_nodup) {
@ -2557,8 +2549,8 @@ static int ds_disassemble(RDisasmState *ds, ut8 *buf, int len) {
char *ba = r_asm_op_get_asm (&ds->asmop);
*ba = toupper ((ut8)*ba);
}
if (info && mt_sz != UT64_MAX) {
ds->oplen = mt_sz;
if (meta && meta_size != UT64_MAX) {
ds->oplen = meta_size;
}
return ret;
}
@ -2934,9 +2926,8 @@ static bool ds_print_data_type(RDisasmState *ds, const ut8 *buf, int ib, int siz
static bool ds_print_meta_infos(RDisasmState *ds, ut8* buf, int len, int idx, int *mi_type) {
bool ret = false;
RAnalMetaItem *mi, *fmi;
RAnalMetaItem *fmi;
RCore *core = ds->core;
RListIter *iter;
if (!ds->asm_meta) {
return false;
}
@ -2947,132 +2938,143 @@ static bool ds_print_meta_infos(RDisasmState *ds, ut8* buf, int len, int idx, in
snprintf (key, sizeof (key), "meta.0x%" PFMT64x, ds->at);
const char *infos = sdb_const_get (s, key, 0);
#endif
RList *list = r_meta_find_list_in (core->anal, ds->at, R_META_TYPE_ANY, R_META_WHERE_HERE);
if (list) {
bool once = true;
fmi = NULL;
r_list_foreach (list, iter, mi) {
switch (mi->type) {
case R_META_TYPE_DATA:
if (once) {
if (ds->asm_hint_pos == 0) {
if (ds->asm_hint_lea) {
ds_print_shortcut (ds, mi->from, 0);
} else {
r_cons_strcat (" ");
}
}
once = false;
}
break;
case R_META_TYPE_STRING:
fmi = mi;
break;
}
}
r_list_foreach (list, iter, mi) {
char *out = NULL;
int hexlen;
int delta;
if (fmi && mi != fmi) {
continue;
}
if (mi_type) {
*mi_type = mi->type;
}
switch (mi->type) {
case R_META_TYPE_STRING:
if (mi->str) {
bool esc_bslash = core->print->esc_bslash;
switch (mi->subtype) {
case R_STRING_ENC_UTF8:
out = r_str_escape_utf8 (mi->str, false, esc_bslash);
break;
case 0: /* temporary legacy workaround */
esc_bslash = false;
/* fallthrough */
default:
out = r_str_escape_latin1 (mi->str, false, esc_bslash, false);
}
if (!out) {
break;
}
r_cons_printf (" .string %s\"%s\"%s ; len=%"PFMT64d,
COLOR (ds, color_btext), out, COLOR_RESET (ds),
mi->size);
free (out);
delta = ds->at - mi->from;
ds->oplen = mi->size - delta;
ds->asmop.size = (int)mi->size;
//i += mi->size-1; // wtf?
R_FREE (ds->line);
R_FREE (ds->line_col);
R_FREE (ds->refline);
R_FREE (ds->refline2);
R_FREE (ds->prev_line_col);
ret = true;
break;
}
case R_META_TYPE_HIDE:
r_cons_printf ("(%"PFMT64d" bytes hidden)", mi->size);
ds->asmop.size = mi->size;
ds->oplen = mi->size;
ret = true;
break;
case R_META_TYPE_RUN:
r_core_cmdf (core, "%s @ 0x%"PFMT64x, mi->str, ds->at);
ds->asmop.size = mi->size;
ds->oplen = mi->size;
ret = true;
break;
case R_META_TYPE_DATA:
hexlen = len - idx;
delta = ds->at - mi->from;
if (mi->size < hexlen) {
hexlen = mi->size;
}
ds->oplen = mi->size - delta;
core->print->flags &= ~R_PRINT_FLAGS_HEADER;
// TODO do not pass a copy in parameter buf that is possibly to small for this
// print operation
int size = R_MIN (mi->size, len - idx);
if (!ds_print_data_type (ds, buf + idx, ds->hint? ds->hint->immbase: 0, size)) {
r_cons_printf ("hex length=%" PFMT64d " delta=%d\n", size , delta);
r_print_hexdump (core->print, ds->at, buf+idx, hexlen-delta, 16, 1, 1);
}
core->print->flags |= R_PRINT_FLAGS_HEADER;
ds->asmop.size = (int)mi->size;
R_FREE (ds->line);
R_FREE (ds->line_col);
R_FREE (ds->refline);
R_FREE (ds->refline2);
R_FREE (ds->prev_line_col);
ret = true;
break;
case R_META_TYPE_FORMAT:
{
r_cons_printf ("pf %s # size=%d\n", mi->str, mi->size);
int len_before = r_cons_get_buffer_len ();
r_print_format (core->print, ds->at, buf + idx,
len - idx, mi->str, R_PRINT_MUSTSEE, NULL, NULL);
int len_after = r_cons_get_buffer_len ();
const char *cons_buf = r_cons_get_buffer ();
if (len_after > len_before && buf && cons_buf[len_after - 1] == '\n') {
r_cons_drop (1);
}
ds->oplen = ds->asmop.size = (int)mi->size;
R_FREE (ds->line);
R_FREE (ds->refline);
R_FREE (ds->refline2);
R_FREE (ds->prev_line_col);
ret = true;
}
break;
}
}
r_list_free (list);
RPVector *metas = r_meta_get_all_in (core->anal, ds->at, R_META_TYPE_ANY);
if (!metas) {
return false;
}
bool once = true;
fmi = NULL;
void **it;
r_pvector_foreach (metas, it) {
RIntervalNode *node = *it;
RAnalMetaItem *mi = node->data;
switch (mi->type) {
case R_META_TYPE_DATA:
if (once) {
if (ds->asm_hint_pos == 0) {
if (ds->asm_hint_lea) {
ds_print_shortcut (ds, node->start, 0);
} else {
r_cons_strcat (" ");
}
}
once = false;
}
break;
case R_META_TYPE_STRING:
fmi = mi;
break;
default:
break;
}
}
r_pvector_foreach (metas, it) {
RIntervalNode *node = *it;
RAnalMetaItem *mi = node->data;
ut64 mi_size = r_meta_node_size (node);
char *out = NULL;
int hexlen;
int delta;
if (fmi && mi != fmi) {
continue;
}
if (mi_type) {
*mi_type = mi->type;
}
switch (mi->type) {
case R_META_TYPE_STRING:
if (mi->str) {
bool esc_bslash = core->print->esc_bslash;
switch (mi->subtype) {
case R_STRING_ENC_UTF8:
out = r_str_escape_utf8 (mi->str, false, esc_bslash);
break;
case 0: /* temporary legacy workaround */
esc_bslash = false;
/* fallthrough */
default:
out = r_str_escape_latin1 (mi->str, false, esc_bslash, false);
}
if (!out) {
break;
}
r_cons_printf (" .string %s\"%s\"%s ; len=%"PFMT64d,
COLOR (ds, color_btext), out, COLOR_RESET (ds),
mi_size);
free (out);
delta = ds->at - node->start;
ds->oplen = mi_size - delta;
ds->asmop.size = (int)mi_size;
//i += mi->size-1; // wtf?
R_FREE (ds->line);
R_FREE (ds->line_col);
R_FREE (ds->refline);
R_FREE (ds->refline2);
R_FREE (ds->prev_line_col);
ret = true;
break;
}
case R_META_TYPE_HIDE:
r_cons_printf ("(%"PFMT64d" bytes hidden)", mi_size);
ds->asmop.size = mi_size;
ds->oplen = mi_size;
ret = true;
break;
case R_META_TYPE_RUN:
r_core_cmdf (core, "%s @ 0x%"PFMT64x, mi->str, ds->at);
ds->asmop.size = mi_size;
ds->oplen = mi_size;
ret = true;
break;
case R_META_TYPE_DATA:
hexlen = len - idx;
delta = ds->at - node->start;
if (mi_size < hexlen) {
hexlen = mi_size;
}
ds->oplen = mi_size - delta;
core->print->flags &= ~R_PRINT_FLAGS_HEADER;
// TODO do not pass a copy in parameter buf that is possibly to small for this
// print operation
int size = R_MIN (mi_size, len - idx);
if (!ds_print_data_type (ds, buf + idx, ds->hint? ds->hint->immbase: 0, size)) {
r_cons_printf ("hex length=%" PFMT64d " delta=%d\n", size , delta);
r_print_hexdump (core->print, ds->at, buf+idx, hexlen-delta, 16, 1, 1);
}
core->print->flags |= R_PRINT_FLAGS_HEADER;
ds->asmop.size = (int)mi_size;
R_FREE (ds->line);
R_FREE (ds->line_col);
R_FREE (ds->refline);
R_FREE (ds->refline2);
R_FREE (ds->prev_line_col);
ret = true;
break;
case R_META_TYPE_FORMAT:
{
r_cons_printf ("pf %s # size=%d\n", mi->str, mi_size);
int len_before = r_cons_get_buffer_len ();
r_print_format (core->print, ds->at, buf + idx,
len - idx, mi->str, R_PRINT_MUSTSEE, NULL, NULL);
int len_after = r_cons_get_buffer_len ();
const char *cons_buf = r_cons_get_buffer ();
if (len_after > len_before && buf && cons_buf[len_after - 1] == '\n') {
r_cons_drop (1);
}
ds->oplen = ds->asmop.size = (int)mi_size;
R_FREE (ds->line);
R_FREE (ds->refline);
R_FREE (ds->refline2);
R_FREE (ds->prev_line_col);
ret = true;
}
break;
default:
break;
}
}
r_pvector_free (metas);
return ret;
}
@ -3515,17 +3517,15 @@ static bool ds_print_core_vmode(RDisasmState *ds, int pos) {
}
}
if (ds->asm_hint_lea) {
RAnalMetaItem *mi = r_meta_find (ds->core->anal, ds->at, R_META_TYPE_ANY, R_META_WHERE_HERE);
if (mi && mi->from) {
ut64 size;
RAnalMetaItem *mi = r_meta_get_at (ds->core->anal, ds->at, R_META_TYPE_ANY, &size);
if (mi) {
int obits = ds->core->assembler->bits;
ds->core->assembler->bits = mi->size * 8;
getPtr (ds, mi->from, pos);
ds->core->assembler->bits = size * 8;
getPtr (ds, ds->at, pos);
ds->core->assembler->bits = obits;
gotShortcut = true;
}
if (mi) {
r_meta_item_free (mi);
}
}
switch (ds->analop.type) {
case R_ANAL_OP_TYPE_UJMP:
@ -3830,16 +3830,14 @@ static inline bool is_filtered_flag(RDisasmState *ds, const char *name) {
return false;
}
ut64 refaddr = ds->analop.ptr;
char *anal_flag = r_meta_get_string (ds->core->anal, R_META_TYPE_STRING, refaddr);
const char *anal_flag = r_meta_get_string (ds->core->anal, R_META_TYPE_STRING, refaddr);
if (anal_flag) {
anal_flag = strdup (anal_flag);
if (anal_flag) {
r_name_filter (anal_flag, -1);
if (!strcmp (&name[4], anal_flag)) {
free (anal_flag);
char *dupped = strdup (anal_flag);
if (dupped) {
r_name_filter (dupped, -1);
if (!strcmp (&name[4], dupped)) {
return true;
}
free (anal_flag);
}
}
return false;
@ -4562,26 +4560,21 @@ static void delete_last_comment(RDisasmState *ds) {
}
}
static bool can_emulate_metadata(RCore * core, ut64 at) {
static bool can_emulate_metadata(RCore *core, ut64 at) {
// check if there is a meta at the addr that is unemulateable
const char *emuskipmeta = r_config_get (core->config, "emu.skip");
char key[32];
Sdb *s = core->anal->sdb_meta;
snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, at);
const char *infos = sdb_const_get (s, key, 0);
if (!infos) {
/* no metadata: let's emulate this */
return true;
}
for (; *infos; infos++) {
/*
* don't emulate if at least one metadata type
* can't be emulated
*/
if (*infos != ',' && strchr(emuskipmeta, *infos)) {
return false;
bool ret = true;
RPVector *metas = r_meta_get_all_at (core->anal, at);
void **it;
r_pvector_foreach (metas, it) {
RAnalMetaItem *item = ((RIntervalNode *)*it)->data;
if (strchr (emuskipmeta, (char)item->type)) {
ret = false;
break;
}
}
return true;
r_pvector_free (metas);
return ret;
}
static void mipsTweak(RDisasmState *ds) {
@ -4870,10 +4863,9 @@ static void ds_print_comments_right(RDisasmState *ds) {
RCore *core = ds->core;
ds_print_relocs (ds);
bool is_code = (!ds->hint) || (ds->hint && ds->hint->type != 'd');
RAnalMetaItem *mi = r_meta_find (ds->core->anal, ds->at, R_META_TYPE_ANY, R_META_WHERE_HERE);
RAnalMetaItem *mi = r_meta_get_at (ds->core->anal, ds->at, R_META_TYPE_ANY, NULL);
if (mi) {
is_code = mi->type != 'd';
r_meta_item_free (mi);
mi = NULL;
}
if (is_code && ds->asm_describe && !ds->has_description) {
@ -5274,11 +5266,10 @@ toro:
if (of != f) {
char cmt[32];
get_bits_comment (core, f, cmt, sizeof (cmt));
char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ds->at);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ds->at);
if (comment) {
ds_pre_xrefs (ds, true);
r_cons_printf ("; %s\n", comment);
free (comment);
}
r_cons_printf ("%s%s%s (fcn) %s%s%s\n",
COLOR (ds, color_fline), core->cons->vline[CORNER_TL],
@ -6113,12 +6104,11 @@ R_API int r_core_print_disasm_json(RCore *core, ut64 addr, ut8 *buf, int nb_byte
}
/* add comments */
{
// TODO: slow because we are decoding and encoding b64
char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, at);
// TODO: slow because we are encoding b64
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, at);
if (comment) {
char *b64comment = sdb_encode ((const ut8*)comment, -1);
pj_ks (pj, "comment", b64comment);
free (comment);
free (b64comment);
}
}
@ -6402,27 +6392,27 @@ toro:
unsigned int seggrn = r_config_get_i (core->config, "asm.seggrn");
r_print_offset_sg (core->print, at, 0, show_offseg, seggrn, show_offdec, 0, NULL);
}
r_meta_item_free (meta);
meta = r_meta_find (core->anal, core->offset + i,
R_META_TYPE_ANY, R_META_WHERE_HERE);
if (meta && meta->size > 0) {
ut64 meta_start = core->offset + i;
ut64 meta_size;
meta = r_meta_get_at (core->anal, meta_start, R_META_TYPE_ANY, &meta_size);
if (meta) {
switch (meta->type) {
case R_META_TYPE_DATA:
//r_cons_printf (".data: %s\n", meta->str);
i += meta->size;
i += meta_size;
{
int idx = i;
ut64 at = core->offset + i;
int hexlen = len - idx;
int delta = at - meta->from;
if (meta->size < hexlen) {
hexlen = meta->size;
int delta = at - meta_start;
if (meta_size < hexlen) {
hexlen = meta_size;
}
// int oplen = meta->size - delta;
core->print->flags &= ~R_PRINT_FLAGS_HEADER;
// TODO do not pass a copy in parameter buf that is possibly to small for this
// print operation
int size = R_MIN (meta->size, len - idx);
int size = R_MIN (meta_size, len - idx);
ut8 *buf = calloc (size, 1);
if (buf) {
r_io_read_at (core->io, at, buf, size);
@ -6441,19 +6431,21 @@ toro:
continue;
case R_META_TYPE_STRING:
//r_cons_printf (".string: %s\n", meta->str);
i += meta->size;
i += meta_size;
continue;
case R_META_TYPE_FORMAT:
//r_cons_printf (".format : %s\n", meta->str);
i += meta->size;
i += meta_size;
continue;
case R_META_TYPE_MAGIC:
//r_cons_printf (".magic : %s\n", meta->str);
i += meta->size;
i += meta_size;
continue;
case R_META_TYPE_RUN:
/* TODO */
break;
default:
break;
}
}
r_asm_set_pc (core->assembler, core->offset + i);
@ -6480,10 +6472,9 @@ toro:
}
}
if (fmt == 'C') {
char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, core->offset + i);
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, core->offset + i);
if (comment) {
r_cons_printf ("0x%08"PFMT64x " %s\n", core->offset + i, comment);
free (comment);
}
i += ret;
continue;
@ -6575,7 +6566,6 @@ toro:
goto toro;
}
r_config_set_i (core->config, "asm.marks", asmmarks);
r_meta_item_free (meta);
r_cons_break_pop ();
r_core_seek (core, old_offset, true);
return err;

View File

@ -602,7 +602,7 @@ static bool simpleProjectSaveScript(RCore *core, const char *file, int opts) {
}
if (opts & R_CORE_PRJ_META) {
r_str_write (fd, "# meta\n");
r_meta_list (core->anal, R_META_TYPE_ANY, 1);
r_meta_print_list_all (core->anal, R_META_TYPE_ANY, 1);
r_cons_flush ();
r_core_cmd (core, "fV*", 0);
r_cons_flush ();
@ -688,7 +688,7 @@ static bool projectSaveScript(RCore *core, const char *file, int opts) {
}
if (opts & R_CORE_PRJ_META) {
r_str_write (fd, "# meta\n");
r_meta_list (core->anal, R_META_TYPE_ANY, 1);
r_meta_print_list_all (core->anal, R_META_TYPE_ANY, 1);
r_cons_flush ();
r_core_cmd (core, "fV*", 0);
r_cons_flush ();

View File

@ -1661,7 +1661,8 @@ static void visual_comma(RCore *core) {
bool mouse_state = __holdMouseState (core);
ut64 addr = core->offset + (core->print->cur_enabled? core->print->cur: 0);
char *comment, *cwd, *cmtfile;
comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
const char *prev_cmt = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
comment = prev_cmt ? strdup (prev_cmt) : NULL;
cmtfile = r_str_between (comment, ",(", ")");
cwd = getcommapath (core);
if (!cmtfile) {
@ -2935,17 +2936,13 @@ R_API int r_core_visual_cmd(RCore *core, const char *arg) {
} else {
int times = R_MAX (1, wheelspeed);
// Check if we have a data annotation.
RAnalMetaItem *ami = r_meta_find (core->anal,
core->offset, R_META_TYPE_DATA,
R_META_WHERE_HERE);
ut64 amisize;
RAnalMetaItem *ami = r_meta_get_at (core->anal, core->offset, R_META_TYPE_DATA, &amisize);
if (!ami) {
ami = r_meta_find (core->anal,
core->offset, R_META_TYPE_STRING,
R_META_WHERE_HERE);
ami = r_meta_get_at (core->anal, core->offset, R_META_TYPE_STRING, &amisize);
}
if (ami) {
r_core_seek_delta (core, ami->size);
r_meta_item_free (ami);
r_core_seek_delta (core, amisize);
} else {
int distance = numbuf_pull ();
if (distance > 1) {

View File

@ -842,25 +842,6 @@ R_API int r_core_visual_types(RCore *core) {
return true;
}
static int cmtcb(void *usr, const char *k, const char *v) {
if (!strncmp (k, "meta.C.", 7)) {
RList *list = (RList*)usr;
char *msg, *comma = strchr (v, ',');
if (comma) {
comma = strchr (comma + 1, ',');
if (comma) {
msg = (char *)sdb_decode (comma + 1, NULL);
if (msg) {
msg = r_str_replace (msg, "\n", "", true);
r_list_append (list, r_str_newf ("%s %s", k+7, msg));
free (msg);
}
}
}
}
return 1;
}
R_API bool r_core_visual_hudclasses(RCore *core) {
RListIter *iter, *iter2;
RBinClass *c;
@ -917,7 +898,16 @@ R_API bool r_core_visual_hudstuff(RCore *core) {
}
list->free = free;
r_flag_foreach (core->flags, hudstuff_append, list);
sdb_foreach (core->anal->sdb_meta, cmtcb, list);
RIntervalTreeIter it;
RAnalMetaItem *mi;
r_interval_tree_foreach (&core->anal->meta, it, mi) {
if (mi->type == R_META_TYPE_COMMENT) {
char *s = r_str_newf ("0x%08"PFMT64x" %s", r_interval_tree_iter_get (&it)->start, mi->str);
if (s) {
r_list_push (list, s);
}
}
}
res = r_cons_hud (list, NULL);
if (res) {
char *p = strchr (res, ' ');
@ -1672,10 +1662,9 @@ R_API int r_core_visual_view_rop(RCore *core) {
int extra = strlen (chainstr) / scr_w;
r_cons_gotoxy (0, extra + 22 + count);
r_cons_strcat (msg);
char *cmt = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, r_num_get (NULL, msg));
const char *cmt = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, r_num_get (NULL, msg));
if (cmt) {
r_cons_strcat (cmt);
free (cmt);
}
count ++;
}
@ -2161,35 +2150,6 @@ R_API int r_core_visual_trackflags(RCore *core) {
}
return true;
}
static bool meta_deserialize(RAnal *a, RAnalMetaItem *it, const char *k, const char *v) {
if (strlen (k) < 8) {
return false;
}
if (memcmp (k + 6, ".0x", 3)) {
return false;
}
return r_meta_deserialize_val (a, it, k[5], sdb_atoi (k + 7), v);
}
static int meta_enumerate_cb(void *user, const char *k, const char *v) {
RAnalMetaUserItem *ui = user;
RList *list = ui->user;
RAnalMetaItem *it = R_NEW0 (RAnalMetaItem);
if (!it) {
return 0;
}
if (!meta_deserialize (ui->anal, it, k, v)) {
free (it);
goto beach;
}
if (!it->str) {
free (it);
goto beach;
}
r_list_append (list, it);
beach:
return 1;
}
R_API int r_core_visual_comments (RCore *core) {
char *str;
@ -2201,23 +2161,23 @@ R_API int r_core_visual_comments (RCore *core) {
for (;;) {
r_cons_clear00 ();
r_cons_strcat ("Comments:\n");
RList *items = r_list_newf (free);
RIntervalTreeIter it;
RAnalMetaItem *item;
RListIter *iter;
r_meta_list_cb (core->anal, R_META_TYPE_COMMENT, 0, meta_enumerate_cb, items, UT64_MAX);
i = 0;
r_list_foreach (items, iter, item) {
r_interval_tree_foreach (&core->anal->meta, it, item) {
if (item->type != R_META_TYPE_COMMENT) {
continue;
}
str = item->str;
addr = item->from;
addr = r_interval_tree_iter_get (&it)->start;
if (option==i) {
from = addr;
size = 1; // XXX: remove this thing size for comments is useless d->size;
free (p);
p = str;
p = strdup (str);
r_cons_printf (" > %s\n", str);
} else {
r_cons_printf (" %s\n", str);
free (str);
}
i ++;
}
@ -3725,12 +3685,12 @@ R_API void r_core_seek_previous (RCore *core, const char *type) {
//define the data at offset according to the type (byte, word...) n times
static void define_data_ntimes (RCore *core, ut64 off, int times, int type) {
int i = 0;
r_meta_cleanup (core->anal, off, off + core->blocksize);
r_meta_del (core->anal, R_META_TYPE_ANY, off, core->blocksize);
if (times < 0) {
times = 1;
}
for (i = 0; i < times; i++, off += type) {
r_meta_add (core->anal, R_META_TYPE_DATA, off, off + type, "");
r_meta_set (core->anal, R_META_TYPE_DATA, off, type, "");
}
}
@ -4117,13 +4077,13 @@ onemoretime:
}
name[4 + n] = '\0';
if (is_wide) {
r_meta_add (core->anal, R_META_TYPE_STRING,
off + ntotal, off + (n * 2) + ntotal,
(const char *)name + 4);
r_meta_set (core->anal, R_META_TYPE_STRING,
off + ntotal, (n * 2) + ntotal,
(const char *) name + 4);
} else {
r_meta_add (core->anal, R_META_TYPE_STRING,
off + ntotal, off + n + ntotal,
(const char *)name + 4);
r_meta_set (core->anal, R_META_TYPE_STRING,
off + ntotal, n + ntotal,
(const char *) name + 4);
}
r_name_filter (name, n + 10);
r_flag_set (core->flags, name, off + ntotal, n);
@ -4170,11 +4130,11 @@ onemoretime:
//handle wide strings
//memcpy (name + 4, (const char *)p, n);
if (is_wide) {
r_meta_add (core->anal, R_META_TYPE_STRING, off,
off + (n * 2), (const char *)name + 4);
r_meta_set (core->anal, R_META_TYPE_STRING, off,
n * 2, (const char *) name + 4);
} else {
r_meta_add (core->anal, R_META_TYPE_STRING, off,
off + n, (const char *)name + 4);
r_meta_set (core->anal, R_META_TYPE_STRING, off,
n, (const char *) name + 4);
}
r_name_filter (name, n + 10);
r_flag_set (core->flags, name, off, n);
@ -4183,12 +4143,12 @@ onemoretime:
}
break;
case 'd': // TODO: check
r_meta_cleanup (core->anal, off, off+plen);
r_meta_add (core->anal, R_META_TYPE_DATA, off, off+plen, "");
r_meta_del (core->anal, R_META_TYPE_ANY, off, plen);
r_meta_set (core->anal, R_META_TYPE_DATA, off, plen, "");
break;
case 'c': // TODO: check
r_meta_cleanup (core->anal, off, off + plen);
r_meta_add (core->anal, R_META_TYPE_CODE, off, off + plen, "");
r_meta_del (core->anal, R_META_TYPE_ANY, off, plen);
r_meta_set (core->anal, R_META_TYPE_CODE, off, plen, "");
break;
case 'u':
r_core_anal_undefine (core, off);

View File

@ -35,17 +35,6 @@ R_LIB_VERSION_HEADER(r_anal);
bb_has_ops=0 -> 350MB
*/
/* meta */
typedef struct r_anal_meta_item_t {
ut64 from;
ut64 to;
ut64 size;
int type;
int subtype;
char *str;
const RSpace *space;
} RAnalMetaItem;
typedef struct {
struct r_anal_t *anal;
int type;
@ -284,14 +273,7 @@ struct r_anal_type_t {
RList *content;
};
enum {
R_META_WHERE_PREV = -1,
R_META_WHERE_HERE = 0,
R_META_WHERE_NEXT = 1,
};
enum {
R_META_TYPE_NONE = 0,
typedef enum {
R_META_TYPE_ANY = -1,
R_META_TYPE_DATA = 'd',
R_META_TYPE_CODE = 'c',
@ -303,7 +285,15 @@ enum {
R_META_TYPE_RUN = 'r',
R_META_TYPE_HIGHLIGHT = 'H',
R_META_TYPE_VARTYPE = 't',
};
} RAnalMetaType;
/* meta */
typedef struct r_anal_meta_item_t {
RAnalMetaType type;
int subtype;
char *str;
const RSpace *space;
} RAnalMetaItem;
// anal
typedef enum {
@ -602,12 +592,10 @@ typedef struct r_anal_t {
RList *plugins;
Sdb *sdb_types;
Sdb *sdb_fmts;
Sdb *sdb_meta; // TODO: Future r_meta api
Sdb *sdb_zigns;
HtUP *dict_refs;
HtUP *dict_xrefs;
bool recursive_noreturn;
RSpaces meta_spaces;
RSpaces zign_spaces;
char *zign_path;
PrintfCallback cb_printf;
@ -624,6 +612,8 @@ typedef struct r_anal_t {
RBTree/*<RAnalArchHintRecord>*/ arch_hints;
RBTree/*<RAnalArchBitsRecord>*/ bits_hints;
RHintCb hint_cbs;
RIntervalTree meta;
RSpaces meta_spaces;
Sdb *sdb_fcnsign; // OK
Sdb *sdb_cc; // calling conventions
Sdb *sdb_classes;
@ -1727,34 +1717,78 @@ R_API void r_anal_data_free (RAnalData *d);
#include <r_cons.h>
R_API char *r_anal_data_to_string(RAnalData *d, RConsPrintablePalette *pal);
R_API void r_meta_free(RAnal *m);
R_API RList *r_meta_find_list_in(RAnal *a, ut64 at, int type, int where);
R_API void r_meta_space_unset_for(RAnal *a, const RSpace *space);
R_API int r_meta_space_count_for(RAnal *a, const RSpace *space_name);
R_API RList *r_meta_enumerate(RAnal *a, int type);
R_API int r_meta_count(RAnal *m, int type, ut64 from, ut64 to);
R_API char *r_meta_get_string(RAnal *m, int type, ut64 addr);
R_API bool r_meta_set_string(RAnal *m, int type, ut64 addr, const char *s);
R_API int r_meta_get_size(RAnal *a, int type);
R_API int r_meta_del(RAnal *m, int type, ut64 from, ut64 size);
R_API int r_meta_add(RAnal *m, int type, ut64 from, ut64 to, const char *str);
R_API int r_meta_add_with_subtype(RAnal *m, int type, int subtype, ut64 from, ut64 to, const char *str);
R_API RAnalMetaItem *r_meta_find(RAnal *m, ut64 off, int type, int where);
R_API RAnalMetaItem *r_meta_find_any_except(RAnal *m, ut64 at, int type, int where);
R_API RAnalMetaItem *r_meta_find_in(RAnal *m, ut64 off, int type, int where);
R_API int r_meta_cleanup(RAnal *m, ut64 from, ut64 to);
R_API const char *r_meta_type_to_string(int type);
R_API RList *r_meta_enumerate(RAnal *a, int type);
R_API int r_meta_list(RAnal *m, int type, int rad);
R_API int r_meta_list_at(RAnal *m, int type, int rad, ut64 addr);
R_API int r_meta_list_cb(RAnal *m, int type, int rad, SdbForeachCallback cb, void *user, ut64 addr);
R_API void r_meta_list_offset(RAnal *m, ut64 addr, char input);
R_API void r_meta_item_free(void *_item);
R_API RAnalMetaItem *r_meta_item_new(int type);
R_API bool r_meta_deserialize_val(RAnal *a, RAnalMetaItem *it, int type, ut64 from, const char *v);
R_API void r_meta_print(RAnal *a, RAnalMetaItem *d, int rad, PJ *pj, bool show_full);
/* meta
*
* Meta uses Condret's Klemmbaustein Priciple, i.e. intervals are defined inclusive/inclusive.
* A meta item from 0x42 to 0x42 has a size of 1. Items with size 0 do not exist.
* Meta items are allowed to overlap and the internal data structure allows for multiple meta items
* starting at the same address.
* Meta items are saved in an RIntervalTree. To access the interval of an item, use the members of RIntervalNode.
*/
static inline ut64 r_meta_item_size(ut64 start, ut64 end) {
// meta items use inclusive/inclusive intervals
return end - start + 1;
}
static inline ut64 r_meta_node_size(RIntervalNode *node) {
return r_meta_item_size (node->start, node->end);
}
// Set a meta item at addr with the given contents in the current space.
// If there already exists an item with this type and space at addr (regardless of its size) it will be overwritten.
R_API bool r_meta_set(RAnal *a, RAnalMetaType type, ut64 addr, ut64 size, const char *str);
// Same as r_meta_set() but also sets the subtype.
R_API bool r_meta_set_with_subtype(RAnal *m, RAnalMetaType type, int subtype, ut64 addr, ut64 size, const char *str);
// Delete all meta items in the current space that intersect with the given interval.
// If size == UT64_MAX, everything in the current space will be deleted.
R_API void r_meta_del(RAnal *a, RAnalMetaType type, ut64 addr, ut64 size);
// Same as r_meta_set() with a size of 1.
R_API bool r_meta_set_string(RAnal *a, RAnalMetaType type, ut64 addr, const char *s);
// Convenience function to get the str content of the item at addr with given type in the current space.
R_API const char *r_meta_get_string(RAnal *a, RAnalMetaType type, ut64 addr);
// Convenience function to add an R_META_TYPE_DATA item at the given addr in the current space.
R_API void r_meta_set_data_at(RAnal *a, ut64 addr, ut64 wordsz);
// Returns the item with given type that starts at addr in the current space or NULL. The size of this item optionally returned through size.
R_API RAnalMetaItem *r_meta_get_at(RAnal *a, ut64 addr, RAnalMetaType type, R_OUT R_NULLABLE ut64 *size);
// Returns the node for one meta item with the given type that contains addr in the current space or NULL.
// To get all the nodes, use r_meta_get_all_in().
R_API RIntervalNode *r_meta_get_in(RAnal *a, ut64 addr, RAnalMetaType type);
// Returns all nodes for items starting at the given address in the current space.
R_API RPVector/*<RIntervalNode<RMetaItem> *>*/ *r_meta_get_all_at(RAnal *a, ut64 at);
// Returns all nodes for items with the given type containing the given address in the current space.
R_API RPVector/*<RIntervalNode<RMetaItem> *>*/ *r_meta_get_all_in(RAnal *a, ut64 at, RAnalMetaType type);
// Returns all nodes for items with the given type intersecting the given interval in the current space.
R_API RPVector/*<RIntervalNode<RMetaItem> *>*/ *r_meta_get_all_intersect(RAnal *a, ut64 start, ut64 size, RAnalMetaType type);
// Delete all meta items in the given space
R_API void r_meta_space_unset_for(RAnal *a, const RSpace *space);
// Returns the number of meta items in the given space
R_API int r_meta_space_count_for(RAnal *a, const RSpace *space);
// Shift all meta items by the given delta, for rebasing between different memory layouts.
R_API void r_meta_rebase(RAnal *anal, ut64 diff);
// Calculate the total size covered by meta items of the given type.
R_API ut64 r_meta_get_size(RAnal *a, RAnalMetaType type);
R_API const char *r_meta_type_to_string(int type);
R_API void r_meta_print(RAnal *a, RAnalMetaItem *d, ut64 start, ut64 size, int rad, PJ *pj, bool show_full);
R_API void r_meta_print_list_all(RAnal *a, int type, int rad);
R_API void r_meta_print_list_at(RAnal *a, ut64 addr, int rad);
R_API void r_meta_print_list_in_function(RAnal *a, int type, int rad, ut64 addr);
/* hints */
R_API void r_anal_hint_del(RAnal *anal, ut64 addr, ut64 size); // delete all hints that are contained within the given range, if size > 1, this operation is quite heavy!

View File

@ -23,6 +23,19 @@ xmm0l:
EOF
RUN
NAME=repeat comments
FILE=-
CMDS=<<EOF
CC aero@0x42
CC pause@0x43
CC plus@0x1337
s@@@C:p*
EOF
EXPECT=<<EOF
0x43
0x1337
EOF
RUN
NAME=3p8
FILE=-

View File

@ -373,12 +373,12 @@ EXPECT=<<EOF
----
0x00000380 magic 8 wwww
----
0x00000000 ascii[12] "hello world"
0x00000000 CCu "Hello!"
0x00000100 data Cd 3
0x00000300 format 4 x
0x00000200 hidden Ch 2
0x00000300 format 4 x
0x00000380 magic 8 wwww
0x00000000 ascii[12] "hello world"
----
Cs 12 @ 0x00000000 # hello world
----
@ -392,12 +392,12 @@ CCu base64:SGVsbG8h @ 0x00000000
----
Cm 8 wwww @ 0x00000380
----
Cs 12 @ 0x00000000 # hello world
CCu base64:SGVsbG8h @ 0x00000000
Cd 3 @ 0x00000100
Cf 4 x @ 0x00000300
Ch 2 @ 0x00000200
Cf 4 x @ 0x00000300
Cm 8 wwww @ 0x00000380
Cs 12 @ 0x00000000 # hello world
----
[{"offset":0,"type":"Cs","name":"aGVsbG8gd29ybGQ=","enc":"latin1","ascii":true}]
----
@ -411,7 +411,7 @@ Cs 12 @ 0x00000000 # hello world
----
[{"offset":896,"type":"Cm","name":"wwww"}]
----
[{"offset":0,"type":"CCu","name":"Hello!"},{"offset":256,"type":"Cd","name":"3","size":3},{"offset":768,"type":"Cf","name":"x"},{"offset":512,"type":"Ch","name":"2"},{"offset":896,"type":"Cm","name":"wwww"},{"offset":0,"type":"Cs","name":"aGVsbG8gd29ybGQ=","enc":"latin1","ascii":true}]
[{"offset":0,"type":"Cs","name":"aGVsbG8gd29ybGQ=","enc":"latin1","ascii":true},{"offset":0,"type":"CCu","name":"Hello!"},{"offset":256,"type":"Cd","name":"3","size":3},{"offset":512,"type":"Ch","name":"2"},{"offset":768,"type":"Cf","name":"x"},{"offset":896,"type":"Cm","name":"wwww"}]
EOF
RUN
@ -615,8 +615,8 @@ Cf-
C
EOF
EXPECT=<<EOF
0x00000100 format 8 xx
0x00000100 ascii[4] "abcd"
0x00000100 format 8 xx
----
0x00000100 format 8 xx
----
@ -637,9 +637,9 @@ C-
C
EOF
EXPECT=<<EOF
0x00000100 CCu "a string"
0x00000100 format 8 xx
0x00000100 ascii[4] "abcd"
0x00000100 format 8 xx
0x00000100 CCu "a string"
----
EOF
RUN
@ -700,7 +700,7 @@ C.
EOF
EXPECT=<<EOF
0x0007a23c ascii[13] "match_symbol"
0x00083fc4 CCu "[14] -rw- section size 4 named .init_array"
0x00083fc4 data Cd 4
0x00083fc4 CCu "[14] -rw- section size 4 named .init_array"
EOF
RUN

View File

@ -72,26 +72,26 @@ EXPECT=<<EOF
0x08048300 CCu "[13] -r-x section size 404 named .text"
0x08048494 CCu "[14] -r-x section size 20 named .fini"
0x080484a8 CCu "[15] -r-- section size 21 named .rodata"
0x080484b0 ascii[13] "Hello world!"
0x080484c0 CCu "[16] -r-- section size 44 named .eh_frame_hdr"
0x080484ec CCu "[17] -r-- section size 176 named .eh_frame"
0x0804959c data Cd 4
0x0804959c CCu "[18] -rw- section size 4 named .init_array"
0x080495a0 data Cd 4
0x080495a0 CCu "[19] -rw- section size 4 named .fini_array"
0x080495a4 CCu "[20] -rw- section size 4 named .jcr"
0x080495a8 CCu "[21] -rw- section size 232 named .dynamic"
0x08049690 CCu "[22] -rw- section size 4 named .got"
0x08049694 CCu "[23] -rw- section size 24 named .got.plt"
0x080496ac CCu "[24] -rw- section size 8 named .data"
0x080496b4 CCu "[25] -rw- section size 4 named .bss"
0x0804959c data Cd 4
0x080495a0 data Cd 4
0x08049690 data Cd 4
0x08049690 CCu "[22] -rw- section size 4 named .got"
0x08049694 data Cd 4
0x08049694 CCu "[23] -rw- section size 24 named .got.plt"
0x08049698 data Cd 4
0x0804969c data Cd 4
0x080496a0 data Cd 4
0x080496a4 data Cd 4
0x080496a8 data Cd 4
0x080484b0 ascii[13] "Hello world!"
0x080496ac CCu "[24] -rw- section size 8 named .data"
0x080496b4 CCu "[25] -rw- section size 4 named .bss"
EOF
RUN
@ -115,26 +115,26 @@ CCu base64:WzEyXSAtci14IHNlY3Rpb24gc2l6ZSA2NCBuYW1lZCAucGx0 @ 0x080482c0
CCu base64:WzEzXSAtci14IHNlY3Rpb24gc2l6ZSA0MDQgbmFtZWQgLnRleHQ= @ 0x08048300
CCu base64:WzE0XSAtci14IHNlY3Rpb24gc2l6ZSAyMCBuYW1lZCAuZmluaQ== @ 0x08048494
CCu base64:WzE1XSAtci0tIHNlY3Rpb24gc2l6ZSAyMSBuYW1lZCAucm9kYXRh @ 0x080484a8
Cs 13 @ 0x080484b0 # Hello world!
CCu base64:WzE2XSAtci0tIHNlY3Rpb24gc2l6ZSA0NCBuYW1lZCAuZWhfZnJhbWVfaGRy @ 0x080484c0
CCu base64:WzE3XSAtci0tIHNlY3Rpb24gc2l6ZSAxNzYgbmFtZWQgLmVoX2ZyYW1l @ 0x080484ec
Cd 4 @ 0x0804959c
CCu base64:WzE4XSAtcnctIHNlY3Rpb24gc2l6ZSA0IG5hbWVkIC5pbml0X2FycmF5 @ 0x0804959c
Cd 4 @ 0x080495a0
CCu base64:WzE5XSAtcnctIHNlY3Rpb24gc2l6ZSA0IG5hbWVkIC5maW5pX2FycmF5 @ 0x080495a0
CCu base64:WzIwXSAtcnctIHNlY3Rpb24gc2l6ZSA0IG5hbWVkIC5qY3I= @ 0x080495a4
CCu base64:WzIxXSAtcnctIHNlY3Rpb24gc2l6ZSAyMzIgbmFtZWQgLmR5bmFtaWM= @ 0x080495a8
CCu base64:WzIyXSAtcnctIHNlY3Rpb24gc2l6ZSA0IG5hbWVkIC5nb3Q= @ 0x08049690
CCu base64:WzIzXSAtcnctIHNlY3Rpb24gc2l6ZSAyNCBuYW1lZCAuZ290LnBsdA== @ 0x08049694
CCu base64:WzI0XSAtcnctIHNlY3Rpb24gc2l6ZSA4IG5hbWVkIC5kYXRh @ 0x080496ac
CCu base64:WzI1XSAtcnctIHNlY3Rpb24gc2l6ZSA0IG5hbWVkIC5ic3M= @ 0x080496b4
Cd 4 @ 0x0804959c
Cd 4 @ 0x080495a0
Cd 4 @ 0x08049690
CCu base64:WzIyXSAtcnctIHNlY3Rpb24gc2l6ZSA0IG5hbWVkIC5nb3Q= @ 0x08049690
Cd 4 @ 0x08049694
CCu base64:WzIzXSAtcnctIHNlY3Rpb24gc2l6ZSAyNCBuYW1lZCAuZ290LnBsdA== @ 0x08049694
Cd 4 @ 0x08049698
Cd 4 @ 0x0804969c
Cd 4 @ 0x080496a0
Cd 4 @ 0x080496a4
Cd 4 @ 0x080496a8
Cs 13 @ 0x080484b0 # Hello world!
CCu base64:WzI0XSAtcnctIHNlY3Rpb24gc2l6ZSA4IG5hbWVkIC5kYXRh @ 0x080496ac
CCu base64:WzI1XSAtcnctIHNlY3Rpb24gc2l6ZSA0IG5hbWVkIC5ic3M= @ 0x080496b4
EOF
RUN

View File

@ -5,6 +5,7 @@ if get_option('enable_tests')
'anal_block',
'anal_function',
'anal_hints',
'anal_meta',
'anal_var',
'anal_xrefs',
'base64',

609
test/unit/test_anal_meta.c Normal file
View File

@ -0,0 +1,609 @@
#include <r_anal.h>
#include "minunit.h"
bool test_meta_set() {
RAnal *anal = r_anal_new ();
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "summer of love");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF8, 0x200, 0x30, "true confessions");
bool found[3] = { 0 };
size_t count = 0;
RIntervalTreeIter it;
RAnalMetaItem *item;
r_interval_tree_foreach (&anal->meta, it, item) {
count++;
RIntervalNode *node = r_interval_tree_iter_get (&it);
switch (item->type) {
case R_META_TYPE_DATA:
mu_assert_eq (node->start, 0x100, "node start");
mu_assert_eq (node->end, 0x103, "node end (inclusive)");
mu_assert_null (item->str, "no string");
mu_assert_eq (item->subtype, 0, "no subtype");
found[0] = true;
break;
case R_META_TYPE_COMMENT:
mu_assert_eq (node->start, 0x100, "node start");
mu_assert_eq (node->end, 0x100, "node end (inclusive)");
mu_assert_streq (item->str, "summer of love", "comment string");
mu_assert_eq (item->subtype, 0, "no subtype");
found[1] = true;
break;
case R_META_TYPE_STRING:
mu_assert_eq (node->start, 0x200, "node start");
mu_assert_eq (node->end, 0x22f, "node end (inclusive)");
mu_assert_streq (item->str, "true confessions", "string string");
mu_assert_eq (item->subtype, R_STRING_ENC_UTF8, "subtype");
found[2] = true;
break;
default:
break;
}
}
mu_assert_eq (count, 3, "set count");
mu_assert ("meta 0", found[0]);
mu_assert ("meta 1", found[1]);
mu_assert ("meta 2", found[2]);
// Override an item, changing only its size
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 8, NULL);
count = 0;
found[0] = found[1] = found[2] = false;
r_interval_tree_foreach (&anal->meta, it, item) {
count++;
RIntervalNode *node = r_interval_tree_iter_get (&it);
switch (item->type) {
case R_META_TYPE_DATA:
mu_assert_eq (node->start, 0x100, "node start");
mu_assert_eq (node->end, 0x107, "node end (inclusive)");
mu_assert_null (item->str, "no string");
mu_assert_eq (item->subtype, 0, "no subtype");
found[0] = true;
break;
case R_META_TYPE_COMMENT:
mu_assert_eq (node->start, 0x100, "node start");
mu_assert_eq (node->end, 0x100, "node end (inclusive)");
mu_assert_streq (item->str, "summer of love", "comment string");
mu_assert_eq (item->subtype, 0, "no subtype");
found[1] = true;
break;
case R_META_TYPE_STRING:
mu_assert_eq (node->start, 0x200, "node start");
mu_assert_eq (node->end, 0x22f, "node end (inclusive)");
mu_assert_streq (item->str, "true confessions", "string string");
mu_assert_eq (item->subtype, R_STRING_ENC_UTF8, "subtype");
found[2] = true;
break;
default:
break;
}
}
mu_assert_eq (count, 3, "set count");
mu_assert ("meta 0", found[0]);
mu_assert ("meta 1", found[1]);
mu_assert ("meta 2", found[2]);
// Override items, changing their contents
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "this ain't the summer of love");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF16LE, 0x200, 0x40, "e.t.i. (extra terrestrial intelligence)");
count = 0;
found[0] = found[1] = found[2] = false;
r_interval_tree_foreach (&anal->meta, it, item) {
count++;
RIntervalNode *node = r_interval_tree_iter_get (&it);
switch (item->type) {
case R_META_TYPE_DATA:
mu_assert_eq (node->start, 0x100, "node start");
mu_assert_eq (node->end, 0x107, "node end (inclusive)");
mu_assert_null (item->str, "no string");
mu_assert_eq (item->subtype, 0, "no subtype");
found[0] = true;
break;
case R_META_TYPE_COMMENT:
mu_assert_eq (node->start, 0x100, "node start");
mu_assert_eq (node->end, 0x100, "node end (inclusive)");
mu_assert_streq (item->str, "this ain't the summer of love", "comment string");
mu_assert_eq (item->subtype, 0, "no subtype");
found[1] = true;
break;
case R_META_TYPE_STRING:
mu_assert_eq (node->start, 0x200, "node start");
mu_assert_eq (node->end, 0x23f, "node end (inclusive)");
mu_assert_streq (item->str, "e.t.i. (extra terrestrial intelligence)", "string string");
mu_assert_eq (item->subtype, R_STRING_ENC_UTF16LE, "subtype");
found[2] = true;
break;
default:
break;
}
}
mu_assert_eq (count, 3, "set count");
mu_assert ("meta 0", found[0]);
mu_assert ("meta 1", found[1]);
mu_assert ("meta 2", found[2]);
r_anal_free (anal);
mu_end;
}
bool test_meta_get_at() {
RAnal *anal = r_anal_new ();
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF8, 0x200, 0x30, "true confessions");
RAnalMetaItem *item = r_meta_get_at (anal, 0x100, R_META_TYPE_COMMENT, NULL);
mu_assert_notnull (item, "get item");
mu_assert_streq (item->str, "vera gemini", "get contents");
ut64 size;
item = r_meta_get_at (anal, 0x100, R_META_TYPE_DATA, &size);
mu_assert_notnull (item, "get item");
mu_assert_eq (item->type, R_META_TYPE_DATA, "get contents");
mu_assert_eq (size, 4, "get size");
item = r_meta_get_at (anal, 0x200, R_META_TYPE_ANY, NULL);
mu_assert_notnull (item, "get item");
mu_assert_streq (item->str, "true confessions", "get contents");
item = r_meta_get_at (anal, 0x100, R_META_TYPE_ANY, NULL);
mu_assert_notnull (item, "get item");
// which one we get is undefined here (intended)
item = r_meta_get_at (anal, 0x1ff, R_META_TYPE_ANY, NULL);
mu_assert_null (item, "get item");
item = r_meta_get_at (anal, 0x201, R_META_TYPE_ANY, NULL);
mu_assert_null (item, "get item");
item = r_meta_get_at (anal, 0xff, R_META_TYPE_ANY, NULL);
mu_assert_null (item, "get item");
item = r_meta_get_at (anal, 0x101, R_META_TYPE_ANY, NULL);
mu_assert_null (item, "get item");
r_anal_free (anal);
mu_end;
}
bool test_meta_get_in() {
RAnal *anal = r_anal_new ();
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
RIntervalNode *node = r_meta_get_in (anal, 0x100, R_META_TYPE_COMMENT);
mu_assert_notnull (node, "get item");
RAnalMetaItem *item = node->data;
mu_assert_streq (item->str, "vera gemini", "get contents");
node = r_meta_get_in (anal, 0xff, R_META_TYPE_COMMENT);
mu_assert_null (node, "get item");
node = r_meta_get_in (anal, 0x101, R_META_TYPE_COMMENT);
mu_assert_null (node, "get item");
node = r_meta_get_in (anal, 0x100, R_META_TYPE_DATA);
mu_assert_notnull (node, "get item");
item = node->data;
mu_assert_eq (item->type, R_META_TYPE_DATA, "get contents");
node = r_meta_get_in (anal, 0xff, R_META_TYPE_DATA);
mu_assert_null (node, "get item");
node = r_meta_get_in (anal, 0x103, R_META_TYPE_DATA);
mu_assert_notnull (node, "get item");
item = node->data;
mu_assert_eq (item->type, R_META_TYPE_DATA, "get contents");
node = r_meta_get_in (anal, 0x104, R_META_TYPE_DATA);
mu_assert_null (node, "get item");
node = r_meta_get_in (anal, 0x103, R_META_TYPE_ANY);
mu_assert_notnull (node, "get item");
item = node->data;
mu_assert_eq (item->type, R_META_TYPE_DATA, "get contents");
node = r_meta_get_in (anal, 0x100, R_META_TYPE_ANY);
mu_assert_notnull (node, "get item");
// which one we get is undefined here (intended)
r_anal_free (anal);
mu_end;
}
bool test_meta_get_all_at() {
RAnal *anal = r_anal_new ();
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF8, 0x200, 0x30, "true confessions");
RPVector *items = r_meta_get_all_at (anal, 0x100);
mu_assert_eq (r_pvector_len (items), 2, "all count");
void **it;
bool found[2] = { 0 };
r_pvector_foreach (items, it) {
RAnalMetaItem *item = ((RIntervalNode *)*it)->data;
switch (item->type) {
case R_META_TYPE_DATA:
found[0] = true;
break;
case R_META_TYPE_COMMENT:
found[1] = true;
break;
default:
break;
}
}
mu_assert ("meta 0", found[0]);
mu_assert ("meta 1", found[1]);
r_pvector_free (items);
items = r_meta_get_all_at (anal, 0xff);
mu_assert_eq (r_pvector_len (items), 0, "all count");
r_pvector_free (items);
items = r_meta_get_all_at (anal, 0x101);
mu_assert_eq (r_pvector_len (items), 0, "all count");
r_pvector_free (items);
r_anal_free (anal);
mu_end;
}
bool test_meta_get_all_in() {
RAnal *anal = r_anal_new ();
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF8, 0x200, 0x30, "true confessions");
RPVector *items = r_meta_get_all_in (anal, 0x100, R_META_TYPE_ANY);
mu_assert_eq (r_pvector_len (items), 2, "all count");
void **it;
bool found[2] = { 0 };
r_pvector_foreach (items, it) {
RAnalMetaItem *item = ((RIntervalNode *)*it)->data;
switch (item->type) {
case R_META_TYPE_DATA:
found[0] = true;
break;
case R_META_TYPE_COMMENT:
found[1] = true;
break;
default:
break;
}
}
mu_assert ("meta 0", found[0]);
mu_assert ("meta 1", found[1]);
r_pvector_free (items);
items = r_meta_get_all_in (anal, 0x100, R_META_TYPE_COMMENT);
mu_assert_eq (r_pvector_len (items), 1, "all count");
RAnalMetaItem *item = ((RIntervalNode *)r_pvector_at (items, 0))->data;
mu_assert_streq (item->str, "vera gemini", "contents");
r_pvector_free (items);
items = r_meta_get_all_in (anal, 0x100, R_META_TYPE_DATA);
mu_assert_eq (r_pvector_len (items), 1, "all count");
item = ((RIntervalNode *)r_pvector_at (items, 0))->data;
mu_assert_eq (item->type, R_META_TYPE_DATA, "contents");
r_pvector_free (items);
items = r_meta_get_all_in (anal, 0xff, R_META_TYPE_ANY);
mu_assert_eq (r_pvector_len (items), 0, "all count");
r_pvector_free (items);
items = r_meta_get_all_in (anal, 0x101, R_META_TYPE_COMMENT);
mu_assert_eq (r_pvector_len (items), 0, "all count");
r_pvector_free (items);
items = r_meta_get_all_in (anal, 0x103, R_META_TYPE_DATA);
mu_assert_eq (r_pvector_len (items), 1, "all count");
item = ((RIntervalNode *)r_pvector_at (items, 0))->data;
mu_assert_eq (item->type, R_META_TYPE_DATA, "contents");
r_pvector_free (items);
items = r_meta_get_all_in (anal, 0x104, R_META_TYPE_DATA);
mu_assert_eq (r_pvector_len (items), 0, "all count");
r_pvector_free (items);
r_anal_free (anal);
mu_end;
}
bool test_meta_get_all_intersect() {
RAnal *anal = r_anal_new ();
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF8, 0x200, 0x30, "true confessions");
RPVector *items = r_meta_get_all_intersect (anal, 0x100, 1, R_META_TYPE_ANY);
mu_assert_eq (r_pvector_len (items), 2, "all count");
void **it;
bool found[2] = { 0 };
r_pvector_foreach (items, it) {
RAnalMetaItem *item = ((RIntervalNode *)*it)->data;
switch (item->type) {
case R_META_TYPE_DATA:
found[0] = true;
break;
case R_META_TYPE_COMMENT:
found[1] = true;
break;
default:
break;
}
}
mu_assert ("meta 0", found[0]);
mu_assert ("meta 1", found[1]);
r_pvector_free (items);
items = r_meta_get_all_intersect (anal, 0x100, 1, R_META_TYPE_DATA);
mu_assert_eq (r_pvector_len (items), 1, "all count");
RAnalMetaItem *item = ((RIntervalNode *)r_pvector_at (items, 0))->data;
mu_assert_eq (item->type, R_META_TYPE_DATA, "contents");
r_pvector_free (items);
items = r_meta_get_all_intersect (anal, 0x100, 0x300, R_META_TYPE_DATA);
mu_assert_eq (r_pvector_len (items), 1, "all count");
item = ((RIntervalNode *)r_pvector_at (items, 0))->data;
mu_assert_eq (item->type, R_META_TYPE_DATA, "contents");
r_pvector_free (items);
items = r_meta_get_all_intersect (anal, 0x0, 0x300, R_META_TYPE_DATA);
mu_assert_eq (r_pvector_len (items), 1, "all count");
item = ((RIntervalNode *)r_pvector_at (items, 0))->data;
mu_assert_eq (item->type, R_META_TYPE_DATA, "contents");
r_pvector_free (items);
items = r_meta_get_all_intersect (anal, 0x0, 0x100, R_META_TYPE_DATA);
mu_assert_eq (r_pvector_len (items), 0, "all count");
r_pvector_free (items);
items = r_meta_get_all_intersect (anal, 0x103, 0x300, R_META_TYPE_DATA);
mu_assert_eq (r_pvector_len (items), 1, "all count");
item = ((RIntervalNode *)r_pvector_at (items, 0))->data;
mu_assert_eq (item->type, R_META_TYPE_DATA, "contents");
r_pvector_free (items);
items = r_meta_get_all_intersect (anal, 0x104, 0x300, R_META_TYPE_DATA);
mu_assert_eq (r_pvector_len (items), 0, "all count");
r_pvector_free (items);
r_anal_free (anal);
mu_end;
}
bool test_meta_del() {
RAnal *anal = r_anal_new ();
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF8, 0x200, 0x30, "true confessions");
r_meta_del (anal, R_META_TYPE_COMMENT, 0x100, 1);
RAnalMetaItem *item = r_meta_get_at (anal, 0x100, R_META_TYPE_COMMENT, NULL);
mu_assert_null (item, "item deleted");
item = r_meta_get_at (anal, 0x100, R_META_TYPE_DATA, NULL);
mu_assert_notnull (item, "item not deleted");
item = r_meta_get_at (anal, 0x200, R_META_TYPE_STRING, NULL);
mu_assert_notnull (item, "item not deleted");
// reset
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
r_meta_del (anal, R_META_TYPE_COMMENT, 0x0, 0x500);
item = r_meta_get_at (anal, 0x100, R_META_TYPE_COMMENT, NULL);
mu_assert_null (item, "item deleted");
item = r_meta_get_at (anal, 0x100, R_META_TYPE_DATA, NULL);
mu_assert_notnull (item, "item not deleted");
item = r_meta_get_at (anal, 0x200, R_META_TYPE_STRING, NULL);
mu_assert_notnull (item, "item not deleted");
// reset
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
r_meta_del (anal, R_META_TYPE_COMMENT, 0, UT64_MAX);
item = r_meta_get_at (anal, 0x100, R_META_TYPE_COMMENT, NULL);
mu_assert_null (item, "item deleted");
item = r_meta_get_at (anal, 0x100, R_META_TYPE_DATA, NULL);
mu_assert_notnull (item, "item not deleted");
item = r_meta_get_at (anal, 0x200, R_META_TYPE_STRING, NULL);
mu_assert_notnull (item, "item not deleted");
// reset
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
r_meta_del (anal, R_META_TYPE_ANY, 0, 0x500);
item = r_meta_get_at (anal, 0x100, R_META_TYPE_COMMENT, NULL);
mu_assert_null (item, "item deleted");
item = r_meta_get_at (anal, 0x100, R_META_TYPE_DATA, NULL);
mu_assert_null (item, "item deleted");
item = r_meta_get_at (anal, 0x200, R_META_TYPE_STRING, NULL);
mu_assert_null (item, "item deleted");
// reset
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "vera gemini");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF8, 0x200, 0x30, "true confessions");
r_meta_del (anal, R_META_TYPE_ANY, 0, UT64_MAX);
item = r_meta_get_at (anal, 0x100, R_META_TYPE_COMMENT, NULL);
mu_assert_null (item, "item deleted");
item = r_meta_get_at (anal, 0x100, R_META_TYPE_DATA, NULL);
mu_assert_null (item, "item deleted");
item = r_meta_get_at (anal, 0x200, R_META_TYPE_STRING, NULL);
mu_assert_null (item, "item deleted");
r_anal_free (anal);
mu_end;
}
bool test_meta_rebase() {
RAnal *anal = r_anal_new ();
r_meta_set (anal, R_META_TYPE_DATA, 0x200, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x200, "summer of love");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF8, 0x300, 0x30, "true confessions");
r_meta_rebase (anal, -0x100);
bool found[3] = { 0 };
size_t count = 0;
RIntervalTreeIter it;
RAnalMetaItem *item;
r_interval_tree_foreach (&anal->meta, it, item) {
count++;
RIntervalNode *node = r_interval_tree_iter_get (&it);
switch (item->type) {
case R_META_TYPE_DATA:
mu_assert_eq (node->start, 0x100, "node start");
mu_assert_eq (node->end, 0x103, "node end (inclusive)");
mu_assert_null (item->str, "no string");
mu_assert_eq (item->subtype, 0, "no subtype");
found[0] = true;
break;
case R_META_TYPE_COMMENT:
mu_assert_eq (node->start, 0x100, "node start");
mu_assert_eq (node->end, 0x100, "node end (inclusive)");
mu_assert_streq (item->str, "summer of love", "comment string");
mu_assert_eq (item->subtype, 0, "no subtype");
found[1] = true;
break;
case R_META_TYPE_STRING:
mu_assert_eq (node->start, 0x200, "node start");
mu_assert_eq (node->end, 0x22f, "node end (inclusive)");
mu_assert_streq (item->str, "true confessions", "string string");
mu_assert_eq (item->subtype, R_STRING_ENC_UTF8, "subtype");
found[2] = true;
break;
default:
break;
}
}
mu_assert_eq (count, 3, "set count");
mu_assert ("meta 0", found[0]);
mu_assert ("meta 1", found[1]);
mu_assert ("meta 2", found[2]);
r_anal_free (anal);
mu_end;
}
bool test_meta_spaces() {
RAnal *anal = r_anal_new ();
r_meta_set (anal, R_META_TYPE_DATA, 0x100, 4, NULL);
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "summer of love");
r_meta_set_with_subtype (anal, R_META_TYPE_STRING, R_STRING_ENC_UTF8, 0x200, 0x30, "true confessions");
r_spaces_set (&anal->meta_spaces, "fear");
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "reaper");
bool found[4] = { 0 };
size_t count = 0;
RIntervalTreeIter it;
RAnalMetaItem *item;
r_interval_tree_foreach (&anal->meta, it, item) {
count++;
switch (item->type) {
case R_META_TYPE_DATA:
mu_assert_null (item->space, "space");
found[0] = true;
break;
case R_META_TYPE_COMMENT:
if (item->space) {
mu_assert_streq (item->str, "reaper", "comment string");
mu_assert_ptreq (item->space, r_spaces_get (&anal->meta_spaces, "fear"), "space");
found[3] = true;
} else {
mu_assert_streq (item->str, "summer of love", "comment string");
found[1] = true;
}
break;
case R_META_TYPE_STRING:
mu_assert_null (item->space, "space");
found[2] = true;
break;
default:
break;
}
}
mu_assert_eq (count, 4, "set count");
mu_assert ("meta 0", found[0]);
mu_assert ("meta 1", found[1]);
mu_assert ("meta 2", found[2]);
mu_assert ("meta 3", found[3]);
RAnalMetaItem *reaper_item = r_meta_get_at (anal, 0x100, R_META_TYPE_ANY, NULL);
mu_assert_notnull (reaper_item, "get item");
mu_assert_streq (reaper_item->str, "reaper", "comment string");
item = r_meta_get_at (anal, 0x100, R_META_TYPE_DATA, NULL);
mu_assert_null (item, "masked by space");
RIntervalNode *node = r_meta_get_in (anal, 0x100, R_META_TYPE_COMMENT);
mu_assert_notnull (node, "get item");
mu_assert_ptreq (node->data, reaper_item, "masked by space");
node = r_meta_get_in (anal, 0x100, R_META_TYPE_DATA);
mu_assert_null (node, "masked by space");
RPVector *nodes = r_meta_get_all_at (anal, 0x100);
mu_assert_eq (r_pvector_len (nodes), 1, "all count");
mu_assert_ptreq (((RIntervalNode *)r_pvector_at (nodes, 0))->data, reaper_item, "all masked");
r_pvector_free (nodes);
nodes = r_meta_get_all_in (anal, 0x100, R_META_TYPE_ANY);
mu_assert_eq (r_pvector_len (nodes), 1, "all count");
mu_assert_ptreq (((RIntervalNode *)r_pvector_at (nodes, 0))->data, reaper_item, "all masked");
r_pvector_free (nodes);
nodes = r_meta_get_all_intersect (anal, 0x0, 0x500, R_META_TYPE_ANY);
mu_assert_eq (r_pvector_len (nodes), 1, "all count");
mu_assert_ptreq (((RIntervalNode *)r_pvector_at (nodes, 0))->data, reaper_item, "all masked");
r_pvector_free (nodes);
// delete
r_meta_del (anal, R_META_TYPE_ANY, 0, 0x500);
item = r_meta_get_at (anal, 0x100, R_META_TYPE_ANY, NULL);
mu_assert_null (item, "reaper deleted");
count = 0;
r_interval_tree_foreach (&anal->meta, it, item) {
count++;
}
mu_assert_eq (count, 3, "masked untouched");
// reset
r_meta_set_string (anal, R_META_TYPE_COMMENT, 0x100, "reaper");
r_meta_del (anal, R_META_TYPE_ANY, 0, UT64_MAX);
item = r_meta_get_at (anal, 0x100, R_META_TYPE_ANY, NULL);
mu_assert_null (item, "reaper deleted");
count = 0;
r_interval_tree_foreach (&anal->meta, it, item) {
count++;
}
mu_assert_eq (count, 3, "masked untouched");
r_anal_free (anal);
mu_end;
}
bool all_tests() {
mu_run_test(test_meta_set);
mu_run_test(test_meta_get_at);
mu_run_test(test_meta_get_in);
mu_run_test(test_meta_get_all_at);
mu_run_test(test_meta_get_all_in);
mu_run_test(test_meta_get_all_intersect);
mu_run_test(test_meta_del);
mu_run_test(test_meta_rebase);
mu_run_test(test_meta_spaces);
return tests_passed != tests_run;
}
int main(int argc, char **argv) {
return all_tests();
}