Initial implementation of flag tags

This commit is contained in:
pancake 2018-05-11 04:39:08 +02:00
parent 44833bd342
commit 04108092f4
7 changed files with 88 additions and 2 deletions

View File

@ -44,6 +44,7 @@ static const char *help_msg_f[] = {
"fR","[?] [f] [t] [m]","relocate all flags matching f&~m 'f'rom, 't'o, 'm'ask",
"fs","[?]+-*","manage flagspaces",
"fS","[on]","sort flags by offset or name",
"ft","[?]+-*","flag tags, useful to find all flags matching some words",
"fV","[*-] [nkey] [offset]","dump/restore visual marks (mK/'K)",
"fx","[d]","show hexdump (or disasm) of flag:flagsize",
"fq","","list flags in quiet mode",
@ -210,6 +211,35 @@ static int flag_to_flag(RCore *core, const char *glob) {
return 0;
}
static void cmd_flag_tags (RCore *core, const char *input) {
const char *arg = r_str_trim_ro (input + 2);
if (!*arg) {
eprintf ("list tags\n");
return;
}
if (*arg == '?') {
eprintf ("Usage: ft [k] [v ...]\n");
eprintf (" ft string strcpy strlen ... # set words for the 'string' tag\n");
eprintf (" ft string # get offsets of all matching flags\n");
eprintf (" ft # list all tags\n");
return;
}
char *arg1 = strchr (arg, ' ');
if (arg1) {
*arg1 = 0;
const char *a1 = r_str_trim_ro (arg1 + 1);
r_flag_tags_set (core->flags, arg, a1);
} else {
RListIter *iter;
RFlagItem *flag;
RList *flags = r_flag_tags_get (core->flags, arg);
r_list_foreach (flags, iter, flag) {
r_cons_printf ("0x%08"PFMT64x"\n", flag->offset);
// r_cons_printf ("0x%08"PFMT64x" %s\n", flag->offset, flag->name);
}
}
}
static void flag_ordinals(RCore *core, const char *str) {
RFlagItem *flag;
RListIter *iter;
@ -602,6 +632,9 @@ rep:
eprintf ("Missing arguments\n");
}
break;
case 't':
cmd_flag_tags (core, input);
break;
case 'S':
r_flag_sort (core->flags, (input[1]=='n'));
break;

View File

@ -2,6 +2,6 @@ include ../config.mk
NAME=r_flag
DEPS=r_util
OBJS=flag.o sort.o spaces.o zones.o
OBJS=flag.o sort.o spaces.o zones.o tags.o
include ../rules.mk

View File

@ -130,6 +130,7 @@ R_API RFlag * r_flag_new() {
#else
f->zones = NULL;
#endif
f->tags = sdb_new0 ();
f->flags = r_list_new ();
if (!f->flags) {
r_flag_free (f);

View File

@ -1,6 +1,7 @@
files = [
'flag.c',
'sort.c',
'tags.c',
'spaces.c',
'zones.c'
]

44
libr/flag/tags.c Normal file
View File

@ -0,0 +1,44 @@
/* radare - LGPL - Copyright 2018 - pancake */
#include <r_flag.h>
R_API RList *r_flag_tags_set(RFlag *f, const char *name, const char *words) {
const char *k = sdb_fmt ("tag.%s", name);
sdb_set (f->tags, k, words, -1);
return NULL;
}
R_API RList *r_flag_tags_list(RFlag *f) {
RList *res = r_list_newf (free);
SdbList *o = sdb_foreach_list (f->tags, false);
SdbListIter *iter;
const char *tag;
ls_foreach (o, iter, tag) {
r_list_append (res, (void *)tag);
}
ls_free (o);
return res;
}
R_API void r_flag_tags_reset(RFlag *f, const char *name) {
sdb_reset (f->tags);
}
R_API RList *r_flag_tags_get(RFlag *f, const char *name) {
const char *k = sdb_fmt ("tag.%s", name);
RListIter *iter, *iter2;
const char *word;
RFlagItem *flag;
char *words = sdb_get (f->tags, k, NULL);
RList *res = r_list_newf (NULL);
RList *list = r_str_split_list (words, " ");
r_list_foreach (f->flags, iter2, flag) {
r_list_foreach (list, iter, word) {
if (r_str_glob (flag->name, word)) {
r_list_append (res, flag);
}
}
}
r_list_free (list);
return res;
}

View File

@ -53,6 +53,7 @@ typedef struct r_flag_t {
int space_idx; /* index of the selected space in spaces array */
bool space_strict; /* when true returned flag items must belong to the selected space */
char *spaces[R_FLAG_SPACES_MAX]; /* array of flag spaces */
Sdb *tags;
RNum *num;
RSkipList *by_off; /* flags sorted by offset, value=RFlagsAtOffset */
SdbHash *ht_name; /* hashmap key=item name, value=RList of items */
@ -130,6 +131,11 @@ R_API bool r_flag_space_pop(RFlag *f);
R_API int r_flag_space_push(RFlag *f, const char *name);
R_API int r_flag_space_stack_list(RFlag *f, int mode);
/* tags */
R_API RList *r_flag_tags_set(RFlag *f, const char *name, const char *words);
R_API void r_flag_tags_reset(RFlag *f, const char *name);
R_API RList *r_flag_tags_get(RFlag *f, const char *name);
/* zones */
R_API void r_flag_zone_item_free(void *a);

View File

@ -73,7 +73,8 @@ else
@-if [ -f p/Makefile ] ; then (echo "DIR ${NAME}/p"; cd p && ${MAKE}) ; fi
endif
ifeq ($(WITHPIC),1)
ifeq (1,1)
#$(WITHPIC),1)
$(LIBSO): $(EXTRA_TARGETS) ${WFD} ${OBJS} ${SHARED_OBJ}
@for a in ${OBJS} ${SHARED_OBJ} ${SRC}; do \
do=0 ; [ ! -e ${LIBSO} ] && do=1 ; \