mirror of
https://github.com/radareorg/radare2
synced 2026-08-22 20:23:32 -04:00
Add API for getting Atomic and Typedef Types and remove broken !size (#17599)
This commit is contained in:
parent
36e9314832
commit
456b0fdf09
12 changed files with 322 additions and 135 deletions
|
|
@ -212,7 +212,6 @@ func.recvfrom.ret=ssize_t
|
|||
|
||||
NSString=struct
|
||||
struct.NSString=p0,p1,str,len
|
||||
struct.NSString.!size=256
|
||||
struct.NSString.p0=void *,0,0
|
||||
struct.NSString.p0.meta=4
|
||||
struct.NSString.p1=size_t,0,0
|
||||
|
|
|
|||
182
libr/anal/type.c
182
libr/anal/type.c
|
|
@ -18,56 +18,6 @@ static char *is_type(char *type) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \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) {
|
||||
const char *type = NULL;
|
||||
r_return_if_fail (sdb_types && name);
|
||||
if (!sdb_exists (sdb_types, name) || !(type = sdb_const_get (sdb_types, name, 0))) {
|
||||
return;
|
||||
}
|
||||
char *type_name_size = r_str_newf ("%s.%s.%s", type, name, "!size");
|
||||
r_return_if_fail (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_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
|
||||
*/
|
||||
static void __save_parsed_type_size(RAnal *anal, const char *parsed) {
|
||||
r_return_if_fail (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;
|
||||
if (str + offset == ptr) {
|
||||
break;
|
||||
}
|
||||
char *name = ptr - 1;
|
||||
while (name > str && *name != '\n') {
|
||||
name--;
|
||||
}
|
||||
if (*name == '\n') {
|
||||
name++;
|
||||
}
|
||||
save_type_size (anal->sdb_types, name);
|
||||
*ptr = '=';
|
||||
offset = ptr + 1 - str;
|
||||
}
|
||||
free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static char *get_type_data(Sdb *sdb_types, const char *type, const char *sname) {
|
||||
char *key = r_str_newf ("%s.%s", type, sname);
|
||||
if (!key) {
|
||||
|
|
@ -127,7 +77,6 @@ R_API void r_anal_save_parsed_type(RAnal *anal, const char *parsed) {
|
|||
|
||||
// Now add the type to sdb.
|
||||
sdb_query_lines (anal->sdb_types, parsed);
|
||||
__save_parsed_type_size (anal, parsed);
|
||||
}
|
||||
|
||||
static int typecmp(const void *a, const void *b) {
|
||||
|
|
@ -330,35 +279,79 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static RAnalBaseType *get_typedef_type(RAnal *anal, const char *sname) {
|
||||
r_return_val_if_fail (anal && R_STR_ISNOTEMPTY (sname), NULL);
|
||||
|
||||
RAnalBaseType *base_type = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_TYPEDEF);
|
||||
if (!base_type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base_type->type = get_type_data (anal->sdb_types, "typedef", sname);
|
||||
if (!base_type->type) {
|
||||
goto error;
|
||||
}
|
||||
return base_type;
|
||||
|
||||
error:
|
||||
r_anal_base_type_free (base_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static RAnalBaseType *get_atomic_type(RAnal *anal, const char *sname) {
|
||||
r_return_val_if_fail (anal && R_STR_ISNOTEMPTY (sname), NULL);
|
||||
|
||||
RAnalBaseType *base_type = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_ATOMIC);
|
||||
if (!base_type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base_type->type = get_type_data (anal->sdb_types, "type", sname);
|
||||
if (!base_type->type) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
RStrBuf key;
|
||||
base_type->size = sdb_num_get (anal->sdb_types, r_strbuf_initf (&key, "type.%s.size", sname), 0);
|
||||
r_strbuf_fini (&key);
|
||||
|
||||
return base_type;
|
||||
|
||||
error:
|
||||
r_anal_base_type_free (base_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// returns NULL if name is not found or any failure happened
|
||||
R_API RAnalBaseType *r_anal_get_base_type(RAnal *anal, const char *name) {
|
||||
r_return_val_if_fail (anal && name, NULL);
|
||||
|
||||
char *sname = r_str_sanitize_sdb_key (name);
|
||||
const char *type = sdb_const_get (anal->sdb_types, sname, NULL);
|
||||
|
||||
// Right now just types: struct, enum, union are supported
|
||||
if (!type || !(strcmp (type, "enum") || strcmp (type, "struct") || strcmp (type, "union"))) {
|
||||
if (!type) {
|
||||
free (sname);
|
||||
return NULL;
|
||||
}
|
||||
// Taking advantage that all 3 types start with distinct letter
|
||||
// because the strcmp condition guarantees that only those will get to this flow
|
||||
RAnalBaseType *base_type = NULL;
|
||||
|
||||
switch (type[0]) {
|
||||
case 's': // struct
|
||||
RAnalBaseType *base_type = NULL;
|
||||
if (!strcmp (type, "struct")) {
|
||||
base_type = get_struct_type (anal, sname);
|
||||
break;
|
||||
case 'e': // enum
|
||||
} else if (!strcmp (type, "enum")) {
|
||||
base_type = get_enum_type (anal, sname);
|
||||
break;
|
||||
case 'u': // union
|
||||
} else if (!strcmp (type, "union")) {
|
||||
base_type = get_union_type (anal, sname);
|
||||
break;
|
||||
} else if (!strcmp (type, "typedef")) {
|
||||
base_type = get_typedef_type (anal, sname);
|
||||
} else if (!strcmp (type, "type")) {
|
||||
base_type = get_atomic_type (anal, sname);
|
||||
}
|
||||
|
||||
if (base_type) {
|
||||
base_type->name = sname;
|
||||
} else {
|
||||
free (sname);
|
||||
}
|
||||
|
||||
free (sname);
|
||||
return base_type;
|
||||
}
|
||||
|
||||
|
|
@ -372,7 +365,6 @@ static void save_struct(const RAnal *anal, const RAnalBaseType *type) {
|
|||
Sdb:
|
||||
name=struct
|
||||
struct.name=param1,param2,paramN
|
||||
struct.name.!size=96
|
||||
struct.name.param1=type,0,0
|
||||
struct.name.param2=type,4,0
|
||||
struct.name.paramN=type,8,0
|
||||
|
|
@ -393,9 +385,9 @@ static void save_struct(const RAnal *anal, const RAnalBaseType *type) {
|
|||
r_vector_foreach (&type->struct_data.members, member) {
|
||||
// struct.name.param=type,offset,argsize
|
||||
char *member_sname = r_str_sanitize_sdb_key (member->name);
|
||||
r_strbuf_setf (¶m_key, "%s.%s.%s", kind, sname, member_sname);
|
||||
r_strbuf_setf (¶m_val, "%s,%" PFMT64u ",%" PFMT64u "", member->type, member->offset, 0);
|
||||
sdb_set (anal->sdb_types, r_strbuf_get (¶m_key), r_strbuf_get (¶m_val), 0);
|
||||
sdb_set (anal->sdb_types,
|
||||
r_strbuf_setf (¶m_key, "%s.%s.%s", kind, sname, member_sname),
|
||||
r_strbuf_setf (¶m_val, "%s,%" PFMT64u ",%" PFMT64u "", member->type, member->offset, 0), 0);
|
||||
free (member_sname);
|
||||
|
||||
r_strbuf_appendf (&arglist, (i++ == 0) ? "%s" : ",%s", member->name);
|
||||
|
|
@ -404,12 +396,6 @@ static void save_struct(const RAnal *anal, const RAnalBaseType *type) {
|
|||
char *key = r_str_newf ("%s.%s", kind, sname);
|
||||
sdb_set (anal->sdb_types, key, r_strbuf_get (&arglist), 0);
|
||||
free (key);
|
||||
// struct.name.!size=96
|
||||
key = r_str_newf ("%s.%s.!size", kind, sname);
|
||||
char *val = r_str_newf ("%" PFMT64u "", type->size);
|
||||
sdb_set (anal->sdb_types, key, val, 0);
|
||||
free (val);
|
||||
free (key);
|
||||
|
||||
free (sname);
|
||||
|
||||
|
|
@ -428,7 +414,6 @@ static void save_union(const RAnal *anal, const RAnalBaseType *type) {
|
|||
Sdb:
|
||||
name=union
|
||||
union.name=param1,param2,paramN
|
||||
union.name.!size=32
|
||||
union.name.param1=type,0,0
|
||||
union.name.param2=type,0,0
|
||||
union.name.paramN=type,0,0
|
||||
|
|
@ -449,9 +434,9 @@ static void save_union(const RAnal *anal, const RAnalBaseType *type) {
|
|||
r_vector_foreach (&type->union_data.members, member) {
|
||||
// union.name.arg1=type,offset,argsize
|
||||
char *member_sname = r_str_sanitize_sdb_key (member->name);
|
||||
r_strbuf_setf (¶m_key, "%s.%s.%s", kind, sname, member_sname);
|
||||
r_strbuf_setf (¶m_val, "%s,%" PFMT64u ",%" PFMT64u "", member->type, member->offset, 0);
|
||||
sdb_set (anal->sdb_types, r_strbuf_get (¶m_key), r_strbuf_get (¶m_val), 0);
|
||||
sdb_set (anal->sdb_types,
|
||||
r_strbuf_setf (¶m_key, "%s.%s.%s", kind, sname, member_sname),
|
||||
r_strbuf_setf (¶m_val, "%s,%" PFMT64u ",%" PFMT64u "", member->type, member->offset, 0), 0);
|
||||
free (member_sname);
|
||||
|
||||
r_strbuf_appendf (&arglist, (i++ == 0) ? "%s" : ",%s", member->name);
|
||||
|
|
@ -461,12 +446,6 @@ static void save_union(const RAnal *anal, const RAnalBaseType *type) {
|
|||
sdb_set (anal->sdb_types, key, r_strbuf_get (&arglist), 0);
|
||||
free (key);
|
||||
|
||||
key = r_str_newf ("%s.%s.!size", kind, sname);
|
||||
char *val = r_str_newf ("%" PFMT64u "", type->size);
|
||||
sdb_set (anal->sdb_types, key, val, 0);
|
||||
free (val);
|
||||
free (key);
|
||||
|
||||
free (sname);
|
||||
|
||||
r_strbuf_fini (&arglist);
|
||||
|
|
@ -505,12 +484,13 @@ static void save_enum(const RAnal *anal, const RAnalBaseType *type) {
|
|||
r_vector_foreach (&type->enum_data.cases, cas) {
|
||||
// enum.name.arg1=type,offset,???
|
||||
char *case_sname = r_str_sanitize_sdb_key (cas->name);
|
||||
r_strbuf_setf (¶m_key, "enum.%s.%s", sname, case_sname);
|
||||
r_strbuf_setf (¶m_val, "0x%" PFMT32x "", cas->val);
|
||||
sdb_set (anal->sdb_types, r_strbuf_get (¶m_key), r_strbuf_get (¶m_val), 0);
|
||||
sdb_set (anal->sdb_types,
|
||||
r_strbuf_setf (¶m_key, "enum.%s.%s", sname, case_sname),
|
||||
r_strbuf_setf (¶m_val, "0x%" PFMT32x "", cas->val), 0);
|
||||
|
||||
r_strbuf_setf (¶m_key, "enum.%s.0x%" PFMT32x "", sname, cas->val);
|
||||
sdb_set (anal->sdb_types, r_strbuf_get (¶m_key), case_sname, 0);
|
||||
sdb_set (anal->sdb_types,
|
||||
r_strbuf_setf (¶m_key, "enum.%s.0x%" PFMT32x "", sname, cas->val),
|
||||
case_sname, 0);
|
||||
free (case_sname);
|
||||
|
||||
r_strbuf_appendf (&arglist, (i++ == 0) ? "%s" : ",%s", cas->name);
|
||||
|
|
@ -520,12 +500,6 @@ static void save_enum(const RAnal *anal, const RAnalBaseType *type) {
|
|||
sdb_set (anal->sdb_types, key, r_strbuf_get (&arglist), 0);
|
||||
free (key);
|
||||
|
||||
key = r_str_newf ("enum.%s.!size", sname);
|
||||
char *val = r_str_newf ("%" PFMT64u "", type->size);
|
||||
sdb_set (anal->sdb_types, key, val, 0);
|
||||
free (val);
|
||||
free (key);
|
||||
|
||||
free (sname);
|
||||
|
||||
r_strbuf_fini (&arglist);
|
||||
|
|
@ -551,9 +525,13 @@ static void save_atomic_type(const RAnal *anal, const RAnalBaseType *type) {
|
|||
r_strbuf_init (&key);
|
||||
r_strbuf_init (&val);
|
||||
|
||||
r_strbuf_setf (&key, "type.%s.size", sname);
|
||||
r_strbuf_setf (&val, "%" PFMT64u "", type->size);
|
||||
sdb_set (anal->sdb_types, r_strbuf_get (&key), r_strbuf_get (&val), 0);
|
||||
sdb_set (anal->sdb_types,
|
||||
r_strbuf_setf (&key, "type.%s.size", sname),
|
||||
r_strbuf_setf (&val, "%" PFMT64u "", type->size), 0);
|
||||
|
||||
sdb_set (anal->sdb_types,
|
||||
r_strbuf_setf (&key, "type.%s", sname),
|
||||
type->type, 0);
|
||||
|
||||
free (sname);
|
||||
|
||||
|
|
@ -577,9 +555,9 @@ static void save_typedef(const RAnal *anal, const RAnalBaseType *type) {
|
|||
r_strbuf_init (&key);
|
||||
r_strbuf_init (&val);
|
||||
|
||||
r_strbuf_setf (&key, "typedef.%s", sname);
|
||||
r_strbuf_setf (&val, "%s", type->type);
|
||||
sdb_set (anal->sdb_types, r_strbuf_get (&key), r_strbuf_get (&val), 0);
|
||||
sdb_set (anal->sdb_types,
|
||||
r_strbuf_setf (&key, "typedef.%s", sname),
|
||||
r_strbuf_setf (&val, "%s", type->type), 0);
|
||||
|
||||
free (sname);
|
||||
|
||||
|
|
|
|||
|
|
@ -443,17 +443,8 @@ static int print_struct_union_list_json(Sdb *TDB, SdbForeachCallback filter) {
|
|||
continue;
|
||||
}
|
||||
pj_o (pj); // {
|
||||
char *sizecmd = r_str_newf ("%s.%s.!size", sdbkv_value (kv), k);
|
||||
if (!sizecmd) {
|
||||
break;
|
||||
}
|
||||
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); // ]
|
||||
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ EXPECT=<<EOF
|
|||
| ; arg func main @ r0
|
||||
| ; arg int argc @ r1
|
||||
| 0x00008174 b80000eb bl sym.__libc_start_main ; lr=0x8178 -> 0xeb0002a4 ; pc=0x845c -> 0xe92d41f0
|
||||
| ; int __libc_start_main(?, -1, ?, ?, ?, ?, -1)
|
||||
| ; int __libc_start_main(?, ?, ?, ?, ?, ?, -1)
|
||||
\ 0x00008178 a40200eb bl sym.abort ; lr=0x817c -> 0xe92d4030 ; pc=0x8c10 -> 0xe59f62a0
|
||||
\ ; void abort(void)
|
||||
|
||||
|
|
@ -281,7 +281,7 @@ EXPECT=<<EOF
|
|||
| ; arg int argc @ r1
|
||||
| ; lr=0x8178 -> 0xeb0002a4
|
||||
| ; pc=0x845c -> 0xe92d41f0 sym.__libc_start_main
|
||||
| ; int __libc_start_main(?, -1, ?, ?, ?, ?, -1)
|
||||
| ; int __libc_start_main(?, ?, ?, ?, ?, ?, -1)
|
||||
| 0x00008174 b80000eb bl sym.__libc_start_main
|
||||
| ; lr=0x817c -> 0xe92d4030
|
||||
| ; pc=0x8c10 -> 0xe59f62a0 sym.abort
|
||||
|
|
@ -296,7 +296,7 @@ EXPECT=<<EOF
|
|||
| ; arg int argc @ r1 |
|
||||
| ; lr=0x8178 -> 0xeb0002a4 |
|
||||
| ; pc=0x845c -> 0xe92d41f0 sym.__libc_start_main |
|
||||
| ; int __libc_start_main(?, -1, ?, ?, ?, ?, -1) |
|
||||
| ; int __libc_start_main(?, ?, ?, ?, ?, ?, -1) |
|
||||
| bl sym.__libc_start_main;[oa] |
|
||||
| ; lr=0x817c -> 0xe92d4030 |
|
||||
| ; pc=0x8c10 -> 0xe59f62a0 sym.abort |
|
||||
|
|
|
|||
|
|
@ -241,3 +241,14 @@ struct NSString {
|
|||
};
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=tc typedef
|
||||
FILE=-
|
||||
CMDS=<<EOF
|
||||
"td typedef char *string;"
|
||||
ttc string
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
typedef char * string;
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ days=typedef
|
|||
easy_prey=typedef
|
||||
humans=typedef
|
||||
struct.dangerous=neo
|
||||
struct.dangerous.!size=64
|
||||
struct.dangerous.neo=uint64_t,0,0
|
||||
struct.dangerous.neo.meta=13
|
||||
tokyo=typedef
|
||||
|
|
|
|||
|
|
@ -213,7 +213,6 @@ t-xoo
|
|||
EOF
|
||||
EXPECT=<<EOF
|
||||
union.xoo=x,y,z
|
||||
union.xoo.!size=32
|
||||
union.xoo.x=int32_t,0,0
|
||||
union.xoo.x.meta=0
|
||||
union.xoo.y=int32_t,0,0
|
||||
|
|
@ -1394,7 +1393,6 @@ tk~struct.s1
|
|||
EOF
|
||||
EXPECT=<<EOF
|
||||
struct.s1=a,size,b
|
||||
struct.s1.!size=96
|
||||
struct.s1.a=int32_t,0,0
|
||||
struct.s1.a.meta=0
|
||||
struct.s1.b=int32_t,8,0
|
||||
|
|
@ -1538,7 +1536,6 @@ EXPECT=<<EOF
|
|||
pf.foo dc a b
|
||||
tk foo=union
|
||||
tk union.foo=a,b
|
||||
tk union.foo.!size=32
|
||||
tk union.foo.a=int32_t,0,0
|
||||
tk union.foo.a.meta=0
|
||||
tk union.foo.b=char,0,0
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ if get_option('enable_tests')
|
|||
'json',
|
||||
'list',
|
||||
'parse_ctype',
|
||||
'pdb',
|
||||
'pj',
|
||||
'queue',
|
||||
'r2r',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#include <r_anal.h>
|
||||
#include <r_parse.h>
|
||||
#include "minunit.h"
|
||||
|
||||
#include "minunit.h"
|
||||
#include "test_sdb.h"
|
||||
|
||||
static void setup_sdb_for_struct(Sdb *res) {
|
||||
// "td struct kappa {int bar;int cow;};"
|
||||
|
|
@ -25,6 +26,20 @@ static void setup_sdb_for_enum(Sdb *res) {
|
|||
sdb_set (res, "enum.foo", "firstCase,secondCase", 0);
|
||||
sdb_set (res, "enum.foo.firstCase", "0x1", 0);
|
||||
sdb_set (res, "enum.foo.secondCase", "0x2", 0);
|
||||
sdb_set (res, "enum.foo.0x1", "firstCase", 0);
|
||||
sdb_set (res, "enum.foo.0x2", "secondCase", 0);
|
||||
}
|
||||
|
||||
static void setup_sdb_for_typedef(Sdb *res) {
|
||||
// td typedef char *string;
|
||||
sdb_set (res, "string", "typedef", 0);
|
||||
sdb_set (res, "typedef.string", "char *", 0);
|
||||
}
|
||||
|
||||
static void setup_sdb_for_atomic(Sdb *res) {
|
||||
sdb_set (res, "char", "type", 0);
|
||||
sdb_set (res, "type.char.size", "8", 0);
|
||||
sdb_set (res, "type.char", "c", 0);
|
||||
}
|
||||
|
||||
static void setup_sdb_for_not_found(Sdb *res) {
|
||||
|
|
@ -53,6 +68,7 @@ static bool test_anal_get_base_type_struct(void) {
|
|||
mu_assert_notnull (base, "Couldn't create get base type of struct \"kappa\"");
|
||||
|
||||
mu_assert_eq (R_ANAL_BASE_TYPE_KIND_STRUCT, base->kind, "Wrong base type");
|
||||
mu_assert_streq (base->name, "kappa", "type name");
|
||||
|
||||
RAnalStructMember *member;
|
||||
|
||||
|
|
@ -71,6 +87,38 @@ static bool test_anal_get_base_type_struct(void) {
|
|||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_save_base_type_struct(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
|
||||
|
||||
RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_STRUCT);
|
||||
base->name = strdup ("kappa");
|
||||
|
||||
RAnalStructMember member = {
|
||||
.offset = 0,
|
||||
.type = strdup ("int32_t"),
|
||||
.name = strdup ("bar")
|
||||
};
|
||||
r_vector_push (&base->struct_data.members, &member);
|
||||
|
||||
member.offset = 4;
|
||||
member.type = strdup ("int32_t");
|
||||
member.name = strdup ("cow");
|
||||
r_vector_push (&base->struct_data.members, &member);
|
||||
|
||||
r_anal_save_base_type (anal, base);
|
||||
r_anal_base_type_free (base);
|
||||
|
||||
Sdb *reg = sdb_new0 ();
|
||||
setup_sdb_for_struct (reg);
|
||||
assert_sdb_eq (anal->sdb_types, reg, "save struct type");
|
||||
sdb_free (reg);
|
||||
|
||||
r_anal_free (anal);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_get_base_type_union(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
|
|
@ -82,6 +130,7 @@ static bool test_anal_get_base_type_union(void) {
|
|||
mu_assert_notnull (base, "Couldn't create get base type of union \"kappa\"");
|
||||
|
||||
mu_assert_eq (R_ANAL_BASE_TYPE_KIND_UNION, base->kind, "Wrong base type");
|
||||
mu_assert_streq (base->name, "kappa", "type name");
|
||||
|
||||
RAnalUnionMember *member;
|
||||
|
||||
|
|
@ -98,6 +147,38 @@ static bool test_anal_get_base_type_union(void) {
|
|||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_save_base_type_union(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
|
||||
|
||||
RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_UNION);
|
||||
base->name = strdup ("kappa");
|
||||
|
||||
RAnalUnionMember member = {
|
||||
.offset = 0,
|
||||
.type = strdup ("int32_t"),
|
||||
.name = strdup ("bar")
|
||||
};
|
||||
r_vector_push (&base->union_data.members, &member);
|
||||
|
||||
member.offset = 0;
|
||||
member.type = strdup ("int32_t");
|
||||
member.name = strdup ("cow");
|
||||
r_vector_push (&base->union_data.members, &member);
|
||||
|
||||
r_anal_save_base_type (anal, base);
|
||||
r_anal_base_type_free (base);
|
||||
|
||||
Sdb *reg = sdb_new0 ();
|
||||
setup_sdb_for_union (reg);
|
||||
assert_sdb_eq (anal->sdb_types, reg, "save union type");
|
||||
sdb_free (reg);
|
||||
|
||||
r_anal_free (anal);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_get_base_type_enum(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
|
|
@ -109,10 +190,9 @@ static bool test_anal_get_base_type_enum(void) {
|
|||
mu_assert_notnull (base, "Couldn't create get base type of enum \"foo\"");
|
||||
|
||||
mu_assert_eq (R_ANAL_BASE_TYPE_KIND_ENUM, base->kind, "Wrong base type");
|
||||
mu_assert_streq (base->name, "foo", "type name");
|
||||
|
||||
RAnalEnumCase *cas;
|
||||
|
||||
cas = r_vector_index_ptr (&base->enum_data.cases, 0);
|
||||
RAnalEnumCase *cas = r_vector_index_ptr (&base->enum_data.cases, 0);
|
||||
mu_assert_eq (cas->val, 1, "Incorrect value for enum case");
|
||||
mu_assert_streq (cas->name, "firstCase", "Incorrect name for enum case");
|
||||
|
||||
|
|
@ -125,9 +205,121 @@ static bool test_anal_get_base_type_enum(void) {
|
|||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_save_base_type_enum(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
|
||||
|
||||
RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_ENUM);
|
||||
base->name = strdup ("foo");
|
||||
|
||||
RAnalEnumCase cas = {
|
||||
.name = strdup ("firstCase"),
|
||||
.val = 1
|
||||
};
|
||||
r_vector_push (&base->enum_data.cases, &cas);
|
||||
|
||||
cas.name = strdup ("secondCase");
|
||||
cas.val = 2;
|
||||
r_vector_push (&base->enum_data.cases, &cas);
|
||||
|
||||
r_anal_save_base_type (anal, base);
|
||||
r_anal_base_type_free (base);
|
||||
|
||||
Sdb *reg = sdb_new0 ();
|
||||
setup_sdb_for_enum (reg);
|
||||
assert_sdb_eq (anal->sdb_types, reg, "save enum type");
|
||||
sdb_free (reg);
|
||||
|
||||
r_anal_free (anal);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_get_base_type_typedef(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
|
||||
|
||||
setup_sdb_for_typedef (anal->sdb_types);
|
||||
|
||||
RAnalBaseType *base = r_anal_get_base_type (anal, "string");
|
||||
mu_assert_notnull (base, "Couldn't create get base type of typedef \"string\"");
|
||||
|
||||
mu_assert_eq (R_ANAL_BASE_TYPE_KIND_TYPEDEF, base->kind, "Wrong base type");
|
||||
mu_assert_streq (base->name, "string", "type name");
|
||||
mu_assert_streq (base->type, "char *", "typedefd type");
|
||||
|
||||
r_anal_base_type_free (base);
|
||||
r_anal_free (anal);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_save_base_type_typedef(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
|
||||
|
||||
RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_TYPEDEF);
|
||||
base->name = strdup ("string");
|
||||
base->type = strdup ("char *");
|
||||
|
||||
r_anal_save_base_type (anal, base);
|
||||
r_anal_base_type_free (base);
|
||||
|
||||
Sdb *reg = sdb_new0 ();
|
||||
setup_sdb_for_typedef (reg);
|
||||
assert_sdb_eq (anal->sdb_types, reg, "save typedef type");
|
||||
sdb_free (reg);
|
||||
|
||||
r_anal_free (anal);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_get_base_type_atomic(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
|
||||
|
||||
setup_sdb_for_atomic (anal->sdb_types);
|
||||
|
||||
RAnalBaseType *base = r_anal_get_base_type (anal, "char");
|
||||
mu_assert_notnull (base, "Couldn't create get base type of atomic type \"char\"");
|
||||
|
||||
mu_assert_eq (R_ANAL_BASE_TYPE_KIND_ATOMIC, base->kind, "Wrong base type");
|
||||
mu_assert_streq (base->name, "char", "type name");
|
||||
mu_assert_streq (base->type, "c", "atomic type type");
|
||||
mu_assert_eq (base->size, 8, "atomic type size");
|
||||
|
||||
r_anal_base_type_free (base);
|
||||
r_anal_free (anal);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_save_base_type_atomic(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
|
||||
|
||||
RAnalBaseType *base = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_ATOMIC);
|
||||
base->name = strdup ("char");
|
||||
base->type = strdup ("c");
|
||||
base->size = 8;
|
||||
|
||||
r_anal_save_base_type (anal, base);
|
||||
r_anal_base_type_free (base);
|
||||
|
||||
Sdb *reg = sdb_new0 ();
|
||||
setup_sdb_for_atomic (reg);
|
||||
assert_sdb_eq (anal->sdb_types, reg, "save atomic type");
|
||||
sdb_free (reg);
|
||||
|
||||
r_anal_free (anal);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_anal_get_base_type_not_found(void) {
|
||||
RAnal *anal = r_anal_new ();
|
||||
setup_sdb_for_not_found(anal->sdb_types);
|
||||
setup_sdb_for_not_found (anal->sdb_types);
|
||||
|
||||
mu_assert_notnull (anal, "Couldn't create new RAnal");
|
||||
mu_assert_notnull (anal->sdb_types, "Couldn't create new RAnal.sdb_types");
|
||||
|
|
@ -149,8 +341,15 @@ static bool test_anal_get_base_type_not_found(void) {
|
|||
|
||||
int all_tests(void) {
|
||||
mu_run_test (test_anal_get_base_type_struct);
|
||||
mu_run_test (test_anal_save_base_type_struct);
|
||||
mu_run_test (test_anal_get_base_type_union);
|
||||
mu_run_test (test_anal_save_base_type_union);
|
||||
mu_run_test (test_anal_get_base_type_enum);
|
||||
mu_run_test (test_anal_save_base_type_enum);
|
||||
mu_run_test (test_anal_get_base_type_typedef);
|
||||
mu_run_test (test_anal_save_base_type_typedef);
|
||||
mu_run_test (test_anal_get_base_type_atomic);
|
||||
mu_run_test (test_anal_save_base_type_atomic);
|
||||
mu_run_test (test_anal_get_base_type_not_found);
|
||||
return tests_passed != tests_run;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ static bool test_parse_dwarf_types(void) {
|
|||
char * value = NULL;
|
||||
Sdb *sdb = anal->sdb_types;
|
||||
check_kv ("_cairo_status", "enum");
|
||||
check_kv ("enum._cairo_status.!size", "32");
|
||||
check_kv ("enum._cairo_status.0x0", "CAIRO_STATUS_SUCCESS");
|
||||
check_kv ("enum._cairo_status.CAIRO_STATUS_SUCCESS", "0x0");
|
||||
check_kv ("enum._cairo_status.0x9", "CAIRO_STATUS_INVALID_PATH_DATA");
|
||||
|
|
@ -63,12 +62,10 @@ static bool test_parse_dwarf_types(void) {
|
|||
"CAIRO_STATUS_INVALID_SLANT,CAIRO_STATUS_INVALID_WEIGHT");
|
||||
|
||||
check_kv ("_MARGINS", "struct");
|
||||
check_kv ("struct._MARGINS.!size", "128");
|
||||
// TODO evaluate member_location operations in DWARF to get offset and test it
|
||||
check_kv ("struct._MARGINS", "cxLeftWidth,cxRightWidth,cyTopHeight,cyBottomHeight");
|
||||
|
||||
check_kv ("unaligned", "union");
|
||||
check_kv ("union.unaligned.!size", "64");
|
||||
check_kv ("union.unaligned", "ptr,u2,u4,u8,s2,s4,s8");
|
||||
check_kv ("union.unaligned.u2", "short unsigned int,0,0");
|
||||
check_kv ("union.unaligned.s8", "long long int,0,0");
|
||||
|
|
@ -256,5 +253,5 @@ int all_tests(void) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
return all_tests();
|
||||
}
|
||||
return all_tests ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -420,7 +420,6 @@ bool test_pdb_tpi_rust(void) {
|
|||
mu_assert_eq (type_info->leaf_type, eLF_ARGLIST, "Incorrect data type");
|
||||
} else if (type->tpi_idx == 0x1058) {
|
||||
mu_assert_eq (type_info->leaf_type, eLF_STRUCTURE, "Incorrect data type");
|
||||
SType *return_type;
|
||||
char *name;
|
||||
type_info->get_name (&type->type_data, &name);
|
||||
mu_assert_streq (name, "std::thread::local::fast::Key<core::cell::Cell<core::option::Option<core::ptr::non_null::NonNull<core::task::wake::Context>>>>", "Wrong name");
|
||||
|
|
@ -475,7 +474,6 @@ bool test_pdb_type_save(void) {
|
|||
check_kv ("union.R2_TEST_UNION", "r2_union_var_1,r2_union_var_2");
|
||||
check_kv ("union.R2_TEST_UNION.r2_union_var_1", "int32_t,0,0");
|
||||
check_kv ("union.R2_TEST_UNION.r2_union_var_2", "double,0,0");
|
||||
check_kv ("union.R2_TEST_UNION.!size", "8");
|
||||
|
||||
check_kv ("__m64", "union");
|
||||
check_kv ("union.__m64", "m64_u64,m64_f32,m64_i8,m64_i16,m64_i32,m64_i64,m64_u8,m64_u16,m64_u32");
|
||||
|
|
@ -488,19 +486,16 @@ bool test_pdb_type_save(void) {
|
|||
check_kv ("union.__m64.m64_u8", "uint8_t[8],0,0");
|
||||
check_kv ("union.__m64.m64_u16", "uint16_t[8],0,0");
|
||||
check_kv ("union.__m64.m64_u32", "uint32_t[8],0,0");
|
||||
check_kv ("union.__m64.!size", "8");
|
||||
|
||||
check_kv ("TEST_CLASS", "struct");
|
||||
check_kv ("struct.TEST_CLASS", "class_var1,calss_var2");
|
||||
check_kv ("struct.TEST_CLASS.class_var1", "int32_t,0,0");
|
||||
check_kv ("struct.TEST_CLASS.calss_var2", "uint16_t,4,0");
|
||||
check_kv ("union.__m64.!size", "8");
|
||||
|
||||
check_kv ("localeinfo_struct", "struct");
|
||||
check_kv ("struct.localeinfo_struct", "locinfo,mbcinfo");
|
||||
check_kv ("struct.localeinfo_struct.locinfo", "struct threadlocaleinfostruct*,0,0");
|
||||
check_kv ("struct.localeinfo_struct.mbcinfo", "struct threadmbcinfostruct*,4,0");
|
||||
check_kv ("union.__m64.!size", "8");
|
||||
r_anal_free (anal);
|
||||
mu_end;
|
||||
}
|
||||
|
|
@ -514,4 +509,4 @@ bool all_tests() {
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
return all_tests ();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
test/unit/test_sdb.h
Normal file
20
test/unit/test_sdb.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef TEST_SDB_H
|
||||
#define TEST_SDB_H
|
||||
|
||||
static void diff_cb(const SdbDiff *diff, void *user) {
|
||||
char buf[2048];
|
||||
if (sdb_diff_format (buf, sizeof (buf), diff) < 0) {
|
||||
return;
|
||||
}
|
||||
printf ("%s\n", buf);
|
||||
}
|
||||
|
||||
static inline void print_sdb(Sdb *sdb) {
|
||||
Sdb *e = sdb_new0 ();
|
||||
sdb_diff (e, sdb, diff_cb, NULL);
|
||||
sdb_free (e);
|
||||
}
|
||||
|
||||
#define assert_sdb_eq(actual, expected, msg) mu_assert ((msg), sdb_diff (expected, actual, diff_cb, NULL));
|
||||
|
||||
#endif //R2DB_TEST_UTILS_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue