Rizin
unix-like reverse engineering framework and cli tools
typeclass.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 Anton Kochkov <anton.kochkov@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_util.h>
5 #include <rz_type.h>
6 #include <string.h>
7 
26 inline static bool typeclass_is_num(RzTypeTypeclass t) {
28 }
29 
30 inline static bool typeclass_is_integal(RzTypeTypeclass t) {
32 }
33 
40  switch (typeclass) {
42  return "Num";
44  return "Integral";
46  return "Floating";
48  return "Address";
50  return "Signed Integral";
52  return "Unsigned Integral";
54  return "None";
55  default:
57  }
58  return "None";
59 }
60 
68 
69  if (!strcmp(typeclass, "Integral")) {
71  } else if (!strcmp(typeclass, "Signed Integral")) {
73  } else if (!strcmp(typeclass, "Unsigned Integral")) {
75  } else if (!strcmp(typeclass, "Floating")) {
77  } else if (!strcmp(typeclass, "Address")) {
79  } else if (!strcmp(typeclass, "Num")) {
80  return RZ_TYPE_TYPECLASS_NUM;
81  }
83 }
84 
85 inline static bool get_base_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type, RZ_NONNULL RzTypeTypeclass *typeclass) {
86  rz_return_val_if_fail(type && typeclass, false);
87  *typeclass = type->attrs & RZ_TYPE_ATTRIBUTE_TYPECLASS_MASK;
88  if (*typeclass < RZ_TYPE_TYPECLASS_INVALID) {
89  return true;
90  }
91  // If the type is typedef, we check the underlying type all the way down
92  if (*typeclass == 0 && type->kind == RZ_BASE_TYPE_KIND_TYPEDEF) {
93  // We do not treat pointers and arrays as the same typeclass
94  if (type->type->kind != RZ_TYPE_KIND_IDENTIFIER) {
95  return false;
96  }
97  const char *identifier = rz_type_identifier(type->type);
98  if (!identifier) {
99  return false;
100  }
101  RzBaseType *t = rz_type_db_get_base_type(typedb, identifier);
102  if (!t) {
103  return false;
104  }
105  return get_base_type_typeclass(typedb, t, typeclass);
106  }
107  return false;
108 }
109 
110 inline static bool get_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzType *type, RzTypeTypeclass *typeclass) {
111  rz_return_val_if_fail(type && typeclass, false);
112  const char *identifier = rz_type_identifier(type);
113  if (!identifier) {
114  return false;
115  }
116  RzBaseType *t = rz_type_db_get_base_type(typedb, identifier);
117  if (!t) {
118  return false;
119  }
120  return get_base_type_typeclass(typedb, t, typeclass);
121 }
122 
123 inline static bool check_base_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type, RzTypeTypeclass typeclass) {
124  rz_return_val_if_fail(type, false);
125  RzTypeTypeclass tclass;
126  if (!get_base_type_typeclass(typedb, type, &tclass)) {
127  return false;
128  }
129  return tclass == typeclass;
130 }
131 
132 inline static bool check_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzType *type, RzTypeTypeclass typeclass) {
133  rz_return_val_if_fail(type, false);
134  RzTypeTypeclass tclass;
135  if (!get_type_typeclass(typedb, type, &tclass)) {
136  return false;
137  }
138  return tclass == typeclass;
139 }
140 
148  rz_return_val_if_fail(type, false);
150  get_base_type_typeclass(typedb, type, &tclass);
151  return tclass;
152 }
153 
161  rz_return_val_if_fail(type, false);
163  get_type_typeclass(typedb, type, &tclass);
164  return tclass;
165 }
166 
174  rz_return_val_if_fail(type, false);
175  RzTypeTypeclass tclass;
176  if (!get_base_type_typeclass(typedb, type, &tclass)) {
177  return false;
178  }
179  return typeclass_is_num(tclass);
180 }
181 
188 RZ_API bool rz_type_is_num(const RzTypeDB *typedb, RZ_NONNULL const RzType *type) {
189  rz_return_val_if_fail(type, false);
190  RzTypeTypeclass tclass;
191  if (!get_type_typeclass(typedb, type, &tclass)) {
192  return false;
193  }
194  return typeclass_is_num(tclass);
195 }
196 
204  rz_return_val_if_fail(type, false);
205  RzTypeTypeclass tclass;
206  if (!get_base_type_typeclass(typedb, type, &tclass)) {
207  return false;
208  }
209  return typeclass_is_integal(tclass);
210 }
211 
219  rz_return_val_if_fail(type, false);
220  RzTypeTypeclass tclass;
221  if (!get_type_typeclass(typedb, type, &tclass)) {
222  return false;
223  }
224  return typeclass_is_integal(tclass);
225 }
226 
234  rz_return_val_if_fail(type, false);
236 }
237 
245  rz_return_val_if_fail(type, false);
247 }
248 
256  rz_return_val_if_fail(type, false);
258 }
259 
267  rz_return_val_if_fail(type, false);
269 }
270 
278  rz_return_val_if_fail(type, false);
280 }
281 
289  rz_return_val_if_fail(type, false);
291 }
292 
294  const RzTypeDB *typedb;
297 };
298 
299 static bool base_type_typeclass_collect_cb(void *user, const void *k, const void *v) {
300  struct list_typeclass *l = user;
301  RzBaseType *btype = (RzBaseType *)v;
303  if (!get_base_type_typeclass(l->typedb, btype, &typeclass)) {
304  return false;
305  }
306  if (l->typeclass == typeclass) {
307  rz_list_append(l->types, btype);
308  }
309  return true;
310 }
311 
313  const RzTypeDB *typedb;
316  size_t size;
317 };
318 
319 static bool base_type_typeclass_sized_collect_cb(void *user, const void *k, const void *v) {
320  struct list_typeclass_size *l = user;
321  RzBaseType *btype = (RzBaseType *)v;
323  if (!get_base_type_typeclass(l->typedb, btype, &typeclass)) {
324  return false;
325  }
326  if (l->typeclass == typeclass && l->size == btype->size) {
327  rz_list_append(l->types, btype);
328  }
329  return true;
330 }
331 
341  RzList *types = rz_list_new();
342  struct list_typeclass lt = { typedb, types, typeclass };
343  ht_pp_foreach(typedb->types, base_type_typeclass_collect_cb, &lt);
344  return types;
345 }
346 
357  RzList *types = rz_list_new();
360  return types;
361 }
362 
374  if (!l || rz_list_empty(l)) {
375  return NULL;
376  }
377  RzBaseType *ret = rz_list_pop(l);
378  rz_list_free(l);
379  return ret;
380 }
RZ_API RZ_BORROW RzBaseType * rz_type_db_get_base_type(const RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the RzBaseType in the types database given the name.
Definition: base.c:57
#define RZ_API
#define NULL
Definition: cris-opc.c:27
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
voidpf void uLong size
Definition: ioapi.h:138
RZ_API RZ_OWN void * rz_list_pop(RZ_NONNULL RzList *list)
Removes and returns the last element of the list.
Definition: list.c:376
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
int type
Definition: mipsasm.c:17
insn_type_descr_t types[]
Definition: or1k_disas.c:7
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
@ RZ_BASE_TYPE_KIND_TYPEDEF
Definition: rz_type.h:76
@ RZ_TYPE_ATTRIBUTE_TYPECLASS_MASK
Definition: rz_type.h:56
RzTypeTypeclass
Definition: rz_type.h:61
@ RZ_TYPE_TYPECLASS_FLOATING
Definition: rz_type.h:65
@ RZ_TYPE_TYPECLASS_NONE
Definition: rz_type.h:62
@ RZ_TYPE_TYPECLASS_INVALID
Definition: rz_type.h:69
@ RZ_TYPE_TYPECLASS_ADDRESS
Definition: rz_type.h:66
@ RZ_TYPE_TYPECLASS_NUM
Definition: rz_type.h:63
@ RZ_TYPE_TYPECLASS_INTEGRAL
Definition: rz_type.h:64
@ RZ_TYPE_TYPECLASS_INTEGRAL_SIGNED
Definition: rz_type.h:67
@ RZ_TYPE_TYPECLASS_INTEGRAL_UNSIGNED
Definition: rz_type.h:68
@ RZ_TYPE_KIND_IDENTIFIER
Definition: rz_type.h:128
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_BORROW
Definition: rz_types.h:63
RzTypeTypeclass typeclass
Definition: typeclass.c:315
const RzTypeDB * typedb
Definition: typeclass.c:313
const RzTypeDB * typedb
Definition: typeclass.c:294
RzTypeTypeclass typeclass
Definition: typeclass.c:296
RzList * types
Definition: typeclass.c:295
HtPP * types
Definition: rz_type.h:33
RZ_API RZ_BORROW const char * rz_type_identifier(RZ_NONNULL const RzType *type)
Returns the type C identifier.
Definition: type.c:1155
RZ_API bool rz_type_is_num(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Checks if the RzType is Num typeclass.
Definition: typeclass.c:188
static bool typeclass_is_integal(RzTypeTypeclass t)
Definition: typeclass.c:30
RZ_API bool rz_base_type_is_integral(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type)
Checks if the RzBaseType is Integral typeclass.
Definition: typeclass.c:203
static bool get_base_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type, RZ_NONNULL RzTypeTypeclass *typeclass)
Definition: typeclass.c:85
RZ_API bool rz_base_type_is_floating(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type)
Checks if the RzBaseType is Floating typeclass.
Definition: typeclass.c:233
RZ_API bool rz_base_type_is_integral_signed(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type)
Checks if the RzBaseType is Integral and Signed typeclass.
Definition: typeclass.c:255
static bool typeclass_is_num(RzTypeTypeclass t)
Definition: typeclass.c:26
RZ_API bool rz_type_is_integral_unsigned(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Checks if the RzType is Integral and Unsigned typeclass.
Definition: typeclass.c:288
RZ_API bool rz_type_is_integral(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Checks if the RzType is Integral typeclass.
Definition: typeclass.c:218
RZ_API bool rz_base_type_is_num(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type)
Checks if the RzBaseType is Num typeclass.
Definition: typeclass.c:173
RZ_API RZ_BORROW const char * rz_type_typeclass_as_string(RzTypeTypeclass typeclass)
Returns the string representation of a typeclass.
Definition: typeclass.c:39
RZ_API RzTypeTypeclass rz_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Gets the type class.
Definition: typeclass.c:160
RZ_API RZ_OWN RzList * rz_type_typeclass_get_all_sized(const RzTypeDB *typedb, RzTypeTypeclass typeclass, size_t size)
Returns the list of all base types given the typeclass and size.
Definition: typeclass.c:354
static bool base_type_typeclass_sized_collect_cb(void *user, const void *k, const void *v)
Definition: typeclass.c:319
static bool check_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzType *type, RzTypeTypeclass typeclass)
Definition: typeclass.c:132
RZ_API bool rz_base_type_is_integral_unsigned(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type)
Checks if the RzBaseType is Integral and Unsigned typeclass.
Definition: typeclass.c:277
RZ_API RzTypeTypeclass rz_type_typeclass_from_string(RZ_NONNULL const char *typeclass)
Returns the typeclass from the string name of it.
Definition: typeclass.c:66
RZ_API bool rz_type_is_integral_signed(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Checks if the RzType is Integral and Signed typeclass.
Definition: typeclass.c:266
RZ_API RZ_OWN RzBaseType * rz_type_typeclass_get_default_sized(const RzTypeDB *typedb, RzTypeTypeclass typeclass, size_t size)
Returns the default base type given the typeclass and size.
Definition: typeclass.c:370
static bool get_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzType *type, RzTypeTypeclass *typeclass)
Definition: typeclass.c:110
RZ_API RZ_OWN RzList * rz_type_typeclass_get_all(const RzTypeDB *typedb, RzTypeTypeclass typeclass)
Returns the list of all base types given the typeclass.
Definition: typeclass.c:338
RZ_API bool rz_type_is_floating(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Checks if the RzType is Floating typeclass.
Definition: typeclass.c:244
static bool check_base_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type, RzTypeTypeclass typeclass)
Definition: typeclass.c:123
static bool base_type_typeclass_collect_cb(void *user, const void *k, const void *v)
Definition: typeclass.c:299
RZ_API RzTypeTypeclass rz_base_type_typeclass(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *type)
Gets the base type class.
Definition: typeclass.c:147