Intial work for union support (#10340)

This commit is contained in:
sivaramaaa 2018-06-14 03:26:45 +05:30 committed by radare
parent d43bc02f99
commit 17a77857b9
3 changed files with 43 additions and 15 deletions

View File

@ -136,6 +136,8 @@ static const char *help_msg_ts[] = {
static const char *help_msg_tu[] = {
"Usage: tu[...]", "", "",
"tu", "", "List all loaded unions",
"tu", " [type]", "Show pf format string for given union",
"tu*", " [type]", "Show pf.<name> format string for given union",
"tu?", "", "show this help",
NULL
};
@ -420,6 +422,7 @@ static void link_struct_offset(RCore *core, RAnalFunction *fcn) {
RAnalOp aop = {0};
bool ioCache = r_config_get_i (core->config, "io.cache");
bool stack_set = false;
const char *varpfx;
int dbg_follow = r_config_get_i (core->config, "dbg.follow");
Sdb *TDB = core->anal->sdb_types;
RAnalEsil *esil = core->anal->esil;
@ -519,11 +522,16 @@ static void link_struct_offset(RCore *core, RAnalFunction *fcn) {
} else if (dlink) {
RAnalVar *var = aop.var;
if (dst_imm == 0 && var) {
if (r_type_kind (TDB, dlink) == R_TYPE_UNION) {
varpfx = "union";
} else {
varpfx = "struct";
}
// if a var addr matches with struct , change it's type and name
// var int local_e0h --> var struct foo
if (strcmp (var->name , dlink)) {
r_anal_var_retype (core->anal, fcn->addr, R_ANAL_VAR_SCOPE_LOCAL,
-1, var->kind, "struct", -1, var->isarg, var->name);
-1, var->kind, varpfx, -1, var->isarg, var->name);
r_anal_var_rename (core->anal, fcn->addr, R_ANAL_VAR_SCOPE_LOCAL,
var->kind, var->name, dlink);
}
@ -564,6 +572,12 @@ static int cmd_type(void *data, const char *input) {
case '?':
r_core_cmd_help (core, help_msg_tu);
break;
case '*':
showFormat (core, input + 2, 1);
break;
case ' ':
showFormat (core, input + 2, 0);
break;
case 0:
sdb_foreach (TDB, stdprintifunion, core);
break;
@ -654,7 +668,7 @@ static int cmd_type(void *data, const char *input) {
if (member_name) {
*member_name++ = 0;
}
if (name && !r_type_isenum (TDB, name)) {
if (name && (r_type_kind (TDB, name) != R_TYPE_ENUM)) {
eprintf ("%s is not an enum\n", name);
break;
}

View File

@ -10,9 +10,16 @@ typedef struct r_type_enum {
const char *val;
}RTypeEnum;
enum RTypeKind {
R_TYPE_BASIC = 0,
R_TYPE_ENUM = 1,
R_TYPE_STRUCT = 2,
R_TYPE_UNION = 3,
};
R_API int r_type_set(Sdb *TDB, ut64 at, const char *field, ut64 val);
R_API void r_type_del(Sdb *TDB, const char *name);
R_API bool r_type_isenum(Sdb *TDB, const char *name);
R_API int r_type_kind(Sdb *TDB, const char *name);
R_API char *r_type_enum_member(Sdb *TDB, const char *name, const char *member, ut64 val);
R_API char *r_type_enum_getbitfield(Sdb *TDB, const char *name, ut64 val);
R_API RList* r_type_get_enum (Sdb *TDB, const char *name);

View File

@ -21,23 +21,31 @@ R_API int r_type_set(Sdb *TDB, ut64 at, const char *field, ut64 val) {
return false;
}
R_API bool r_type_isenum(Sdb *TDB, const char *name) {
R_API int r_type_kind(Sdb *TDB, const char *name) {
if (!name) {
return false;
return -1;
}
const char *type = sdb_const_get (TDB, name, 0);
if (type && !strcmp (type, "enum")) {
return true;
} else {
return false;
if (!type) {
return -1;
}
if (!strcmp (type, "enum")) {
return R_TYPE_ENUM;
} else if (!strcmp (type, "struct")){
return R_TYPE_STRUCT;
} else if (!strcmp (type, "union")){
return R_TYPE_UNION;
} else if (!strcmp (type, "type")){
return R_TYPE_BASIC;
}
return -1;
}
R_API RList* r_type_get_enum (Sdb *TDB, const char *name) {
char *p, *val, var[128], var2[128];
int n;
if (!r_type_isenum (TDB, name)) {
if (r_type_kind (TDB, name) != R_TYPE_ENUM) {
return NULL;
}
RList *res = r_list_new ();
@ -55,7 +63,7 @@ R_API RList* r_type_get_enum (Sdb *TDB, const char *name) {
R_API char *r_type_enum_member(Sdb *TDB, const char *name, const char *member, ut64 val) {
const char *q;
if (!r_type_isenum (TDB, name)) {
if (r_type_kind (TDB, name) != R_TYPE_ENUM) {
return NULL;
}
if (member) {
@ -71,7 +79,7 @@ R_API char *r_type_enum_getbitfield(Sdb *TDB, const char *name, ut64 val) {
const char *res;
int i;
if (!r_type_isenum (TDB, name)) {
if (r_type_kind (TDB, name) != R_TYPE_ENUM) {
return NULL;
}
bool isFirst = true;
@ -166,7 +174,7 @@ R_API const char *r_type_get_struct_memb(Sdb *TDB, const char *type, int offset)
char* query = sdb_fmt ("struct.%s", type);
char *members = sdb_get (TDB, query, 0);
if (!members) {
eprintf ("%s is not a struct\n", type);
//eprintf ("%s is not a struct\n", type);
return NULL;
}
int nargs = r_str_split (members, ',');
@ -293,8 +301,7 @@ R_API char *r_type_format(Sdb *TDB, const char *t) {
const char *fmt = sdb_const_get (TDB, var, NULL);
if (fmt)
return strdup (fmt);
} else
if (!strcmp (kind, "struct")) {
} else if (!strcmp (kind, "struct") || !strcmp (kind, "union")) {
// assumes var list is sorted by offset.. should do more checks here
for (n = 0; (p = sdb_array_get (TDB, var, n, NULL)); n++) {
const char *tfmt;