diff --git a/libr/anal/anal.c b/libr/anal/anal.c index 9899a92a1c..9adca89de5 100644 --- a/libr/anal/anal.c +++ b/libr/anal/anal.c @@ -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; diff --git a/libr/anal/types.c b/libr/anal/types.c index f8f7dd7afe..13ac478eb8 100644 --- a/libr/anal/types.c +++ b/libr/anal/types.c @@ -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; +} diff --git a/libr/core/cmd_type.c b/libr/core/cmd_type.c index bfce49a02a..07e8c765bb 100644 --- a/libr/core/cmd_type.c +++ b/libr/core/cmd_type.c @@ -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; diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index d103b2922d..13a92fbf0a 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -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); diff --git a/libr/util/p_format.c b/libr/util/p_format.c index ea27bed47c..1091c4d3ca 100644 --- a/libr/util/p_format.c +++ b/libr/util/p_format.c @@ -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); diff --git a/libr/util/str.c b/libr/util/str.c index bf3222f7af..2a5c6787be 100644 --- a/libr/util/str.c +++ b/libr/util/str.c @@ -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); diff --git a/shlr/sdb/src/ht.c b/shlr/sdb/src/ht.c index 527b65a079..9286d8d2ce 100644 --- a/shlr/sdb/src/ht.c +++ b/shlr/sdb/src/ht.c @@ -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; diff --git a/shlr/sdb/src/sdb-version.h b/shlr/sdb/src/sdb-version.h new file mode 100644 index 0000000000..fba42b2078 --- /dev/null +++ b/shlr/sdb/src/sdb-version.h @@ -0,0 +1 @@ +#define SDB_VERSION "0.6.6" diff --git a/shlr/sdb/src/sdb.c b/shlr/sdb/src/sdb.c index 4e9b8b4ef5..5d416b7084 100644 --- a/shlr/sdb/src/sdb.c +++ b/shlr/sdb/src/sdb.c @@ -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 = ','; diff --git a/shlr/tcc/libtcc.c b/shlr/tcc/libtcc.c index 2bdf259130..e4f3ce49b7 100644 --- a/shlr/tcc/libtcc.c +++ b/shlr/tcc/libtcc.c @@ -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;