Rizin
unix-like reverse engineering framework and cli tools
type.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2013-2020 sivaramaaa <sivaramaaa@gmail.com>
2 // SPDX-FileCopyrightText: 2013-2020 pancake <pancake@nopcode.org>
3 // SPDX-FileCopyrightText: 2013-2020 oddcoder <ahmedsoliman@oddcoder.com>
4 // SPDX-FileCopyrightText: 2019-2021 Anton Kochkov <anton.kochkov@gmail.com>
5 // SPDX-License-Identifier: LGPL-3.0-only
6 
7 #include <rz_util.h>
8 #include <rz_type.h>
9 #include <string.h>
10 #include <sdb.h>
11 
12 static void types_ht_free(HtPPKv *kv) {
13  free(kv->key);
14  rz_type_base_type_free(kv->value);
15 }
16 
17 static void formats_ht_free(HtPPKv *kv) {
18  free(kv->key);
19  free(kv->value);
20 }
21 
22 static void callables_ht_free(HtPPKv *kv) {
23  free(kv->key);
24  rz_type_callable_free(kv->value);
25 }
26 
35  RzTypeDB *typedb = RZ_NEW0(RzTypeDB);
36  if (!typedb) {
37  return NULL;
38  }
39  typedb->target = RZ_NEW0(RzTypeTarget);
40  if (!typedb->target) {
41  free(typedb);
42  return NULL;
43  }
44  typedb->target->default_type = strdup("int");
45  typedb->types = ht_pp_new(NULL, types_ht_free, NULL);
46  if (!typedb->types) {
47  goto rz_type_db_new_fail;
48  }
49  typedb->formats = ht_pp_new(NULL, formats_ht_free, NULL);
50  if (!typedb->formats) {
51  goto rz_type_db_new_fail;
52  }
53  typedb->callables = ht_pp_new(NULL, callables_ht_free, NULL);
54  if (!typedb->callables) {
55  goto rz_type_db_new_fail;
56  }
57  typedb->parser = rz_type_parser_init(typedb->types, typedb->callables);
58  if (!typedb->parser) {
59  goto rz_type_db_new_fail;
60  }
61  rz_io_bind_init(typedb->iob);
62  return typedb;
63 
64 rz_type_db_new_fail:
65  free((void *)typedb->target->default_type);
66  free(typedb->target);
67  ht_pp_free(typedb->types);
68  ht_pp_free(typedb->formats);
69  ht_pp_free(typedb->callables);
70  free(typedb);
71  return NULL;
72 }
73 
80  rz_type_parser_free(typedb->parser);
81  ht_pp_free(typedb->callables);
82  ht_pp_free(typedb->types);
83  ht_pp_free(typedb->formats);
84  free((void *)typedb->target->default_type);
85  free(typedb->target->os);
86  free(typedb->target->cpu);
87  free(typedb->target);
88  free(typedb);
89 }
90 
97  ht_pp_free(typedb->callables);
98  typedb->callables = ht_pp_new(NULL, callables_ht_free, NULL);
99  ht_pp_free(typedb->types);
100  typedb->types = ht_pp_new(NULL, types_ht_free, NULL);
101  rz_type_parser_free(typedb->parser);
102  typedb->parser = rz_type_parser_init(typedb->types, typedb->callables);
103 }
104 
109  ht_pp_free(typedb->formats);
110  typedb->formats = ht_pp_new(NULL, formats_ht_free, NULL);
111 }
112 
113 static void set_default_type(RzTypeTarget *target, int bits) {
114  if (target->default_type) {
115  free((void *)target->default_type);
116  }
117  switch (bits) {
118  case 8:
119  target->default_type = strdup("int8_t");
120  break;
121  case 16:
122  target->default_type = strdup("int16_t");
123  break;
124  case 32:
125  target->default_type = strdup("int32_t");
126  break;
127  case 64:
128  target->default_type = strdup("int64_t");
129  break;
130  default:
132  target->default_type = strdup("int");
133  }
134 }
135 
146  typedb->target->bits = bits;
147  // Also set the new default type
148  set_default_type(typedb->target, bits);
149 }
150 
161 RZ_API void rz_type_db_set_address_bits(RzTypeDB *typedb, int addr_bits) {
162  rz_return_if_fail(typedb);
163  typedb->target->addr_bits = addr_bits;
164 }
165 
175 RZ_API void rz_type_db_set_os(RzTypeDB *typedb, const char *os) {
176  free(typedb->target->os);
177  typedb->target->os = os ? strdup(os) : NULL;
178 }
179 
189 RZ_API void rz_type_db_set_cpu(RzTypeDB *typedb, const char *cpu) {
190  free(typedb->target->cpu);
191  typedb->target->cpu = cpu ? strdup(cpu) : NULL;
192 }
193 
202 RZ_API void rz_type_db_set_endian(RzTypeDB *typedb, bool big_endian) {
203  typedb->target->big_endian = big_endian;
204 }
205 
212  return typedb->target->addr_bits > 0 ? typedb->target->addr_bits : typedb->target->bits;
213 }
214 
223 RZ_API bool rz_type_db_del(RzTypeDB *typedb, RZ_NONNULL const char *name) {
224  rz_return_val_if_fail(typedb && name, false);
225  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
226  if (!btype) {
227  if (!rz_type_func_exist(typedb, name)) {
228  eprintf("Unrecognized type \"%s\"\n", name);
229  return false;
230  }
231  rz_type_func_delete(typedb, name);
232  return true;
233  }
234  rz_type_db_delete_base_type(typedb, btype);
235  return true;
236 }
237 
253 RZ_API void rz_type_db_init(RzTypeDB *typedb, const char *types_dir, const char *arch, int bits, const char *os) {
254  rz_return_if_fail(typedb && typedb->types && typedb->formats);
255 
256  // A workaround to fix loading incorrectly detected MacOS binaries
257  if (os && RZ_STR_ISNOTEMPTY(os) && !strcmp(os, "darwin")) {
258  os = "macos";
259  }
260 
261  // At first we load the basic types
262  // Atomic types
263  char *dbpath = rz_file_path_join(types_dir, "types-atomic.sdb");
264  if (rz_type_db_load_sdb(typedb, dbpath)) {
265  RZ_LOG_DEBUG("types: loaded \"%s\"\n", dbpath);
266  }
267  free(dbpath);
268  // C runtime types
269  dbpath = rz_file_path_join(types_dir, "types-libc.sdb");
270  if (rz_type_db_load_sdb(typedb, dbpath)) {
271  RZ_LOG_DEBUG("types: loaded \"%s\"\n", dbpath);
272  }
273  free(dbpath);
274 
275  // We do not load further if bits are not specified
276  if (bits <= 0) {
277  return;
278  }
279 
280  // Bits-specific types that are independent from architecture or OS
281  char tmp[100];
282  dbpath = rz_file_path_join(types_dir, rz_strf(tmp, "types-%d.sdb", bits));
283  if (rz_type_db_load_sdb(typedb, dbpath)) {
284  RZ_LOG_DEBUG("types: loaded \"%s\"\n", dbpath);
285  }
286  free(dbpath);
287 
288  // We do not load further if architecture is not specified
289  if (!arch) {
290  return;
291  }
292 
293  // Architecture-specific types
294  dbpath = rz_file_path_join(types_dir, rz_strf(tmp, "types-%s.sdb", arch));
295  if (rz_type_db_load_sdb(typedb, dbpath)) {
296  RZ_LOG_DEBUG("types: loaded \"%s\"\n", dbpath);
297  }
298  free(dbpath);
299 
300  // Architecture- and bits-specific types
301  dbpath = rz_file_path_join(types_dir, rz_strf(tmp, "types-%s-%d.sdb", arch, bits));
302  if (rz_type_db_load_sdb(typedb, dbpath)) {
303  RZ_LOG_DEBUG("types: loaded \"%s\"\n", dbpath);
304  }
305  free(dbpath);
306 
307  if (os) {
308  // OS-specific types
309  dbpath = rz_file_path_join(types_dir, rz_strf(tmp, "types-%s.sdb", os));
310  if (rz_type_db_load_sdb(typedb, dbpath)) {
311  RZ_LOG_DEBUG("types: loaded \"%s\"\n", dbpath);
312  }
313  free(dbpath);
314  dbpath = rz_file_path_join(types_dir, rz_strf(tmp, "types-%s-%d.sdb", os, bits));
315  if (rz_type_db_load_sdb(typedb, dbpath)) {
316  RZ_LOG_DEBUG("types: loaded \"%s\"\n", dbpath);
317  }
318  free(dbpath);
319  dbpath = rz_file_path_join(types_dir, rz_strf(tmp, "types-%s-%s.sdb", arch, os));
320  if (rz_type_db_load_sdb(typedb, dbpath)) {
321  RZ_LOG_DEBUG("types: loaded \"%s\"\n", dbpath);
322  }
323  free(dbpath);
324  dbpath = rz_file_path_join(types_dir, rz_strf(tmp, "types-%s-%s-%d.sdb", arch, os, bits));
325  if (rz_type_db_load_sdb(typedb, dbpath)) {
326  RZ_LOG_DEBUG("types: loaded \"%s\"\n", dbpath);
327  }
328  free(dbpath);
329  }
330 
331  // Then, after all basic types are initialized, we load function types
332  // that use loaded previously base types for return and arguments
333  dbpath = rz_file_path_join(types_dir, "functions-libc.sdb");
334  if (rz_type_db_load_callables_sdb(typedb, dbpath)) {
335  RZ_LOG_DEBUG("callable types: loaded \"%s\"\n", dbpath);
336  }
337  free(dbpath);
338  // OS-specific function types
339  if (os) {
340  dbpath = rz_file_path_join(types_dir, rz_strf(tmp, "functions-%s.sdb", os));
341  if (rz_type_db_load_callables_sdb(typedb, dbpath)) {
342  RZ_LOG_DEBUG("callable types: loaded \"%s\"\n", dbpath);
343  }
344  free(dbpath);
345  }
346 }
347 
357 RZ_API void rz_type_db_reload(RzTypeDB *typedb, const char *types_dir) {
358  rz_type_db_purge(typedb);
359  rz_type_db_init(typedb, types_dir, typedb->target->cpu, typedb->target->bits, typedb->target->os);
360 }
361 
362 // Listing all available types by category
363 
370  rz_return_val_if_fail(typedb, NULL);
372  RzList *result = rz_list_new();
373  RzListIter *iter;
374  RzBaseType *e;
375  rz_list_foreach (enums, iter, e) {
376  rz_list_append(result, e->name);
377  }
378  rz_list_free(enums);
379  return result;
380 }
381 
388  rz_return_val_if_fail(typedb, NULL);
390  RzList *result = rz_list_new();
391  RzListIter *iter;
392  RzBaseType *u;
393  rz_list_foreach (unions, iter, u) {
394  rz_list_append(result, u->name);
395  }
396  rz_list_free(unions);
397  return result;
398 }
399 
406  rz_return_val_if_fail(typedb, NULL);
408  RzList *result = rz_list_new();
409  RzListIter *iter;
410  RzBaseType *s;
411  rz_list_foreach (structs, iter, s) {
412  rz_list_append(result, s->name);
413  }
414  rz_list_free(structs);
415  return result;
416 }
417 
424  rz_return_val_if_fail(typedb, NULL);
426  RzList *result = rz_list_new();
427  RzListIter *iter;
428  RzBaseType *t;
429  rz_list_foreach (typedefs, iter, t) {
430  rz_list_append(result, t->name);
431  }
432  rz_list_free(typedefs);
433  return result;
434 }
435 
441 RZ_API RZ_OWN RzList /*<char *>*/ *rz_type_db_all(RzTypeDB *typedb) {
442  rz_return_val_if_fail(typedb, NULL);
444  RzList *result = rz_list_new();
445  RzListIter *iter;
446  RzBaseType *t;
447  rz_list_foreach (types, iter, t) {
448  rz_list_append(result, t->name);
449  }
451  return result;
452 }
453 
454 // Type-specific APIs
455 
462 RZ_API bool rz_type_exists(RzTypeDB *typedb, RZ_NONNULL const char *name) {
463  rz_return_val_if_fail(typedb && name, -1);
464  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
465  return btype != NULL;
466 }
467 
474 RZ_API int rz_type_kind(RzTypeDB *typedb, RZ_NONNULL const char *name) {
475  rz_return_val_if_fail(typedb && name, -1);
476  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
477  if (!btype) {
478  return -1;
479  }
480  return btype->kind;
481 }
482 
490  rz_return_val_if_fail(typedb && name, NULL);
491  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
492  if (!btype) {
493  return NULL;
494  }
495  if (btype->kind != RZ_BASE_TYPE_KIND_ENUM) {
496  return NULL;
497  }
498  return btype;
499 }
500 
508 RZ_API RZ_BORROW const char *rz_type_db_enum_member_by_val(const RzTypeDB *typedb, RZ_NONNULL const char *name, ut64 val) {
509  rz_return_val_if_fail(typedb && name, NULL);
510  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
511  if (!btype) {
512  return NULL;
513  }
514  if (btype->kind != RZ_BASE_TYPE_KIND_ENUM) {
515  return NULL;
516  }
517  RzTypeEnumCase *cas;
518  rz_vector_foreach(&btype->enum_data.cases, cas) {
519  if (cas->val == val) {
520  return cas->name;
521  }
522  }
523  return NULL;
524 }
525 
533 RZ_API int rz_type_db_enum_member_by_name(const RzTypeDB *typedb, RZ_NONNULL const char *name, const char *member) {
534  rz_return_val_if_fail(typedb && name, -1);
535  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
536  if (!btype) {
537  return -1;
538  }
539  if (btype->kind != RZ_BASE_TYPE_KIND_ENUM) {
540  return -1;
541  }
542  RzTypeEnumCase *cas;
543  int result = -1;
544  rz_vector_foreach(&btype->enum_data.cases, cas) {
545  if (!strcmp(cas->name, member)) {
546  result = cas->val;
547  break;
548  }
549  }
550  return result;
551 }
552 
560  rz_return_val_if_fail(typedb, NULL);
562  RzList *result = rz_list_newf(free);
563  RzListIter *iter;
564  RzBaseType *e;
565  rz_list_foreach (enums, iter, e) {
566  RzTypeEnumCase *cas;
567  rz_vector_foreach(&e->enum_data.cases, cas) {
568  if (cas->val == val) {
569  rz_list_append(result, rz_str_newf("%s.%s", e->name, cas->name));
570  }
571  }
572  }
573  rz_list_free(enums);
574  return result;
575 }
576 
585  rz_return_val_if_fail(typedb && name, NULL);
586  char *res = NULL;
587  int i;
588  bool isFirst = true;
589 
590  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
591  if (!btype) {
592  return NULL;
593  }
594  if (btype->kind != RZ_BASE_TYPE_KIND_ENUM) {
595  return NULL;
596  }
597  char *ret = rz_str_newf("0x%08" PFMT64x " : ", val);
598  for (i = 0; i < 32; i++) {
599  ut32 n = 1ULL << i;
600  if (!(val & n)) {
601  continue;
602  }
603  RzTypeEnumCase *cas;
604  rz_vector_foreach(&btype->enum_data.cases, cas) {
605  if (cas->val == n) {
606  res = cas->name;
607  break;
608  }
609  }
610  if (isFirst) {
611  isFirst = false;
612  } else {
613  ret = rz_str_append(ret, " | ");
614  }
615  if (res) {
616  ret = rz_str_append(ret, res);
617  } else {
618  ret = rz_str_appendf(ret, "0x%x", n);
619  }
620  }
621  return ret;
622 }
623 
631  rz_return_val_if_fail(typedb && name, NULL);
632  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
633  if (!btype) {
634  return NULL;
635  }
636  if (btype->kind != RZ_BASE_TYPE_KIND_UNION) {
637  return NULL;
638  }
639  return btype;
640 }
641 
649  rz_return_val_if_fail(typedb && name, NULL);
650  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
651  if (!btype) {
652  return NULL;
653  }
654  if (btype->kind != RZ_BASE_TYPE_KIND_STRUCT) {
655  return NULL;
656  }
657  return btype;
658 }
659 
667  rz_return_val_if_fail(typedb && name, NULL);
668  RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
669  if (!btype) {
670  return NULL;
671  }
672  if (btype->kind != RZ_BASE_TYPE_KIND_TYPEDEF) {
673  return NULL;
674  }
675  return btype;
676 }
677 
685  rz_return_val_if_fail(typedb && btype && btype->kind == RZ_BASE_TYPE_KIND_ATOMIC, 0);
686  return btype->size;
687 }
688 
696  rz_return_val_if_fail(typedb && btype && btype->kind == RZ_BASE_TYPE_KIND_ENUM, 0);
697  // FIXME: Need a proper way to determine size of enum
698  return 32;
699 }
700 
708  rz_return_val_if_fail(typedb && btype && btype->kind == RZ_BASE_TYPE_KIND_STRUCT, 0);
709  RzTypeStructMember *memb;
710  ut64 size = 0;
711  rz_vector_foreach(&btype->struct_data.members, memb) {
712  size += rz_type_db_get_bitsize(typedb, memb->type);
713  }
714  return size;
715 }
716 
724  rz_return_val_if_fail(typedb && btype && btype->kind == RZ_BASE_TYPE_KIND_UNION, 0);
725  RzTypeUnionMember *memb;
726  ut64 size = 0;
727  // Union has the size of the maximum size of its elements
728  rz_vector_foreach(&btype->union_data.members, memb) {
729  size = RZ_MAX(rz_type_db_get_bitsize(typedb, memb->type), size);
730  }
731  return size;
732 }
733 
741  rz_return_val_if_fail(typedb && btype && btype->kind == RZ_BASE_TYPE_KIND_TYPEDEF, 0);
742  rz_return_val_if_fail(btype->type, 0);
743  if (btype->type->kind == RZ_TYPE_KIND_IDENTIFIER && !strcmp(btype->type->identifier.name, btype->name)) {
744  return btype->size;
745  }
746  return rz_type_db_get_bitsize(typedb, btype->type);
747 }
748 
756  rz_return_val_if_fail(typedb && btype, 0);
757  if (btype->kind == RZ_BASE_TYPE_KIND_ENUM) {
758  return rz_type_db_enum_bitsize(typedb, btype);
759  } else if (btype->kind == RZ_BASE_TYPE_KIND_STRUCT) {
760  return rz_type_db_struct_bitsize(typedb, btype);
761  } else if (btype->kind == RZ_BASE_TYPE_KIND_UNION) {
762  return rz_type_db_union_bitsize(typedb, btype);
763  } else if (btype->kind == RZ_BASE_TYPE_KIND_ATOMIC) {
764  return rz_type_db_atomic_bitsize(typedb, btype);
765  } else if (btype->kind == RZ_BASE_TYPE_KIND_TYPEDEF) {
766  return rz_type_db_typedef_bitsize(typedb, btype);
767  }
768  // Should not happen
770  return 0;
771 }
772 
780  rz_return_val_if_fail(typedb && type, 0);
781  // Detect if the pointer and return the corresponding size
782  if (type->kind == RZ_TYPE_KIND_POINTER || type->kind == RZ_TYPE_KIND_CALLABLE) {
783  // Note, that function types (RzCallable) are in fact pointers too
784  return rz_type_db_pointer_size(typedb);
785  // Detect if the pointer is array, then return the bitsize of the base type
786  // multiplied to the array size
787  } else if (type->kind == RZ_TYPE_KIND_ARRAY) {
788  return type->array.count * rz_type_db_get_bitsize(typedb, type->array.type);
789  }
790  // The rest of the logic is for the normal, identifier types
791  RzBaseType *btype = rz_type_db_get_base_type(typedb, type->identifier.name);
792  if (!btype) {
793  return 0;
794  }
795  if (btype->kind == RZ_BASE_TYPE_KIND_ENUM && type->identifier.kind == RZ_TYPE_IDENTIFIER_KIND_ENUM) {
796  return rz_type_db_enum_bitsize(typedb, btype);
797  } else if (btype->kind == RZ_BASE_TYPE_KIND_STRUCT && type->identifier.kind == RZ_TYPE_IDENTIFIER_KIND_STRUCT) {
798  return rz_type_db_struct_bitsize(typedb, btype);
799  } else if (btype->kind == RZ_BASE_TYPE_KIND_UNION && type->identifier.kind == RZ_TYPE_IDENTIFIER_KIND_UNION) {
800  return rz_type_db_union_bitsize(typedb, btype);
801  } else if (btype->kind == RZ_BASE_TYPE_KIND_ATOMIC) {
802  return rz_type_db_atomic_bitsize(typedb, btype);
803  } else if (btype->kind == RZ_BASE_TYPE_KIND_TYPEDEF) {
804  return rz_type_db_typedef_bitsize(typedb, btype);
805  }
806  // Should not happen
808  return 0;
809 }
810 
818  rz_return_val_if_fail(typedb && type, NULL);
819 
821 }
822 
830  rz_return_val_if_fail(typedb && type, NULL);
831 
833 }
834 
841 RZ_API RZ_OWN char *rz_type_identifier_declaration_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type, RZ_NONNULL const char *identifier) {
842  rz_return_val_if_fail(typedb && type, NULL);
843 
844  return rz_type_as_pretty_string(typedb, type, identifier, RZ_TYPE_PRINT_ZERO_VLA | RZ_TYPE_PRINT_NO_END_SEMICOLON | RZ_TYPE_PRINT_UNFOLD_ANON_ONLY_STRICT, 1); // one level unfold (for anonymous only)
845 }
846 
848  RzStrBuf *typename;
851 };
852 
853 static bool type_decl_as_pretty_string(const RzTypeDB *typedb, const RzType *type, HtPP *used_types, struct PrettyHelperBufs phbuf, bool *self_ref, char **self_ref_typename, bool zero_vla, bool print_anon, bool show_typedefs) {
854  rz_return_val_if_fail(typedb && type && used_types && self_ref, false);
855 
856  bool is_anon = false;
857  switch (type->kind) {
859  if (!type->identifier.name) {
860  return false;
861  }
862  is_anon = !strncmp(type->identifier.name, "anonymous ", strlen("anonymous "));
863  *self_ref = false;
864  ht_pp_find(used_types, type->identifier.name, self_ref);
865  *self_ref = *self_ref && !is_anon; // no self_ref for anon types
866  *self_ref_typename = *self_ref ? strdup(type->identifier.name) : NULL;
867 
868  RzBaseType *btype = rz_type_db_get_base_type(typedb, type->identifier.name);
869  if (!btype) {
870  rz_strbuf_append(phbuf.typename, "unknown_t");
871  } else {
872  switch (btype->kind) {
874  rz_strbuf_appendf(phbuf.typename, "%sstruct", type->identifier.is_const ? "const " : "");
875  if (!is_anon || print_anon) {
876  rz_strbuf_appendf(phbuf.typename, " %s", btype->name);
877  }
878  break;
880  rz_strbuf_appendf(phbuf.typename, "%sunion", type->identifier.is_const ? "const " : "");
881  if (!is_anon || print_anon) {
882  rz_strbuf_appendf(phbuf.typename, " %s", btype->name);
883  }
884  break;
886  rz_strbuf_appendf(phbuf.typename, "%senum", type->identifier.is_const ? "const " : "");
887  if (!is_anon || print_anon) {
888  rz_strbuf_appendf(phbuf.typename, " %s", btype->name);
889  }
890  break;
892  if (show_typedefs) {
893  char *typestr = rz_type_as_string(typedb, btype->type);
894  if (!typestr) {
895  RZ_LOG_ERROR("Failed to get type representation of typedef of base type: %s\n", btype->name);
896  return false;
897  }
898  rz_strbuf_appendf(phbuf.typename, "typedef %s", typestr);
899  free(typestr);
900  } else {
901  rz_strbuf_append(phbuf.typename, btype->name);
902  }
903  break;
904  }
906  rz_strbuf_appendf(phbuf.typename, "%s%s", type->identifier.is_const ? "const " : "", btype->name);
907  break;
908  default:
910  break;
911  }
912  }
913  break;
914  }
916  if (rz_type_is_callable_ptr_nested(type)) { // function pointers
917  char *typestr = rz_type_callable_ptr_as_string(typedb, type);
918  rz_strbuf_append(phbuf.typename, typestr);
919  free(typestr);
920  } else {
921  type_decl_as_pretty_string(typedb, type->pointer.type, used_types, phbuf, self_ref, self_ref_typename, zero_vla, print_anon, show_typedefs);
922  rz_strbuf_append(phbuf.pointerbuf, "*");
923  rz_strbuf_appendf(phbuf.pointerbuf, "%s", type->pointer.is_const ? " const " : "");
924  }
925  break;
926  case RZ_TYPE_KIND_ARRAY:
927  if (type->array.count) {
928  rz_strbuf_appendf(phbuf.arraybuf, "[%" PFMT64d "]", type->array.count);
929  } else { // variable length arrays
930  rz_strbuf_appendf(phbuf.arraybuf, "[%s]", zero_vla ? "0" : "");
931  }
932  type_decl_as_pretty_string(typedb, type->array.type, used_types, phbuf, self_ref, self_ref_typename, zero_vla, print_anon, show_typedefs);
933  break;
934  case RZ_TYPE_KIND_CALLABLE: {
935  char *callstr = rz_type_callable_as_string(typedb, type->callable);
936  rz_strbuf_append(phbuf.typename, callstr);
937  free(callstr);
938  break;
939  }
940  default:
942  break;
943  }
944 
945  return true;
946 }
947 
948 static char *type_as_pretty_string(const RzTypeDB *typedb, const RzType *type, const char *identifier, HtPP *used_types, unsigned int opts, int unfold_level, int indent_level) {
949  rz_return_val_if_fail(typedb && type, NULL);
950 
951  if (unfold_level < 0) { // recursion base case
952  return NULL;
953  }
954  bool multiline = opts & RZ_TYPE_PRINT_MULTILINE;
955  bool anon_only = opts & RZ_TYPE_PRINT_UNFOLD_ANON_ONLY;
956  bool anon_only_strict = opts & RZ_TYPE_PRINT_UNFOLD_ANON_ONLY_STRICT;
957  bool zero_vla = opts & RZ_TYPE_PRINT_ZERO_VLA;
958  bool print_anon = opts & RZ_TYPE_PRINT_ANONYMOUS;
959  bool no_end_semicolon = opts & RZ_TYPE_PRINT_NO_END_SEMICOLON;
960  no_end_semicolon = no_end_semicolon && (indent_level == 0); // indent_level needs to be zero for the last semicolon
961  bool end_newline = opts & RZ_TYPE_PRINT_END_NEWLINE;
962  end_newline = end_newline && (indent_level == 0); // only append newline for the outer type
963  bool show_typedefs = opts & RZ_TYPE_PRINT_SHOW_TYPEDEF;
964  if (indent_level == 0) { // for the root type, disregard anon_only
965  anon_only = false;
966  }
967  anon_only = anon_only || anon_only_strict;
968  bool unfold_all = !anon_only && unfold_level;
969  bool unfold_anon = unfold_level;
970  int indent = 0;
971  char *separator = " ";
972  if (multiline) {
973  indent = indent_level; // indent only if multiline
974  separator = "\n";
975  }
976 
977  RzStrBuf *buf = rz_strbuf_new("");
978  for (int i = 0; i < indent; i++) {
979  rz_strbuf_append(buf, "\t");
980  }
981  RzStrBuf *typename = rz_strbuf_new("");
982  RzStrBuf *pointer_buf = rz_strbuf_new("");
983  RzStrBuf *array_buf = rz_strbuf_new("");
984  struct PrettyHelperBufs phbuf = { typename, pointer_buf, array_buf };
985  bool self_ref = false;
986  char *self_ref_typename = NULL;
987  bool decl = type_decl_as_pretty_string(typedb, type, used_types, phbuf, &self_ref, &self_ref_typename, zero_vla, print_anon, show_typedefs);
988  if (!decl) {
990  rz_strbuf_free(typename);
991  rz_strbuf_free(pointer_buf);
992  rz_strbuf_free(array_buf);
993  return NULL;
994  }
995  if (self_ref) { // in case of self referntial type
996  unfold_level = 0; // no unfold
997  unfold_anon = unfold_all = false;
998  } else if (self_ref_typename) {
999  ht_pp_insert(used_types, self_ref_typename, NULL); // add the type to the ht
1000  }
1001  RzBaseType *btype = NULL;
1002  bool is_anon = false;
1003  if (type->kind == RZ_TYPE_KIND_IDENTIFIER) {
1004  is_anon = !strncmp(type->identifier.name, "anonymous ", 10);
1005  btype = rz_type_db_get_base_type(typedb, type->identifier.name);
1007  identifier = NULL; // no need to separately print identifier for function pointers or functions
1008  }
1009  char *typename_str = rz_strbuf_drain(phbuf.typename);
1010  char *pointer_str = rz_strbuf_drain(phbuf.pointerbuf);
1011  char *array_str = rz_strbuf_drain(phbuf.arraybuf);
1012  rz_strbuf_append(buf, typename_str);
1013 
1014  if (btype) {
1015  bool not_empty; // to check if no members are present
1016  switch (btype->kind) {
1018  if (unfold_all || (is_anon && unfold_anon)) {
1019  rz_strbuf_append(buf, " {");
1020  RzTypeStructMember *memb;
1021  not_empty = rz_vector_len(&btype->struct_data.members);
1022  if (not_empty) {
1023  rz_strbuf_appendf(buf, "%s", multiline ? "\n" : " ");
1024  }
1025  rz_vector_foreach(&btype->struct_data.members, memb) {
1026  char *unfold = type_as_pretty_string(typedb, memb->type, memb->name, used_types, opts, unfold_level - 1, indent_level + 1);
1027  rz_strbuf_appendf(buf, "%s%s", unfold, separator);
1028  free(unfold);
1029  }
1030  for (int i = 0; i < indent; i++) {
1031  rz_strbuf_append(buf, "\t");
1032  }
1033  rz_strbuf_append(buf, "}");
1034  }
1035  break;
1037  if (unfold_all || (is_anon && unfold_anon)) {
1038  rz_strbuf_append(buf, " {");
1039  RzTypeUnionMember *memb;
1040  not_empty = rz_vector_len(&btype->union_data.members);
1041  if (not_empty) {
1042  rz_strbuf_appendf(buf, "%s", multiline ? "\n" : " ");
1043  }
1044  rz_vector_foreach(&btype->union_data.members, memb) {
1045  char *unfold = type_as_pretty_string(typedb, memb->type, memb->name, used_types, opts, unfold_level - 1, indent_level + 1);
1046  rz_strbuf_appendf(buf, "%s%s", unfold, separator);
1047  free(unfold);
1048  }
1049  for (int i = 0; i < indent; i++) {
1050  rz_strbuf_append(buf, "\t");
1051  }
1052  rz_strbuf_append(buf, "}");
1053  }
1054  break;
1056  if (unfold_all || (is_anon && unfold_anon)) {
1057  RzTypeEnumCase *cas;
1058  rz_strbuf_append(buf, " {");
1059  if (multiline) {
1060  indent++; // no recursive call, so manually need to update indent
1061  }
1062  not_empty = rz_vector_len(&btype->enum_data.cases);
1063  if (not_empty) {
1064  rz_strbuf_appendf(buf, "%s", multiline ? "\n" : " ");
1065  }
1066  rz_vector_foreach(&btype->enum_data.cases, cas) {
1067  for (int i = 0; i < indent; i++) {
1068  rz_strbuf_append(buf, "\t");
1069  }
1070  rz_strbuf_appendf(buf, "%s = 0x%" PFMT64x ",%s", cas->name, cas->val, separator);
1071  }
1072  if (not_empty) {
1074  rz_strbuf_append(buf, separator);
1075  }
1076  if (multiline) {
1077  indent--; // restore the original value
1078  }
1079  for (int i = 0; i < indent; i++) {
1080  rz_strbuf_append(buf, "\t");
1081  }
1082  rz_strbuf_append(buf, "}");
1083  }
1084  break;
1086  if (show_typedefs && !rz_type_is_callable_ptr_nested(btype->type)) { // if not a callable
1087  rz_strbuf_appendf(buf, " %s", btype->name);
1088  }
1089  break;
1091  break;
1092  default:
1094  break;
1095  }
1096  }
1097 
1098  if (rz_str_nlen(pointer_str, 1) != 0 || identifier || rz_str_nlen(array_str, 1) != 0) {
1099  rz_strbuf_append(buf, " "); // add space only if the type is pointer or an array or has an identifier
1100  }
1101  rz_strbuf_appendf(buf, "%s%s%s", pointer_str ? pointer_str : "", identifier ? identifier : "", array_str ? array_str : "");
1102  if (!no_end_semicolon) {
1103  rz_strbuf_append(buf, ";");
1104  }
1105  if (end_newline) {
1106  rz_strbuf_append(buf, "\n");
1107  }
1108  if (self_ref_typename) {
1109  ht_pp_delete(used_types, self_ref_typename);
1110  free(self_ref_typename);
1111  }
1112  free(typename_str);
1113  free(pointer_str);
1114  free(array_str);
1115 
1116  char *pretty_type = rz_strbuf_drain(buf);
1117  return pretty_type;
1118 }
1119 
1130 RZ_API RZ_OWN char *rz_type_as_pretty_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type, RZ_NULLABLE const char *identifier, unsigned int opts, int unfold_level) {
1131  rz_return_val_if_fail(typedb && type, NULL);
1132 
1133  if (unfold_level < 0) { // any negative number means maximum unfolding
1134  unfold_level = INT32_MAX;
1135  }
1136  HtPP *used_types = ht_pp_new0(); // use a hash table to keep track of unfolded types
1137  if (!used_types) {
1138  RZ_LOG_ERROR("Failed to create hashtable while pretty printing types")
1139  return NULL;
1140  }
1141  char *pretty_type = type_as_pretty_string(typedb, type, identifier, used_types, opts, unfold_level, 0);
1142  ht_pp_free(used_types);
1143  return pretty_type;
1144 }
1145 
1157 
1158  switch (type->kind) {
1159  case RZ_TYPE_KIND_IDENTIFIER: {
1160  // Here it can be any of the RzBaseType
1161  return type->identifier.name;
1162  }
1163  case RZ_TYPE_KIND_POINTER: {
1164  return rz_type_identifier(type->pointer.type);
1165  }
1166  case RZ_TYPE_KIND_ARRAY: {
1167  return rz_type_identifier(type->array.type);
1168  break;
1169  }
1170  case RZ_TYPE_KIND_CALLABLE:
1171  return type->callable->name;
1172  }
1173  return NULL;
1174 }
1175 
1183  RzType *newtype = RZ_NEW0(RzType);
1184  if (!newtype) {
1185  return NULL;
1186  }
1187  switch (type->kind) {
1189  newtype->kind = type->kind;
1190  newtype->identifier.kind = type->identifier.kind;
1191  newtype->identifier.is_const = type->identifier.is_const;
1192  newtype->identifier.name = strdup(type->identifier.name);
1193  break;
1194  case RZ_TYPE_KIND_ARRAY:
1195  newtype->kind = RZ_TYPE_KIND_ARRAY;
1196  newtype->array.count = type->array.count;
1197  newtype->array.type = rz_type_clone(type->array.type);
1198  break;
1199  case RZ_TYPE_KIND_POINTER:
1200  newtype->kind = RZ_TYPE_KIND_POINTER;
1201  newtype->pointer.is_const = type->pointer.is_const;
1202  newtype->pointer.type = rz_type_clone(type->pointer.type);
1203  break;
1204  case RZ_TYPE_KIND_CALLABLE:
1205  newtype->kind = RZ_TYPE_KIND_CALLABLE;
1206  newtype->callable = rz_type_callable_clone(type->callable);
1207  break;
1208  }
1209  return newtype;
1210 }
1211 
1218 RZ_API bool rz_types_equal(RZ_NONNULL const RzType *type1, RZ_NONNULL const RzType *type2) {
1219  rz_return_val_if_fail(type1 && type2, false);
1220  if (type1->kind != type2->kind) {
1221  return false;
1222  }
1223  switch (type1->kind) {
1225  return !strcmp(type1->identifier.name, type2->identifier.name);
1226  case RZ_TYPE_KIND_POINTER:
1227  rz_return_val_if_fail(type1->pointer.type && type2->pointer.type, false);
1228  return rz_types_equal(type1->pointer.type, type2->pointer.type);
1229  case RZ_TYPE_KIND_ARRAY:
1230  if (type1->array.count != type2->array.count) {
1231  return false;
1232  }
1233  return rz_types_equal(type1->array.type, type2->array.type);
1234  case RZ_TYPE_KIND_CALLABLE:
1235  rz_return_val_if_fail(type1->callable && type2->callable, false);
1236  rz_return_val_if_fail(type1->callable->name && type2->callable->name, false);
1237  return !strcmp(type1->callable->name, type2->callable->name);
1238  default:
1240  return false;
1241  }
1242  return false;
1243 }
1244 
1252  rz_return_val_if_fail(type, false);
1253  const char *identifier = rz_type_identifier(type);
1254  if (!identifier) {
1255  return NULL;
1256  }
1257  RzBaseType *btype = rz_type_db_get_base_type(typedb, identifier);
1258  if (!btype) {
1259  return NULL;
1260  }
1261  return btype;
1262 }
1263 
1274  if (!type) {
1275  return;
1276  }
1277  switch (type->kind) {
1279  free(type->identifier.name);
1280  break;
1281  case RZ_TYPE_KIND_POINTER:
1282  rz_type_free(type->pointer.type);
1283  break;
1284  case RZ_TYPE_KIND_ARRAY:
1285  rz_type_free(type->array.type);
1286  break;
1287  case RZ_TYPE_KIND_CALLABLE:
1288  break;
1289  }
1290  free(type);
1291 }
1292 
1305 RZ_API bool rz_type_db_edit_base_type(RzTypeDB *typedb, RZ_NONNULL const char *name, RZ_NONNULL const char *typestr) {
1306  rz_return_val_if_fail(name && typestr, false);
1308  if (!t) {
1309  return false;
1310  }
1311  // Remove the original type first
1312  // but do not free them
1313  void *freefn = (void *)typedb->types->opt.freefn;
1314  typedb->types->opt.freefn = NULL;
1315  ht_pp_delete(typedb->types, t->name);
1316  typedb->types->opt.freefn = freefn;
1317  char *error_msg = NULL;
1318  int result = rz_type_parse_string_stateless(typedb->parser, typestr, &error_msg);
1319  if (result) {
1320  if (error_msg) {
1321  RZ_LOG_ERROR("%s\n", error_msg);
1322  }
1323  free(error_msg);
1324  // There is an error during the parsing thus we restore the old type
1325  // We insert the type back
1326  ht_pp_insert(typedb->types, t->name, t);
1327  return false;
1328  }
1329  // Free now unnecessary old base type
1331  return true;
1332 }
#define e(frag)
static ut32 cpu[32]
Definition: analysis_or1k.c:21
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
RZ_API void rz_type_base_type_free(RzBaseType *type)
Frees the RzBaseType instance and all of its members.
Definition: base.c:132
RZ_API RZ_OWN RzList * rz_type_db_get_base_types(const RzTypeDB *typedb)
Returns the list of all basic types.
Definition: base.c:120
RZ_API RZ_BORROW RzBaseType * rz_type_db_get_compound_type(const RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the compound RzBaseType in the types database given the name.
Definition: base.c:234
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
RZ_API bool rz_type_db_delete_base_type(RzTypeDB *typedb, RZ_NONNULL RzBaseType *type)
Removes RzBaseType from the Types DB.
Definition: base.c:74
RZ_API RZ_OWN RzList * rz_type_db_get_base_types_of_kind(const RzTypeDB *typedb, RzBaseTypeKind kind)
Returns the list of all basic types of the chosen kind.
Definition: base.c:100
int bits(struct state *s, int need)
Definition: blast.c:72
RZ_API RZ_OWN RzTypeParser * rz_type_parser_init(HtPP *types, HtPP *callables)
Creates a new instance of the C type parser.
Definition: c_cpp_parser.c:115
RZ_API void rz_type_parser_free(RZ_NONNULL RzTypeParser *parser)
Frees the instance of the C type parser without destroying hashtables.
Definition: c_cpp_parser.c:127
RZ_API int rz_type_parse_string_stateless(RzTypeParser *parser, const char *code, char **error_msg)
Parses the C type string reusing the existing parser state.
Definition: c_cpp_parser.c:227
#define RZ_API
#define NULL
Definition: cris-opc.c:27
cs_arch arch
Definition: cstool.c:13
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static void freefn(HtName_(Ht) *ht, HT_(Kv) *kv)
Definition: ht_inc.c:46
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
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
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
insn_type_descr_t types[]
Definition: or1k_disas.c:7
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API RZ_OWN char * rz_file_path_join(RZ_NONNULL const char *s1, RZ_NULLABLE const char *s2)
Concatenate two paths to create a new one with s1+s2 with the correct path separator.
Definition: file.c:1312
#define rz_io_bind_init(x)
Definition: rz_io.h:344
#define RZ_LOG_DEBUG(fmtstr,...)
Definition: rz_log.h:49
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
RZ_API char * rz_str_appendf(char *ptr, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_append(char *ptr, const char *string)
Definition: str.c:1063
RZ_API size_t rz_str_nlen(const char *s, size_t n)
Definition: str.c:1949
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API bool rz_strbuf_slice(RZ_NONNULL RzStrBuf *sb, size_t from, size_t len)
Cuts the current string into a substring.
Definition: strbuf.c:122
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API int rz_strbuf_length(RzStrBuf *sb)
Definition: strbuf.c:28
@ RZ_BASE_TYPE_KIND_TYPEDEF
Definition: rz_type.h:76
@ RZ_BASE_TYPE_KIND_ATOMIC
Definition: rz_type.h:77
@ RZ_BASE_TYPE_KIND_UNION
Definition: rz_type.h:74
@ RZ_BASE_TYPE_KIND_STRUCT
Definition: rz_type.h:73
@ RZ_BASE_TYPE_KIND_ENUM
Definition: rz_type.h:75
@ RZ_TYPE_IDENTIFIER_KIND_STRUCT
Definition: rz_type.h:136
@ RZ_TYPE_IDENTIFIER_KIND_ENUM
Definition: rz_type.h:138
@ RZ_TYPE_IDENTIFIER_KIND_UNION
Definition: rz_type.h:137
@ RZ_TYPE_PRINT_NO_END_SEMICOLON
Definition: rz_type.h:220
@ RZ_TYPE_PRINT_ZERO_VLA
Definition: rz_type.h:219
@ RZ_TYPE_PRINT_SHOW_TYPEDEF
Definition: rz_type.h:223
@ RZ_TYPE_PRINT_UNFOLD_ANON_ONLY
Definition: rz_type.h:217
@ RZ_TYPE_PRINT_UNFOLD_ANON_ONLY_STRICT
Definition: rz_type.h:218
@ RZ_TYPE_PRINT_END_NEWLINE
Definition: rz_type.h:222
@ RZ_TYPE_PRINT_MULTILINE
Definition: rz_type.h:216
@ RZ_TYPE_PRINT_ANONYMOUS
Definition: rz_type.h:221
@ RZ_TYPE_KIND_ARRAY
Definition: rz_type.h:130
@ RZ_TYPE_KIND_CALLABLE
Definition: rz_type.h:131
@ RZ_TYPE_KIND_IDENTIFIER
Definition: rz_type.h:128
@ RZ_TYPE_KIND_POINTER
Definition: rz_type.h:129
#define PFMT64d
Definition: rz_types.h:394
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define PFMT64x
Definition: rz_types.h:393
#define RZ_BORROW
Definition: rz_types.h:63
#define RZ_MAX(x, y)
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82
RZ_API bool rz_type_db_load_callables_sdb(RzTypeDB *typedb, RZ_NONNULL const char *path)
Loads the callable types from compiled SDB specified by path.
RZ_API bool rz_type_db_load_sdb(RzTypeDB *typedb, RZ_NONNULL const char *path)
Loads the types from compiled SDB specified by path.
#define INT32_MAX
RzStrBuf * arraybuf
Definition: type.c:850
RzStrBuf * pointerbuf
Definition: type.c:849
RzStrBuf * typename
Definition: type.c:848
Definition: z80asm.h:102
RzVector cases
Definition: rz_type.h:108
RzBaseTypeStruct struct_data
Definition: rz_type.h:118
char * name
Definition: rz_type.h:112
RzType * type
Definition: rz_type.h:113
RzBaseTypeEnum enum_data
Definition: rz_type.h:119
RzBaseTypeUnion union_data
Definition: rz_type.h:120
RzBaseTypeKind kind
Definition: rz_type.h:115
RzVector members
Definition: rz_type.h:104
RzTypeParser * parser
Definition: rz_type.h:37
HtPP * callables
Definition: rz_type.h:35
HtPP * formats
Definition: rz_type.h:34
RzIOBind iob
Definition: rz_type.h:39
HtPP * types
Definition: rz_type.h:33
RzTypeTarget * target
Definition: rz_type.h:36
RzTypeKind kind
Definition: rz_type.h:155
struct rz_type_t::@292::@295 pointer
struct rz_type_t::@292::@294 identifier
RzCallable * callable
Definition: rz_type.h:170
struct rz_type_t::@292::@296 array
int addr_bits
size of a pointer if > 0, otherwise bits is used.
Definition: rz_type.h:23
char * cpu
Definition: rz_type.h:21
const char * default_type
Definition: rz_type.h:26
bool big_endian
Definition: rz_type.h:25
RZ_API RZ_OWN RzCallable * rz_type_callable_clone(RZ_BORROW RZ_NONNULL const RzCallable *callable)
Creates an exact clone of the RzCallable type.
Definition: function.c:33
RZ_API bool rz_type_func_exist(RzTypeDB *typedb, RZ_NONNULL const char *name)
Checks if the RzCallable type exists in the database given the name.
Definition: function.c:203
RZ_API RZ_OWN char * rz_type_callable_ptr_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the callable pointer C representation.
Definition: function.c:464
RZ_API void rz_type_callable_free(RZ_NONNULL RzCallable *callable)
Frees the RzCallable.
Definition: function.c:55
RZ_API bool rz_type_func_delete(RzTypeDB *typedb, RZ_NONNULL const char *name)
Removes RzCallable type from the types database.
Definition: function.c:179
RZ_API RZ_OWN char * rz_type_callable_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzCallable *callable)
Returns the callable C representation.
Definition: function.c:487
RZ_API bool rz_type_is_callable_ptr_nested(RZ_NONNULL const RzType *type)
Checks if the RzType is the nested pointer to the RzCallable.
Definition: function.c:399
RZ_API void rz_type_db_set_address_bits(RzTypeDB *typedb, int addr_bits)
Set the RzType target adress size.
Definition: type.c:161
static char * type_as_pretty_string(const RzTypeDB *typedb, const RzType *type, const char *identifier, HtPP *used_types, unsigned int opts, int unfold_level, int indent_level)
Definition: type.c:948
RZ_API ut64 rz_type_db_union_bitsize(const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
Returns the union type size in bits (target dependent)
Definition: type.c:723
RZ_API void rz_type_db_reload(RzTypeDB *typedb, const char *types_dir)
Re-initializes the types database for current target.
Definition: type.c:357
RZ_API ut64 rz_type_db_base_get_bitsize(const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
Returns the base type size in bits (target dependent)
Definition: type.c:755
RZ_API int rz_type_kind(RzTypeDB *typedb, RZ_NONNULL const char *name)
Returns the kind (RzBaseTypeKind) of the type.
Definition: type.c:474
static void formats_ht_free(HtPPKv *kv)
Definition: type.c:17
RZ_API void rz_type_db_set_os(RzTypeDB *typedb, const char *os)
Set the RzType target architecture operating system.
Definition: type.c:175
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 void rz_type_db_set_bits(RzTypeDB *typedb, int bits)
Set the RzType target architecture bits.
Definition: type.c:145
RZ_API ut64 rz_type_db_get_bitsize(const RzTypeDB *typedb, RZ_NONNULL RzType *type)
Returns the type size in bits (target dependent)
Definition: type.c:779
RZ_API bool rz_types_equal(RZ_NONNULL const RzType *type1, RZ_NONNULL const RzType *type2)
Checks if two types are identical.
Definition: type.c:1218
RZ_API void rz_type_db_free(RzTypeDB *typedb)
Frees the instance of the RzTypeDB.
Definition: type.c:79
static bool type_decl_as_pretty_string(const RzTypeDB *typedb, const RzType *type, HtPP *used_types, struct PrettyHelperBufs phbuf, bool *self_ref, char **self_ref_typename, bool zero_vla, bool print_anon, bool show_typedefs)
Definition: type.c:853
RZ_API RZ_OWN char * rz_type_declaration_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the type C declaration representation.
Definition: type.c:829
RZ_API void rz_type_db_purge(RzTypeDB *typedb)
Purges the instance of the RzTypeDB.
Definition: type.c:96
static void set_default_type(RzTypeTarget *target, int bits)
Definition: type.c:113
RZ_API RZ_BORROW const char * rz_type_db_enum_member_by_val(const RzTypeDB *typedb, RZ_NONNULL const char *name, ut64 val)
Returns the enum case name matching the cpecified value.
Definition: type.c:508
RZ_API bool rz_type_exists(RzTypeDB *typedb, RZ_NONNULL const char *name)
Checks if the type exists in the Type database.
Definition: type.c:462
RZ_API bool rz_type_db_edit_base_type(RzTypeDB *typedb, RZ_NONNULL const char *name, RZ_NONNULL const char *typestr)
Edits the existing base type given the new C code.
Definition: type.c:1305
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
Definition: type.c:1273
RZ_API ut64 rz_type_db_typedef_bitsize(const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
Returns the typedef type size in bits (target dependent)
Definition: type.c:740
RZ_API RZ_OWN RzType * rz_type_clone(RZ_BORROW RZ_NONNULL const RzType *type)
Creates an exact clone of the RzType.
Definition: type.c:1181
RZ_API void rz_type_db_set_endian(RzTypeDB *typedb, bool big_endian)
Set the RzType target architecture CPU.
Definition: type.c:202
RZ_API RZ_OWN char * rz_type_as_pretty_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type, RZ_NULLABLE const char *identifier, unsigned int opts, int unfold_level)
Return a string contining the type pretty printed according to the options provided.
Definition: type.c:1130
RZ_API RzBaseType * rz_type_db_get_enum(const RzTypeDB *typedb, RZ_NONNULL const char *name)
Returns the enum base type matching the specified name.
Definition: type.c:489
RZ_API RZ_BORROW RzBaseType * rz_type_get_base_type(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the RzBaseType for the chosen RzType.
Definition: type.c:1251
RZ_API ut64 rz_type_db_enum_bitsize(const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
Returns the enum type size in bits (target dependent)
Definition: type.c:695
RZ_API ut8 rz_type_db_pointer_size(const RzTypeDB *typedb)
Returns the pointer size for the current RzTypeDB target set.
Definition: type.c:211
RZ_API ut64 rz_type_db_struct_bitsize(const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
Returns the struct type size in bits (target dependent)
Definition: type.c:707
RZ_API RZ_OWN RzList * rz_type_db_enum_names(RzTypeDB *typedb)
Returns the list of all enum names.
Definition: type.c:369
RZ_API RZ_OWN char * rz_type_db_enum_get_bitfield(const RzTypeDB *typedb, RZ_NONNULL const char *name, ut64 val)
Returns all matching bitfields as an OR mask given the resulting value.
Definition: type.c:584
RZ_API RzTypeDB * rz_type_db_new()
Creates a new instance of the RzTypeDB.
Definition: type.c:34
RZ_API void rz_type_db_init(RzTypeDB *typedb, const char *types_dir, const char *arch, int bits, const char *os)
Initializes the types database for specified arch, bits, OS.
Definition: type.c:253
static void types_ht_free(HtPPKv *kv)
Definition: type.c:12
RZ_API bool rz_type_db_del(RzTypeDB *typedb, RZ_NONNULL const char *name)
Removes the type from the database.
Definition: type.c:223
static void callables_ht_free(HtPPKv *kv)
Definition: type.c:22
RZ_API RZ_OWN RzList * rz_type_db_union_names(RzTypeDB *typedb)
Returns the list of all union names.
Definition: type.c:387
RZ_API ut64 rz_type_db_atomic_bitsize(const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
Returns the atomic type size in bits (target dependent)
Definition: type.c:684
RZ_API RZ_OWN RzList * rz_type_db_struct_names(RzTypeDB *typedb)
Returns the list of all struct names.
Definition: type.c:405
RZ_API RZ_OWN RzList * rz_type_db_all(RzTypeDB *typedb)
Returns the list of all type names.
Definition: type.c:441
RZ_API int rz_type_db_enum_member_by_name(const RzTypeDB *typedb, RZ_NONNULL const char *name, const char *member)
Returns the enum case value matched by the enum case name.
Definition: type.c:533
RZ_API RZ_OWN char * rz_type_identifier_declaration_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type, RZ_NONNULL const char *identifier)
Returns the type C representation with identifier.
Definition: type.c:841
RZ_API RzBaseType * rz_type_db_get_typedef(const RzTypeDB *typedb, RZ_NONNULL const char *name)
Returns the typedef base type matching the specified name.
Definition: type.c:666
RZ_API RZ_OWN RzList * rz_type_db_typedef_names(RzTypeDB *typedb)
Returns the list of all typedef (type aliases) names.
Definition: type.c:423
RZ_API RzBaseType * rz_type_db_get_union(const RzTypeDB *typedb, RZ_NONNULL const char *name)
Returns the union base type matching the specified name.
Definition: type.c:630
RZ_API RZ_OWN char * rz_type_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the type C representation.
Definition: type.c:817
RZ_API RzBaseType * rz_type_db_get_struct(const RzTypeDB *typedb, RZ_NONNULL const char *name)
returns the struct base type matching the specified name
Definition: type.c:648
RZ_API RZ_OWN RzList * rz_type_db_find_enums_by_val(const RzTypeDB *typedb, ut64 val)
Returns all enums and cases name matching the specified value.
Definition: type.c:559
RZ_API void rz_type_db_format_purge(RzTypeDB *typedb)
Purges formats in the instance of the RzTypeDB.
Definition: type.c:108
RZ_API void rz_type_db_set_cpu(RzTypeDB *typedb, const char *cpu)
Set the RzType target architecture CPU.
Definition: type.c:189
ut64(WINAPI *w32_GetEnabledXStateFeatures)()