Update sdb, more work on types 't'

This commit is contained in:
pancake 2013-08-13 03:23:39 +02:00
parent c94a4c8d94
commit 05df20f411
10 changed files with 148 additions and 81 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -0,0 +1 @@
#define SDB_VERSION "0.6.6"

View File

@ -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 = ',';

View File

@ -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;