Intial work for union support (#10340)
This commit is contained in:
parent
d43bc02f99
commit
17a77857b9
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue