mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-22 13:51:30 +00:00
Update sdb, more work on types 't'
This commit is contained in:
parent
c94a4c8d94
commit
05df20f411
@ -23,6 +23,17 @@ static RAnalVarType anal_default_vartypes[] =
|
||||
{ NULL, NULL, 0 }};
|
||||
*/
|
||||
|
||||
static void r_anal_type_init(RAnal *anal) {
|
||||
Sdb *D = anal->sdb_types;
|
||||
sdb_set (D, "type.unsigned int", "i", 0);
|
||||
sdb_set (D, "type.int", "d", 0);
|
||||
sdb_set (D, "type.long", "x", 0);
|
||||
sdb_set (D, "type.void *", "p", 0);
|
||||
sdb_set (D, "type.char", "x", 0);
|
||||
sdb_set (D, "type.char*", "*z", 0);
|
||||
sdb_set (D, "type.const char*", "*z", 0);
|
||||
}
|
||||
|
||||
R_API RAnal *r_anal_new() {
|
||||
int i;
|
||||
RAnalPlugin *static_plugin;
|
||||
@ -32,6 +43,7 @@ R_API RAnal *r_anal_new() {
|
||||
anal->decode = R_TRUE; // slow slow if not used
|
||||
anal->sdb_xrefs = NULL;
|
||||
anal->sdb_types = sdb_new (NULL, 0);
|
||||
r_anal_type_init (anal);
|
||||
r_anal_xrefs_init (anal);
|
||||
anal->diff_ops = 0;
|
||||
anal->diff_thbb = R_ANAL_THRESHOLDBB;
|
||||
|
@ -3,13 +3,27 @@
|
||||
#include "r_anal.h"
|
||||
|
||||
R_API void r_anal_type_del(RAnal *anal, const char *name) {
|
||||
Sdb *D = anal->sdb_types;
|
||||
const char *type = sdb_getc (D, name, 0);
|
||||
//sdb_getcf (D, "%s.%s", type, name);
|
||||
// foreach element, delete row
|
||||
int n;
|
||||
char *p, str[128], str2[128];
|
||||
Sdb *DB = anal->sdb_types;
|
||||
const char *kind = sdb_getc (DB, name, 0);
|
||||
snprintf (str, sizeof (str), "%s.%s", kind, name);
|
||||
eprintf ("(((%s)))\n", str);
|
||||
|
||||
#define SDB_FOREACH(x,y,z) for (z = 0; (p = sdb_aget (x, y, z, NULL)); z++)
|
||||
#define SDB_FOREACH_NEXT() free(p)
|
||||
SDB_FOREACH (DB, str, n) {
|
||||
snprintf (str2, sizeof (str2), "%s.%s", str, p);
|
||||
sdb_remove (DB, str2, 0);
|
||||
SDB_FOREACH_NEXT ();
|
||||
}
|
||||
sdb_set (DB, name, NULL, 0);
|
||||
sdb_remove (DB, name, 0);
|
||||
sdb_remove (DB, str, 0);
|
||||
}
|
||||
|
||||
R_API char* r_anal_type_to_str(RAnal *a, RAnalType *t, const char *sep) {
|
||||
// convert to C text... maybe that should be in format string..
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -29,3 +43,63 @@ R_API void r_anal_type_header (RAnal *anal, const char *hdr) {
|
||||
R_API void r_anal_type_define (RAnal *anal, const char *key, const char *value) {
|
||||
|
||||
}
|
||||
|
||||
R_API int r_anal_type_link (RAnal *anal, const char *val, ut64 addr) {
|
||||
char var[128];
|
||||
if (sdb_getc (anal->sdb_types, val, 0)) {
|
||||
sprintf (var, "link.%08"PFMT64x, addr);
|
||||
sdb_set (anal->sdb_types, var, val, 0);
|
||||
return R_TRUE;
|
||||
}
|
||||
eprintf ("Cannot find type\n");
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
static void filter_type(char *t) {
|
||||
for (;*t; t++) {
|
||||
if (*t == ' ')
|
||||
*t = '_';
|
||||
// memmove (t, t+1, strlen (t));
|
||||
}
|
||||
}
|
||||
|
||||
R_API char *r_anal_type_format (RAnal *anal, const char *t) {
|
||||
int n;
|
||||
char *p, var[128], var2[128], var3[128];
|
||||
char *fmt = NULL;
|
||||
char *vars = NULL;
|
||||
Sdb *DB = anal->sdb_types;
|
||||
const char *kind = sdb_getc (DB, t, NULL);
|
||||
if (!kind) return NULL;
|
||||
// only supports struct atm
|
||||
if (strcmp (kind, "struct"))
|
||||
return NULL;
|
||||
snprintf (var, sizeof (var), "%s.%s", kind, t);
|
||||
// assumes var list is sorted by offset.. should do more checks here
|
||||
for (n = 0; (p = sdb_aget (DB, var, n, NULL)); n++) {
|
||||
const char *tfmt;
|
||||
char *type;
|
||||
int off;
|
||||
int size;
|
||||
snprintf (var2, sizeof (var2), "%s.%s", var, p);
|
||||
type = sdb_aget (DB, var2, 0, NULL);
|
||||
if (type) {
|
||||
off = sdb_agetn (DB, var2, 1, NULL);
|
||||
size = sdb_agetn (DB, var2, 2, NULL);
|
||||
snprintf (var3, sizeof (var3), "type.%s", type);
|
||||
tfmt = sdb_getc (DB, var3, NULL);
|
||||
if (tfmt) {
|
||||
filter_type (type);
|
||||
fmt = r_str_concat (fmt, tfmt);
|
||||
vars = r_str_concat (vars, p);
|
||||
vars = r_str_concat (vars, " ");
|
||||
} else eprintf ("Cannot resolve type '%s'\n", type);
|
||||
}
|
||||
free (type);
|
||||
free (p);
|
||||
}
|
||||
fmt = r_str_concat (fmt, " ");
|
||||
fmt = r_str_concat (fmt, vars);
|
||||
free (vars);
|
||||
return fmt;
|
||||
}
|
||||
|
@ -1,37 +1,44 @@
|
||||
/* radare - LGPL - Copyright 2009-2013 - pancake, Anton Kochkov */
|
||||
|
||||
|
||||
static void cmd_type_init(RCore *core) {
|
||||
Sdb *D = core->anal->sdb_types;
|
||||
sdb_set (D, "type.unsigned int", "i", 0);
|
||||
sdb_set (D, "type.int", "d", 0);
|
||||
sdb_set (D, "type.long", "x", 0);
|
||||
sdb_set (D, "type.char", "x", 0);
|
||||
sdb_set (D, "type.char*", "*z", 0);
|
||||
sdb_set (D, "type.const char*", "*z", 0);
|
||||
static void show_help() {
|
||||
eprintf ("Usage: t[-LCvsdfm?] [...]\n"
|
||||
" t list all loaded types\n"
|
||||
" t* list types info in r2 commands\n"
|
||||
" t- [name] delete type by its name.\n"
|
||||
" t-* remove all types\n"
|
||||
//". Use t-! to open $EDITOR\n"
|
||||
" t [type] show given type in 'pf' syntax\n"
|
||||
" tf [path] load types from C header file\n"
|
||||
" tf - open cfg.editor to load types\n"
|
||||
" td int foo(int a) parse oneliner type definition\n"
|
||||
" tv addr view linked type at given address\n"
|
||||
" tl [type] [addr] link type to a given address\n");
|
||||
}
|
||||
|
||||
static int cmd_type(void *data, const char *input) {
|
||||
RCore *core = (RCore*)data;
|
||||
char pcmd[512];
|
||||
RAnalType *t = NULL;
|
||||
|
||||
switch (input[0]) {
|
||||
// t [typename] - show given type in C syntax
|
||||
#if 0
|
||||
case ' ':
|
||||
{
|
||||
const char *tname = input + 1;
|
||||
t = r_anal_type_find (core->anal, tname);
|
||||
if (t == NULL) eprintf ("Type %s not found!\n", tname);
|
||||
else r_anal_type_to_str (core->anal, t, "; ");
|
||||
char *fmt = r_anal_type_format (core->anal, input +1);
|
||||
if (fmt) {
|
||||
r_cons_printf ("pf %s\n", fmt);
|
||||
free (fmt);
|
||||
} else eprintf ("Cannot find '%s' type\n", input+1);
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
// t* - list all types in 'pf' syntax
|
||||
case '*':
|
||||
r_anal_type_list (core->anal, R_ANAL_TYPE_ANY, 1);
|
||||
break;
|
||||
#endif
|
||||
case 0:
|
||||
// TODO: use r_cons here
|
||||
sdb_list (core->anal->sdb_types);
|
||||
break;
|
||||
case 'f':
|
||||
@ -61,9 +68,11 @@ static int cmd_type(void *data, const char *input) {
|
||||
// td - parse string with cparse engine and load types from it
|
||||
case 'd':
|
||||
if (input[1] == ' ') {
|
||||
const char *string = input + 2;
|
||||
char tmp[256];
|
||||
snprintf (tmp, sizeof (tmp), "%s;", input+2);
|
||||
//const char *string = input + 2;
|
||||
//r_anal_str_to_type (core->anal, string);
|
||||
char *out = r_parse_c_string (string);
|
||||
char *out = r_parse_c_string (tmp);
|
||||
if (out) {
|
||||
r_cons_strcat (out);
|
||||
sdb_query_lines (core->anal->sdb_types, out);
|
||||
@ -77,81 +86,42 @@ static int cmd_type(void *data, const char *input) {
|
||||
// tl - link a type to an address
|
||||
case 'l':
|
||||
{
|
||||
char var[128], *ptr = NULL;
|
||||
ut64 addr = core->offset;
|
||||
ptr = strchr (input + 2, ' ');
|
||||
ut64 addr = r_num_math (core->num, input+2);
|
||||
char *ptr = strchr (input + 2, ' ');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
addr = r_num_math (core->num, ptr + 1);
|
||||
*ptr = '\0';
|
||||
if (addr > 0) {
|
||||
if (sdb_getc (core->anal->sdb_types, input+2,0)) {
|
||||
sprintf (var, "link.%08"PFMT64x, addr);
|
||||
sdb_set (core->anal->sdb_types, var, input+2, 0);
|
||||
} else eprintf ("Cannot find type\n");
|
||||
r_anal_type_link (core->anal, input+2, addr);
|
||||
} else eprintf ("Wrong address to link!\n");
|
||||
} else
|
||||
eprintf("Usage: tl[...]\n"
|
||||
" tl [typename] ([addr])@[addr|function]\n");
|
||||
" tl [typename|addr] ([addr])@[addr|function]\n");
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
// tv - get/set type value linked to a given address
|
||||
case 'v':
|
||||
break;
|
||||
case 'h':
|
||||
switch (input[1]) {
|
||||
case ' ':
|
||||
break;
|
||||
/* Convert type into format string */
|
||||
case '*':
|
||||
break;
|
||||
default:
|
||||
eprintf ("Usage: th[..]\n"
|
||||
"th [path] [name] : show definition of type\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '-':
|
||||
if (input[1]!='*') {
|
||||
ut64 n = r_num_math (core->num, input + ((input[1] == ' ') ? 2 : 1));
|
||||
eprintf ("val 0x%"PFMT64x"\n", n);
|
||||
//TODO r_anal_type_del (core->anal->types, R_ANAL_TYPE_ANY, core->offset, i, "");
|
||||
if (input[1]=='*') {
|
||||
eprintf ("TODO\n");
|
||||
} else {
|
||||
const char *ntr, *name = input + 2;
|
||||
ntr = strchr(name, ' ');
|
||||
if (ntr && !ntr[1]) {
|
||||
const char *ntr, *name = input + 1;
|
||||
if (*name==' ') name++;
|
||||
ntr = strchr (name, ' ');
|
||||
if (*name) {
|
||||
r_anal_type_del (core->anal, name);
|
||||
} else
|
||||
eprintf ("Usage: t- name\n"
|
||||
"t- name : delete type by its name\n");
|
||||
} else eprintf ("Usage: t- name\n"
|
||||
"t- name : delete type by its name\n");
|
||||
}
|
||||
break;
|
||||
// t - list all types in C syntax
|
||||
case '\0':
|
||||
{
|
||||
RListIter *k;
|
||||
RAnalType *t;
|
||||
r_list_foreach (core->anal->types, k, t) {
|
||||
const char *str = r_anal_type_to_str (core->anal, t, "; ");
|
||||
r_cons_printf ("%s\n", str);
|
||||
}
|
||||
}
|
||||
// tv - get/set type value linked to a given address
|
||||
case 'v':
|
||||
snprintf (pcmd, sizeof (pcmd), "pf `t %s`", input+2);
|
||||
r_core_cmd0 (core, pcmd);
|
||||
break;
|
||||
#endif
|
||||
case '?':
|
||||
if (input[1]) {
|
||||
sdb_query (core->anal->sdb_types, input+1);
|
||||
} else
|
||||
eprintf (
|
||||
"Usage: t[-LCvsdfm?] [...]\n"
|
||||
" t # list all loaded types\n"
|
||||
" t* # list types info in r2 commands\n"
|
||||
" t- [name] # delete type by its name. Use t-* to remove all types. Use t-! to open $EDITOR\n"
|
||||
" t [type] # show given type in C syntax\n"
|
||||
" tf [path] # load types from C header file\n"
|
||||
" tf - # open cfg.editor to load types\n"
|
||||
" td int foo(int a); # parse oneliner type definition\n"
|
||||
" tl [type] [addr] # link type to a given address\n");
|
||||
} else show_help();
|
||||
|
||||
break;
|
||||
}
|
||||
return R_TRUE;
|
||||
|
@ -691,6 +691,9 @@ R_API RAnalType *r_anal_type_loadfile(RAnal *a, const char *path);
|
||||
R_API void r_anal_type_define (RAnal *anal, const char *key, const char *value);
|
||||
R_API void r_anal_type_header (RAnal *anal, const char *hdr);
|
||||
|
||||
R_API int r_anal_type_link (RAnal *anal, const char *val, ut64 addr);
|
||||
R_API char *r_anal_type_format (RAnal *anal, const char *t);
|
||||
|
||||
/* anal.c */
|
||||
R_API RAnal *r_anal_new();
|
||||
R_API void r_anal_free(RAnal *r);
|
||||
|
@ -188,7 +188,8 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, int len, const char
|
||||
idx--;
|
||||
continue;
|
||||
case 'p':
|
||||
tmp = (sizeof (void*)==8)? 'q': 'x';
|
||||
tmp = (p->bits==64)?'q': 'x';
|
||||
//tmp = (sizeof (void*)==8)? 'q': 'x';
|
||||
break;
|
||||
case '?': // help
|
||||
print_format_help (p);
|
||||
|
@ -549,8 +549,11 @@ R_API char *r_str_prefix(char *ptr, const char *string) {
|
||||
// TODO: use vararg here?
|
||||
R_API char *r_str_concat(char *ptr, const char *string) {
|
||||
int slen, plen;
|
||||
if (ptr == NULL)
|
||||
if (!string && ptr)
|
||||
return ptr;
|
||||
if (string && !ptr)
|
||||
return strdup (string);
|
||||
if (!ptr) ptr = strdup (string);
|
||||
plen = strlen (ptr);
|
||||
slen = strlen (string);
|
||||
ptr = realloc (ptr, slen + plen + 1);
|
||||
|
@ -223,6 +223,7 @@ void ht_remove_entry(SdbHash *ht, SdbHashEntry *entry) {
|
||||
if (!entry)
|
||||
return;
|
||||
if (!rehash && entry->iter) {
|
||||
// XXX: ls_delete not working wtf
|
||||
ls_delete (ht->list, entry->iter);
|
||||
//free (entry->iter);
|
||||
entry->iter = NULL;
|
||||
|
1
shlr/sdb/src/sdb-version.h
Normal file
1
shlr/sdb/src/sdb-version.h
Normal file
@ -0,0 +1 @@
|
||||
#define SDB_VERSION "0.6.6"
|
@ -254,6 +254,8 @@ SDB_VISIBLE void sdb_list (Sdb* s) {
|
||||
SdbKv *kv;
|
||||
SdbListIter *iter;
|
||||
ls_foreach (s->ht->list, iter, kv) {
|
||||
if (!kv->value || !*kv->value)
|
||||
continue;
|
||||
if (strchr (kv->value, SDB_RS)) {
|
||||
char *o, *p = strdup (kv->value);
|
||||
for (o=p; *o; o++) if (*o==SDB_RS) *o = ',';
|
||||
|
@ -1080,7 +1080,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
goto the_end;
|
||||
}
|
||||
|
||||
if (!ext[0] || !PATHCMP(ext, "c") || !PATHCMP(ext, "cparse")) {
|
||||
if (!ext[0] || !PATHCMP(ext, "c") || !PATHCMP(ext, "h") || !PATHCMP(ext, "cparse")) {
|
||||
/* C file assumed */
|
||||
ret = tcc_compile(s1);
|
||||
goto the_end;
|
||||
|
Loading…
x
Reference in New Issue
Block a user