Add API for getting Atomic and Typedef Types and remove broken !size (#17599)

This commit is contained in:
Florian Märkl 2020-09-15 13:31:38 +02:00 committed by GitHub
parent 36e9314832
commit 456b0fdf09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 322 additions and 135 deletions

View file

@ -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

View file

@ -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 (&param_key, "%s.%s.%s", kind, sname, member_sname);
r_strbuf_setf (&param_val, "%s,%" PFMT64u ",%" PFMT64u "", member->type, member->offset, 0);
sdb_set (anal->sdb_types, r_strbuf_get (&param_key), r_strbuf_get (&param_val), 0);
sdb_set (anal->sdb_types,
r_strbuf_setf (&param_key, "%s.%s.%s", kind, sname, member_sname),
r_strbuf_setf (&param_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 (&param_key, "%s.%s.%s", kind, sname, member_sname);
r_strbuf_setf (&param_val, "%s,%" PFMT64u ",%" PFMT64u "", member->type, member->offset, 0);
sdb_set (anal->sdb_types, r_strbuf_get (&param_key), r_strbuf_get (&param_val), 0);
sdb_set (anal->sdb_types,
r_strbuf_setf (&param_key, "%s.%s.%s", kind, sname, member_sname),
r_strbuf_setf (&param_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 (&param_key, "enum.%s.%s", sname, case_sname);
r_strbuf_setf (&param_val, "0x%" PFMT32x "", cas->val);
sdb_set (anal->sdb_types, r_strbuf_get (&param_key), r_strbuf_get (&param_val), 0);
sdb_set (anal->sdb_types,
r_strbuf_setf (&param_key, "enum.%s.%s", sname, case_sname),
r_strbuf_setf (&param_val, "0x%" PFMT32x "", cas->val), 0);
r_strbuf_setf (&param_key, "enum.%s.0x%" PFMT32x "", sname, cas->val);
sdb_set (anal->sdb_types, r_strbuf_get (&param_key), case_sname, 0);
sdb_set (anal->sdb_types,
r_strbuf_setf (&param_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);

View file

@ -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); // ]

View file

@ -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 |

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -38,6 +38,7 @@ if get_option('enable_tests')
'json',
'list',
'parse_ctype',
'pdb',
'pj',
'queue',
'r2r',

View file

@ -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;
}

View file

@ -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 ();
}

View file

@ -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
View 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