mirror of
https://github.com/radareorg/radare2
synced 2026-08-22 20:23:32 -04:00
Resolve typedefs before measuring pointer width ##types
A typedef like "typedef char *string" is a pointer with no star in its name, so r_anal_type_bitsize measured it from the sdb instead of using the target word size. Resolve the typedef chain first and fail closed on cycles.
This commit is contained in:
parent
ec279715f9
commit
3c0735f268
2 changed files with 29 additions and 2 deletions
|
|
@ -157,10 +157,17 @@ R_API void r_anal_types_load_sdb(RAnal *anal, const char *name) {
|
|||
load_types_from (anal, "%s", name);
|
||||
}
|
||||
|
||||
// for pointers prefer the live target width over the one baked into the type sdb
|
||||
// a pointer is one target word wide, which r_type_get_bitsize cannot know from the sdb alone
|
||||
R_API ut64 r_anal_type_bitsize(RAnal *anal, const char *type) {
|
||||
R_RETURN_VAL_IF_FAIL (anal && anal->config && type, 0);
|
||||
return strchr (type, '*')? anal->config->bits: r_type_get_bitsize (anal->sdb_types, type);
|
||||
// resolve first: "typedef char *string" is a pointer with no star in its name
|
||||
char *resolved = r_type_resolve_typedef (anal->sdb_types, type);
|
||||
const char *effective = resolved? resolved: type;
|
||||
const ut64 bits = strchr (effective, '*')
|
||||
? anal->config->bits
|
||||
: r_type_get_bitsize (anal->sdb_types, type);
|
||||
free (resolved);
|
||||
return bits;
|
||||
}
|
||||
|
||||
R_API void r_anal_remove_parsed_type(RAnal *anal, const char *name) {
|
||||
|
|
|
|||
|
|
@ -321,6 +321,26 @@ static bool test_anal_get_base_type_typedef(void) {
|
|||
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");
|
||||
anal->config->bits = 64;
|
||||
mu_assert_eq (r_anal_type_bitsize (anal, "string"), 64,
|
||||
"Pointer typedef uses the current architecture width");
|
||||
sdb_set (anal->sdb_types, "word", "typedef", 0);
|
||||
sdb_set (anal->sdb_types, "typedef.word", "unsigned long", 0);
|
||||
sdb_num_set (anal->sdb_types, "type.word.size", 64, 0);
|
||||
mu_assert_eq (r_anal_type_bitsize (anal, "word"), 64,
|
||||
"Scalar typedef uses its exact declared width");
|
||||
sdb_set (anal->sdb_types, "cycle_a", "typedef", 0);
|
||||
sdb_set (anal->sdb_types, "typedef.cycle_a", "cycle_b", 0);
|
||||
sdb_set (anal->sdb_types, "cycle_b", "typedef", 0);
|
||||
sdb_set (anal->sdb_types, "typedef.cycle_b", "cycle_a", 0);
|
||||
sdb_set (anal->sdb_types, "u64", "type", 0);
|
||||
sdb_num_set (anal->sdb_types, "type.u64.size", 64, 0);
|
||||
sdb_set (anal->sdb_types, "myword", "typedef", 0);
|
||||
sdb_set (anal->sdb_types, "typedef.myword", "u64", 0);
|
||||
mu_assert_eq (r_type_get_bitsize (anal->sdb_types, "myword"), 64,
|
||||
"Typedef without a declared width measures what it aliases");
|
||||
mu_assert_eq (r_anal_type_bitsize (anal, "cycle_a"), 0,
|
||||
"Cyclic typedefs fail closed");
|
||||
|
||||
sdb_set (anal->sdb_types, "word", "typedef", 0);
|
||||
sdb_set (anal->sdb_types, "typedef.word", "unsigned long", 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue