mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-02 19:26:43 +00:00
Compute struct/union size in tsj/tuj ##format
This commit is contained in:
parent
f51e600340
commit
86e0862103
@ -334,6 +334,48 @@ static void cmd_type_noreturn(RCore *core, const char *input) {
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Save the size of the given datatype in sdb
|
||||
* \param sdb_types pointer to the sdb for types
|
||||
* \param name the datatype whose size if to be stored
|
||||
*/
|
||||
static void save_type_size(Sdb *sdb_types, char *name) {
|
||||
char *type = NULL;
|
||||
r_return_if_fail (sdb_types && name);
|
||||
if (!sdb_exists (sdb_types, name) || !(type = sdb_get (sdb_types, name, 0))) {
|
||||
return;
|
||||
}
|
||||
char *type_name_size = r_str_newf ("%s.%s.%s", type, name, "size");
|
||||
int size = r_type_get_bitsize (sdb_types, name);
|
||||
sdb_set (sdb_types, type_name_size, sdb_fmt ("%d", size), 0);
|
||||
free (type);
|
||||
free (type_name_size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Save the sizes of the datatypes which have been parsed
|
||||
* \param core pointer to radare2 core
|
||||
* \param parsed the parsed c string in sdb format
|
||||
*/
|
||||
R_API void save_parsed_type_size(RCore *core, const char *parsed) {
|
||||
r_return_if_fail (core && core->anal && parsed);
|
||||
char *str = strdup (parsed);
|
||||
if (str) {
|
||||
char *ptr = NULL;
|
||||
int offset = 0;
|
||||
while ((ptr = strstr (str + offset, "=struct\n")) || (ptr = strstr (str + offset, "=union\n"))) {
|
||||
*ptr = 0;
|
||||
char *name = ptr;
|
||||
while (name - 1 >= str && *(name - 1) != '\n') {
|
||||
name--;
|
||||
}
|
||||
save_type_size (core->anal->sdb_types, name);
|
||||
offset = ptr + 1 - str;
|
||||
}
|
||||
free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void save_parsed_type(RCore *core, const char *parsed) {
|
||||
if (!core || !core->anal || !parsed) {
|
||||
return;
|
||||
@ -353,6 +395,7 @@ static void save_parsed_type(RCore *core, const char *parsed) {
|
||||
r_core_cmdf (core, "\"t- %s\"", name);
|
||||
// Now add the type to sdb.
|
||||
sdb_query_lines (core->anal->sdb_types, parsed);
|
||||
save_parsed_type_size (core, parsed);
|
||||
}
|
||||
free (type);
|
||||
}
|
||||
@ -375,6 +418,46 @@ static int stdifstruct(void *user, const char *k, const char *v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief print the data types details in JSON format
|
||||
* \param TDB pointer to the sdb for types
|
||||
* \param filter a callback function for the filtering
|
||||
* \return 1 if success, 0 if failure
|
||||
*/
|
||||
static int print_struct_union_list_json(Sdb *TDB, SdbForeachCallback filter) {
|
||||
PJ *pj = pj_new ();
|
||||
if (!pj) {
|
||||
return 0;
|
||||
}
|
||||
SdbList *l = sdb_foreach_list_filter (TDB, filter, true);
|
||||
SdbListIter *it;
|
||||
SdbKv *kv;
|
||||
|
||||
pj_a (pj); // [
|
||||
ls_foreach (l, it, kv) {
|
||||
const char *k = sdbkv_key (kv);
|
||||
if (!k || !*k) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pj_o (pj); // {
|
||||
char *sizecmd = r_str_newf ("%s.%s.size", sdbkv_value (kv), k);
|
||||
char *size_s = sdb_querys (TDB, NULL, -1, sizecmd);
|
||||
pj_ks (pj, "type", k); // key value pair of string and string
|
||||
pj_ki (pj, "size", size_s ? atoi (size_s) : 0); // key value pair of string and int
|
||||
pj_end (pj); // }
|
||||
|
||||
free (sizecmd);
|
||||
free (size_s);
|
||||
}
|
||||
pj_end (pj); // ]
|
||||
|
||||
r_cons_println (pj_string (pj));
|
||||
pj_free (pj);
|
||||
ls_free (l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int printkey_cb(void *user, const char *k, const char *v) {
|
||||
r_cons_println (k);
|
||||
return 1;
|
||||
@ -784,12 +867,12 @@ static int cmd_type(void *data, const char *input) {
|
||||
ls_free (l);
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
case 'j': // "tuj"
|
||||
if (input[2]) {
|
||||
showFormat (core, r_str_trim_ro (input + 2), 'j');
|
||||
r_cons_newline ();
|
||||
} else {
|
||||
print_keys (TDB, core, stdifunion, printkey_json_cb, true);
|
||||
print_struct_union_list_json (TDB, stdifunion);
|
||||
}
|
||||
break;
|
||||
case 'c':{
|
||||
@ -934,7 +1017,7 @@ static int cmd_type(void *data, const char *input) {
|
||||
showFormat (core, r_str_trim_ro (input + 2), 'j');
|
||||
r_cons_newline ();
|
||||
} else {
|
||||
print_keys (TDB, core, stdifstruct, printkey_json_cb, true);
|
||||
print_struct_union_list_json (TDB, stdifstruct);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -498,6 +498,7 @@ R_API void r_core_print_func_args(RCore *core);
|
||||
R_API char *resolve_fcn_name(RAnal *anal, const char * func_name);
|
||||
|
||||
R_API int r_core_get_stacksz (RCore *core, ut64 from, ut64 to);
|
||||
R_API void save_parsed_type_size(RCore *core, const char *parsed);
|
||||
|
||||
/* anal.c */
|
||||
R_API RAnalOp* r_core_anal_op(RCore *core, ut64 addr, int mask);
|
||||
|
@ -143,8 +143,8 @@ R_API int r_type_get_bitsize(Sdb *TDB, const char *type) {
|
||||
query = sdb_fmt ("type.%s.size", tmptype);
|
||||
return sdb_num_get (TDB, query, 0); // returns size in bits
|
||||
}
|
||||
if (!strcmp (t, "struct")) {
|
||||
query = sdb_fmt ("struct.%s", tmptype);
|
||||
if (!strcmp (t, "struct") || !strcmp (t, "union")) {
|
||||
query = sdb_fmt ("%s.%s", t, tmptype);
|
||||
char *members = sdb_get (TDB, query, 0);
|
||||
char *next, *ptr = members;
|
||||
int ret = 0;
|
||||
@ -154,7 +154,7 @@ R_API int r_type_get_bitsize(Sdb *TDB, const char *type) {
|
||||
if (!name) {
|
||||
break;
|
||||
}
|
||||
query = sdb_fmt ("struct.%s.%s", tmptype, name);
|
||||
query = sdb_fmt ("%s.%s.%s", t, tmptype, name);
|
||||
char *subtype = sdb_get (TDB, query, 0);
|
||||
if (!subtype) {
|
||||
break;
|
||||
@ -170,7 +170,12 @@ R_API int r_type_get_bitsize(Sdb *TDB, const char *type) {
|
||||
if (elements == 0) {
|
||||
elements = 1;
|
||||
}
|
||||
ret += r_type_get_bitsize (TDB, subtype) * elements;
|
||||
if (!strcmp (t, "struct")) {
|
||||
ret += r_type_get_bitsize (TDB, subtype) * elements;
|
||||
} else {
|
||||
int sz = r_type_get_bitsize (TDB, subtype) * elements;
|
||||
ret = sz > ret ? sz : ret;
|
||||
}
|
||||
}
|
||||
free (subtype);
|
||||
ptr = next;
|
||||
|
Loading…
x
Reference in New Issue
Block a user