Rizin
unix-like reverse engineering framework and cli tools
type.c File Reference
#include <rz_util.h>
#include <rz_type.h>
#include <string.h>
#include <sdb.h>

Go to the source code of this file.

Classes

struct  PrettyHelperBufs
 

Functions

static void types_ht_free (HtPPKv *kv)
 
static void formats_ht_free (HtPPKv *kv)
 
static void callables_ht_free (HtPPKv *kv)
 
RZ_API RzTypeDBrz_type_db_new ()
 Creates a new instance of the RzTypeDB. More...
 
RZ_API void rz_type_db_free (RzTypeDB *typedb)
 Frees the instance of the RzTypeDB. More...
 
RZ_API void rz_type_db_purge (RzTypeDB *typedb)
 Purges the instance of the RzTypeDB. More...
 
RZ_API void rz_type_db_format_purge (RzTypeDB *typedb)
 Purges formats in the instance of the RzTypeDB. More...
 
static void set_default_type (RzTypeTarget *target, int bits)
 
RZ_API void rz_type_db_set_bits (RzTypeDB *typedb, int bits)
 Set the RzType target architecture bits. More...
 
RZ_API void rz_type_db_set_address_bits (RzTypeDB *typedb, int addr_bits)
 Set the RzType target adress size. More...
 
RZ_API void rz_type_db_set_os (RzTypeDB *typedb, const char *os)
 Set the RzType target architecture operating system. More...
 
RZ_API void rz_type_db_set_cpu (RzTypeDB *typedb, const char *cpu)
 Set the RzType target architecture CPU. More...
 
RZ_API void rz_type_db_set_endian (RzTypeDB *typedb, bool big_endian)
 Set the RzType target architecture CPU. More...
 
RZ_API ut8 rz_type_db_pointer_size (const RzTypeDB *typedb)
 Returns the pointer size for the current RzTypeDB target set. More...
 
RZ_API bool rz_type_db_del (RzTypeDB *typedb, RZ_NONNULL const char *name)
 Removes the type from the database. More...
 
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. More...
 
RZ_API void rz_type_db_reload (RzTypeDB *typedb, const char *types_dir)
 Re-initializes the types database for current target. More...
 
RZ_API RZ_OWN RzListrz_type_db_enum_names (RzTypeDB *typedb)
 Returns the list of all enum names. More...
 
RZ_API RZ_OWN RzListrz_type_db_union_names (RzTypeDB *typedb)
 Returns the list of all union names. More...
 
RZ_API RZ_OWN RzListrz_type_db_struct_names (RzTypeDB *typedb)
 Returns the list of all struct names. More...
 
RZ_API RZ_OWN RzListrz_type_db_typedef_names (RzTypeDB *typedb)
 Returns the list of all typedef (type aliases) names. More...
 
RZ_API RZ_OWN RzListrz_type_db_all (RzTypeDB *typedb)
 Returns the list of all type names. More...
 
RZ_API bool rz_type_exists (RzTypeDB *typedb, RZ_NONNULL const char *name)
 Checks if the type exists in the Type database. More...
 
RZ_API int rz_type_kind (RzTypeDB *typedb, RZ_NONNULL const char *name)
 Returns the kind (RzBaseTypeKind) of the type. More...
 
RZ_API RzBaseTyperz_type_db_get_enum (const RzTypeDB *typedb, RZ_NONNULL const char *name)
 Returns the enum base type matching the specified name. More...
 
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. More...
 
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. More...
 
RZ_API RZ_OWN RzListrz_type_db_find_enums_by_val (const RzTypeDB *typedb, ut64 val)
 Returns all enums and cases name matching the specified value. More...
 
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. More...
 
RZ_API RzBaseTyperz_type_db_get_union (const RzTypeDB *typedb, RZ_NONNULL const char *name)
 Returns the union base type matching the specified name. More...
 
RZ_API RzBaseTyperz_type_db_get_struct (const RzTypeDB *typedb, RZ_NONNULL const char *name)
 returns the struct base type matching the specified name More...
 
RZ_API RzBaseTyperz_type_db_get_typedef (const RzTypeDB *typedb, RZ_NONNULL const char *name)
 Returns the typedef base type matching the specified name. More...
 
RZ_API ut64 rz_type_db_atomic_bitsize (const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
 Returns the atomic type size in bits (target dependent) More...
 
RZ_API ut64 rz_type_db_enum_bitsize (const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
 Returns the enum type size in bits (target dependent) More...
 
RZ_API ut64 rz_type_db_struct_bitsize (const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
 Returns the struct type size in bits (target dependent) More...
 
RZ_API ut64 rz_type_db_union_bitsize (const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
 Returns the union type size in bits (target dependent) More...
 
RZ_API ut64 rz_type_db_typedef_bitsize (const RzTypeDB *typedb, RZ_NONNULL RzBaseType *btype)
 Returns the typedef type size in bits (target dependent) More...
 
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) More...
 
RZ_API ut64 rz_type_db_get_bitsize (const RzTypeDB *typedb, RZ_NONNULL RzType *type)
 Returns the type size in bits (target dependent) More...
 
RZ_API RZ_OWN char * rz_type_as_string (const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
 Returns the type C representation. More...
 
RZ_API RZ_OWN char * rz_type_declaration_as_string (const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
 Returns the type C declaration representation. More...
 
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. More...
 
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)
 
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)
 
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. More...
 
RZ_API RZ_BORROW const char * rz_type_identifier (RZ_NONNULL const RzType *type)
 Returns the type C identifier. More...
 
RZ_API RZ_OWN RzTyperz_type_clone (RZ_BORROW RZ_NONNULL const RzType *type)
 Creates an exact clone of the RzType. More...
 
RZ_API bool rz_types_equal (RZ_NONNULL const RzType *type1, RZ_NONNULL const RzType *type2)
 Checks if two types are identical. More...
 
RZ_API RZ_BORROW RzBaseTyperz_type_get_base_type (const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
 Returns the RzBaseType for the chosen RzType. More...
 
RZ_API void rz_type_free (RZ_NULLABLE RzType *type)
 Frees the RzType. More...
 
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. More...
 

Function Documentation

◆ callables_ht_free()

static void callables_ht_free ( HtPPKv *  kv)
static

Definition at line 22 of file type.c.

22  {
23  free(kv->key);
24  rz_type_callable_free(kv->value);
25 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API void rz_type_callable_free(RZ_NONNULL RzCallable *callable)
Frees the RzCallable.
Definition: function.c:55

References free(), and rz_type_callable_free().

Referenced by rz_type_db_new(), and rz_type_db_purge().

◆ formats_ht_free()

static void formats_ht_free ( HtPPKv *  kv)
static

Definition at line 17 of file type.c.

17  {
18  free(kv->key);
19  free(kv->value);
20 }

References free().

Referenced by rz_type_db_format_purge(), and rz_type_db_new().

◆ rz_type_as_pretty_string()

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.

Parameters
typedbtypedb for the current analysis
typetype to be pretty printed
identifiername of the variable of the given type (RZ_NULLABLE)
optsoptions for pretty printing (see RzTypePrintOpts)
unfold_levellevel of unfolding to do in case of nested structures/unions (any negative number means maximum unfolding, i.e. INT32_MAX. 0 means no unfolding, just the typename and identifier, if any)
Returns
char* string in pretty printed form

Definition at line 1130 of file type.c.

1130  {
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 }
#define NULL
Definition: cris-opc.c:27
int type
Definition: mipsasm.c:17
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define INT32_MAX
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

References INT32_MAX, NULL, RZ_LOG_ERROR, rz_return_val_if_fail, type, and type_as_pretty_string().

Referenced by rz_type_as_string(), rz_type_db_base_type_as_pretty_string(), rz_type_db_base_type_as_string(), rz_type_declaration_as_string(), and rz_type_identifier_declaration_as_string().

◆ rz_type_as_string()

RZ_API RZ_OWN char* rz_type_as_string ( const RzTypeDB typedb,
RZ_NONNULL const RzType type 
)

Returns the type C representation.

Parameters
typedbTypes Database instance
typeRzType type

Definition at line 817 of file type.c.

817  {
818  rz_return_val_if_fail(typedb && type, NULL);
819 
821 }
@ RZ_TYPE_PRINT_NO_END_SEMICOLON
Definition: rz_type.h:220
@ RZ_TYPE_PRINT_ZERO_VLA
Definition: rz_type.h:219
@ RZ_TYPE_PRINT_ANONYMOUS
Definition: rz_type.h:221
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

References NULL, rz_return_val_if_fail, rz_type_as_pretty_string(), RZ_TYPE_PRINT_ANONYMOUS, RZ_TYPE_PRINT_NO_END_SEMICOLON, RZ_TYPE_PRINT_ZERO_VLA, and type.

Referenced by callable_as_string(), core_analysis_var_list_show(), ds_print_calls_hints(), ds_print_esil_analysis(), ds_show_functions(), ds_show_functions_argvar(), pdb_types_print_json(), print_fcn_arg(), rz_analysis_fcn_format_sig(), rz_analysis_function_get_json(), rz_analysis_function_vars_stackframe_handler(), rz_analysis_var_global_list_show(), rz_core_analysis_function_signature(), rz_core_types_function_print(), rz_core_types_link_print(), rz_core_types_struct_print(), rz_core_types_typedef_print(), rz_core_types_union_print(), rz_serialize_analysis_global_var_save(), rz_serialize_analysis_var_save(), save_callable(), save_struct(), save_typedef(), save_typelink(), save_union(), set_offset_hint(), type_decl_as_pretty_string(), type_match(), types_xrefs_function(), types_xrefs_graph(), types_xrefs_summary(), and var_variables_show().

◆ rz_type_clone()

RZ_API RZ_OWN RzType* rz_type_clone ( RZ_BORROW RZ_NONNULL const RzType type)

Creates an exact clone of the RzType.

Parameters
typeRzType pointer

Definition at line 1181 of file type.c.

1181  {
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 }
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")
@ 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 RZ_NEW0(x)
Definition: rz_types.h:284
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
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 RZ_OWN RzType * rz_type_clone(RZ_BORROW RZ_NONNULL const RzType *type)
Creates an exact clone of the RzType.
Definition: type.c:1181

References rz_type_t::array, rz_type_t::callable, rz_type_t::identifier, rz_type_t::kind, NULL, rz_type_t::pointer, RZ_NEW0, rz_return_val_if_fail, rz_type_callable_clone(), RZ_TYPE_KIND_ARRAY, RZ_TYPE_KIND_CALLABLE, RZ_TYPE_KIND_IDENTIFIER, RZ_TYPE_KIND_POINTER, strdup(), and type.

Referenced by function_argument_type_derive(), parse_enum(), parse_structure(), parse_type_nest(), parse_type_string_cached(), parse_union(), rz_analysis_fcn_vars_add_types(), rz_analysis_function_derive_args(), rz_analysis_function_derive_return_type(), rz_analysis_function_set_type(), rz_type_callable_arg_clone(), rz_type_callable_clone(), var_type_clone_or_default_type(), and var_type_set().

◆ rz_type_db_all()

RZ_API RZ_OWN RzList* rz_type_db_all ( RzTypeDB typedb)

Returns the list of all type names.

Parameters
typedbTypes Database instance

Definition at line 441 of file type.c.

441  {
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 }
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_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
insn_type_descr_t types[]
Definition: or1k_disas.c:7
char * name
Definition: rz_type.h:112

References rz_base_type_t::name, NULL, rz_list_append(), rz_list_free(), rz_list_new(), rz_return_val_if_fail, rz_type_db_get_base_types(), and types.

Referenced by autocmplt_cmd_arg_any_type().

◆ rz_type_db_atomic_bitsize()

RZ_API ut64 rz_type_db_atomic_bitsize ( const RzTypeDB typedb,
RZ_NONNULL RzBaseType btype 
)

Returns the atomic type size in bits (target dependent)

Parameters
typedbTypes Database instance
btypeThe base type

Definition at line 684 of file type.c.

684  {
685  rz_return_val_if_fail(typedb && btype && btype->kind == RZ_BASE_TYPE_KIND_ATOMIC, 0);
686  return btype->size;
687 }
@ RZ_BASE_TYPE_KIND_ATOMIC
Definition: rz_type.h:77

References RZ_BASE_TYPE_KIND_ATOMIC, and rz_return_val_if_fail.

Referenced by rz_type_db_base_get_bitsize(), and rz_type_db_get_bitsize().

◆ rz_type_db_base_get_bitsize()

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)

Parameters
typedbTypes Database instance
btypeThe base type

Definition at line 755 of file type.c.

755  {
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 }
#define rz_warn_if_reached()
Definition: rz_assert.h:29
@ RZ_BASE_TYPE_KIND_TYPEDEF
Definition: rz_type.h:76
@ 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_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 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 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 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 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

References RZ_BASE_TYPE_KIND_ATOMIC, RZ_BASE_TYPE_KIND_ENUM, RZ_BASE_TYPE_KIND_STRUCT, RZ_BASE_TYPE_KIND_TYPEDEF, RZ_BASE_TYPE_KIND_UNION, rz_return_val_if_fail, rz_type_db_atomic_bitsize(), rz_type_db_enum_bitsize(), rz_type_db_struct_bitsize(), rz_type_db_typedef_bitsize(), rz_type_db_union_bitsize(), and rz_warn_if_reached.

Referenced by rz_type_integral_set_sign().

◆ rz_type_db_del()

RZ_API bool rz_type_db_del ( RzTypeDB typedb,
RZ_NONNULL const char *  name 
)

Removes the type from the database.

Can remove either RzBaseType or RzCallable type

Parameters
typedbRzTypeDB instance
nameRzBaseType or RzCallable type name

Definition at line 223 of file type.c.

223  {
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 }
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
#define eprintf(x, y...)
Definition: rlcc.c:7
Definition: z80asm.h:102
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 bool rz_type_func_delete(RzTypeDB *typedb, RZ_NONNULL const char *name)
Removes RzCallable type from the types database.
Definition: function.c:179

References eprintf, rz_return_val_if_fail, rz_type_db_delete_base_type(), rz_type_db_get_base_type(), rz_type_func_delete(), and rz_type_func_exist().

Referenced by rz_type_del_handler().

◆ rz_type_db_edit_base_type()

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.

Searches the base type in the types database given the name. If it exists - parses the typestr as the new C type. If there is any error during the parsing it restores the original type in the database.

Parameters
typedbType Database instance
nameName of the base type
typestrC string of the new definition of the type

Definition at line 1305 of file type.c.

1305  {
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 }
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_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 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
static void freefn(HtName_(Ht) *ht, HT_(Kv) *kv)
Definition: ht_inc.c:46
RzTypeParser * parser
Definition: rz_type.h:37
HtPP * types
Definition: rz_type.h:33

References free(), freefn(), rz_base_type_t::name, NULL, rz_type_db_t::parser, RZ_LOG_ERROR, rz_return_val_if_fail, rz_type_base_type_free(), rz_type_db_get_compound_type(), rz_type_parse_string_stateless(), and rz_type_db_t::types.

Referenced by rz_types_open_editor().

◆ rz_type_db_enum_bitsize()

RZ_API ut64 rz_type_db_enum_bitsize ( const RzTypeDB typedb,
RZ_NONNULL RzBaseType btype 
)

Returns the enum type size in bits (target dependent)

Parameters
typedbTypes Database instance
btypeThe base type

Definition at line 695 of file type.c.

695  {
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 }

References RZ_BASE_TYPE_KIND_ENUM, and rz_return_val_if_fail.

Referenced by rz_type_db_base_get_bitsize(), and rz_type_db_get_bitsize().

◆ rz_type_db_enum_get_bitfield()

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.

Parameters
typedbTypes Database instance
nameThe name of the bitfield enum
valThe value to search for

Definition at line 584 of file type.c.

584  {
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 }
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
uint32_t ut32
int n
Definition: mipsasm.c:19
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
#define PFMT64x
Definition: rz_types.h:393
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
RzVector cases
Definition: rz_type.h:108
RzBaseTypeEnum enum_data
Definition: rz_type.h:119
RzBaseTypeKind kind
Definition: rz_type.h:115

References rz_base_type_enum_t::cases, rz_base_type_t::enum_data, i, rz_base_type_t::kind, n, rz_type_enum_case_t::name, NULL, PFMT64x, RZ_BASE_TYPE_KIND_ENUM, rz_return_val_if_fail, rz_str_append(), rz_str_appendf(), rz_str_newf(), rz_type_db_get_base_type(), rz_vector_foreach, val, and rz_type_enum_case_t::val.

Referenced by rz_type_format_bitfield().

◆ rz_type_db_enum_member_by_name()

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.

Parameters
typedbTypes Database instance
nameThe name of the enum to search in
memberThe enum case name to search for

Definition at line 533 of file type.c.

533  {
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 }

References rz_base_type_enum_t::cases, rz_base_type_t::enum_data, rz_base_type_t::kind, rz_type_enum_case_t::name, RZ_BASE_TYPE_KIND_ENUM, rz_return_val_if_fail, rz_type_db_get_base_type(), rz_vector_foreach, and rz_type_enum_case_t::val.

Referenced by rz_type_enum_bitfield_handler().

◆ rz_type_db_enum_member_by_val()

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.

Parameters
typedbTypes Database instance
nameThe name of the enum to search in
valThe value to search for

Definition at line 508 of file type.c.

508  {
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 }

References rz_base_type_enum_t::cases, rz_base_type_t::enum_data, rz_base_type_t::kind, rz_type_enum_case_t::name, NULL, RZ_BASE_TYPE_KIND_ENUM, rz_return_val_if_fail, rz_type_db_get_base_type(), rz_vector_foreach, val, and rz_type_enum_case_t::val.

Referenced by ds_show_flags(), rz_type_format_enum(), and types_enum_member_find().

◆ rz_type_db_enum_names()

RZ_API RZ_OWN RzList* rz_type_db_enum_names ( RzTypeDB typedb)

Returns the list of all enum names.

Parameters
typedbTypes Database instance

Definition at line 369 of file type.c.

369  {
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 }
#define e(frag)
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

References e, NULL, RZ_BASE_TYPE_KIND_ENUM, rz_list_append(), rz_list_free(), rz_list_new(), rz_return_val_if_fail, and rz_type_db_get_base_types_of_kind().

Referenced by autocmplt_cmd_arg_enum_type().

◆ rz_type_db_find_enums_by_val()

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.

Parameters
typedbTypes Database instance
valThe value to search for

Definition at line 559 of file type.c.

559  {
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 }
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

References e, free(), rz_type_enum_case_t::name, NULL, RZ_BASE_TYPE_KIND_ENUM, rz_list_append(), rz_list_free(), rz_list_newf(), rz_return_val_if_fail, rz_str_newf(), rz_type_db_get_base_types_of_kind(), rz_vector_foreach, val, and rz_type_enum_case_t::val.

Referenced by types_enum_member_find_all().

◆ rz_type_db_format_purge()

RZ_API void rz_type_db_format_purge ( RzTypeDB typedb)

Purges formats in the instance of the RzTypeDB.

Definition at line 108 of file type.c.

108  {
109  ht_pp_free(typedb->formats);
110  typedb->formats = ht_pp_new(NULL, formats_ht_free, NULL);
111 }
HtPP * formats
Definition: rz_type.h:34
static void formats_ht_free(HtPPKv *kv)
Definition: type.c:17

References rz_type_db_t::formats, formats_ht_free(), and NULL.

Referenced by cmd_print_format().

◆ rz_type_db_free()

RZ_API void rz_type_db_free ( RzTypeDB typedb)

Frees the instance of the RzTypeDB.

Destroys hashtables for RzBaseType, RzCallable, type formats.

Definition at line 79 of file type.c.

79  {
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 }
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
HtPP * callables
Definition: rz_type.h:35
RzTypeTarget * target
Definition: rz_type.h:36
char * cpu
Definition: rz_type.h:21
const char * default_type
Definition: rz_type.h:26

References rz_type_db_t::callables, rz_type_target_t::cpu, rz_type_target_t::default_type, rz_type_db_t::formats, free(), rz_type_target_t::os, rz_type_db_t::parser, rz_type_parser_free(), rz_type_db_t::target, and rz_type_db_t::types.

Referenced by rz_analysis_free().

◆ rz_type_db_get_bitsize()

RZ_API ut64 rz_type_db_get_bitsize ( const RzTypeDB typedb,
RZ_NONNULL RzType type 
)

Returns the type size in bits (target dependent)

Parameters
typedbTypes Database instance
typeThe type

Definition at line 779 of file type.c.

779  {
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 }
@ 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_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 ut8 rz_type_db_pointer_size(const RzTypeDB *typedb)
Returns the pointer size for the current RzTypeDB target set.
Definition: type.c:211

References rz_base_type_t::kind, RZ_BASE_TYPE_KIND_ATOMIC, RZ_BASE_TYPE_KIND_ENUM, RZ_BASE_TYPE_KIND_STRUCT, RZ_BASE_TYPE_KIND_TYPEDEF, RZ_BASE_TYPE_KIND_UNION, rz_return_val_if_fail, rz_type_db_atomic_bitsize(), rz_type_db_enum_bitsize(), rz_type_db_get_base_type(), rz_type_db_pointer_size(), rz_type_db_struct_bitsize(), rz_type_db_typedef_bitsize(), rz_type_db_union_bitsize(), RZ_TYPE_IDENTIFIER_KIND_ENUM, RZ_TYPE_IDENTIFIER_KIND_STRUCT, RZ_TYPE_IDENTIFIER_KIND_UNION, RZ_TYPE_KIND_ARRAY, RZ_TYPE_KIND_CALLABLE, RZ_TYPE_KIND_POINTER, rz_warn_if_reached, and type.

Referenced by extract_arg(), parse_enum(), path_walker(), rz_analysis_function_set_type(), rz_analysis_var_global_add(), rz_analysis_var_global_get_byaddr_in(), rz_analysis_var_global_set_type(), rz_analysis_var_resolve_overlaps(), rz_core_print_disasm(), rz_core_types_struct_print(), rz_core_types_union_print(), rz_type_db_struct_bitsize(), rz_type_db_struct_member_packed_offset(), rz_type_db_typedef_bitsize(), rz_type_db_union_bitsize(), rz_type_path_by_offset(), set_fcn_args_info(), structured_member_walker(), and var_add_structure_fields_to_list().

◆ rz_type_db_get_enum()

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.

Parameters
typedbTypes Database instance
nameThe name of the enum to match against

Definition at line 489 of file type.c.

489  {
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 }

References rz_base_type_t::kind, NULL, RZ_BASE_TYPE_KIND_ENUM, rz_return_val_if_fail, and rz_type_db_get_base_type().

Referenced by rz_analysis_function_blocks_switch_type_handler(), rz_type_enum_c_handler(), rz_type_enum_c_nl_handler(), and rz_type_list_enum_handler().

◆ rz_type_db_get_struct()

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

Parameters
typedbtypes database instance
namethe name of the struct to match against

Definition at line 648 of file type.c.

648  {
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 }

References rz_base_type_t::kind, NULL, RZ_BASE_TYPE_KIND_STRUCT, rz_return_val_if_fail, and rz_type_db_get_base_type().

Referenced by rz_type_list_structure_handler(), rz_type_structure_c_handler(), and rz_type_structure_c_nl_handler().

◆ rz_type_db_get_typedef()

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.

Parameters
typedbTypes Database instance
nameThe name of the typedef to match against

Definition at line 666 of file type.c.

666  {
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 }

References rz_base_type_t::kind, NULL, RZ_BASE_TYPE_KIND_TYPEDEF, rz_return_val_if_fail, and rz_type_db_get_base_type().

Referenced by rz_type_list_typedef_handler(), and rz_type_typedef_c_handler().

◆ rz_type_db_get_union()

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.

Parameters
typedbTypes Database instance
nameThe name of the union to match against

Definition at line 630 of file type.c.

630  {
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 }

References rz_base_type_t::kind, NULL, RZ_BASE_TYPE_KIND_UNION, rz_return_val_if_fail, and rz_type_db_get_base_type().

Referenced by rz_type_list_union_handler(), rz_type_union_c_handler(), and rz_type_union_c_nl_handler().

◆ rz_type_db_init()

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.

Loads pre-shipped type libraries for base types and function types. Different architectures, operating systems, bitness affects on what exact types are loaded, also some atomic types sizes are different. In some cases the same type, for example, structure type could have a different layout, depending on the operating system or bitness.

Parameters
typedbTypes Database instance
types_dirDirectory where all type libraries are installed
archArchitecture of the analysis session
bitsBitness of the analysis session
osOperating system of the analysis session

Definition at line 253 of file type.c.

253  {
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 }
int bits(struct state *s, int need)
Definition: blast.c:72
cs_arch arch
Definition: cstool.c:13
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
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_LOG_DEBUG(fmtstr,...)
Definition: rz_log.h:49
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
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.

References arch, bits(), rz_type_db_t::formats, free(), rz_file_path_join(), RZ_LOG_DEBUG, rz_return_if_fail, RZ_STR_ISNOTEMPTY, rz_strf, rz_type_db_load_callables_sdb(), rz_type_db_load_sdb(), autogen_x86imm::tmp, and rz_type_db_t::types.

Referenced by rz_core_analysis_type_init(), and rz_type_db_reload().

◆ rz_type_db_new()

RZ_API RzTypeDB* rz_type_db_new ( )

Creates a new instance of the RzTypeDB.

Creates the RzTypeDB instance, initializes hashtables for RzBaseType, RzCallable, type formats. Also initializes default "target" (arch, bits, platform) parameters.

Definition at line 34 of file type.c.

34  {
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 }
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
#define rz_io_bind_init(x)
Definition: rz_io.h:344
RzIOBind iob
Definition: rz_type.h:39
static void types_ht_free(HtPPKv *kv)
Definition: type.c:12
static void callables_ht_free(HtPPKv *kv)
Definition: type.c:22

References rz_type_db_t::callables, callables_ht_free(), rz_type_target_t::default_type, rz_type_db_t::formats, formats_ht_free(), free(), rz_type_db_t::iob, NULL, rz_type_db_t::parser, rz_io_bind_init, RZ_NEW0, rz_type_parser_init(), strdup(), rz_type_db_t::target, rz_type_db_t::types, and types_ht_free().

Referenced by rz_analysis_new().

◆ rz_type_db_pointer_size()

RZ_API ut8 rz_type_db_pointer_size ( const RzTypeDB typedb)

Returns the pointer size for the current RzTypeDB target set.

Parameters
typedbRzTypeDB instance

Definition at line 211 of file type.c.

211  {
212  return typedb->target->addr_bits > 0 ? typedb->target->addr_bits : typedb->target->bits;
213 }
int addr_bits
size of a pointer if > 0, otherwise bits is used.
Definition: rz_type.h:23

References rz_type_target_t::addr_bits, rz_type_target_t::bits, and rz_type_db_t::target.

Referenced by rz_type_db_get_bitsize().

◆ rz_type_db_purge()

RZ_API void rz_type_db_purge ( RzTypeDB typedb)

Purges the instance of the RzTypeDB.

Destroys all loaded base types and callable types.

Definition at line 96 of file type.c.

96  {
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 }

References rz_type_db_t::callables, callables_ht_free(), NULL, rz_type_db_t::parser, rz_type_parser_free(), rz_type_parser_init(), rz_type_db_t::types, and types_ht_free().

Referenced by rz_analysis_purge(), rz_type_db_reload(), and rz_type_del_all_handler().

◆ rz_type_db_reload()

RZ_API void rz_type_db_reload ( RzTypeDB typedb,
const char *  types_dir 
)

Re-initializes the types database for current target.

Similarly to rz_type_db_init loads pre-shipped type libraries for base types and function types.

Parameters
typedbTypes Database instance
types_dirDirectory where all type libraries are installed

Definition at line 357 of file type.c.

357  {
358  rz_type_db_purge(typedb);
359  rz_type_db_init(typedb, types_dir, typedb->target->cpu, typedb->target->bits, typedb->target->os);
360 }
RZ_API void rz_type_db_purge(RzTypeDB *typedb)
Purges the instance of the RzTypeDB.
Definition: type.c:96
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

References rz_type_target_t::bits, rz_type_target_t::cpu, rz_type_target_t::os, rz_type_db_init(), rz_type_db_purge(), and rz_type_db_t::target.

Referenced by analysis_set_os(), rz_analysis_set_bits(), and rz_analysis_set_cpu().

◆ rz_type_db_set_address_bits()

RZ_API void rz_type_db_set_address_bits ( RzTypeDB typedb,
int  addr_bits 
)

Set the RzType target adress size.

Important for calculating some types size, especially pointers's size.

Parameters
typedbRzTypeDB instance
bitssize of an address in bits. If <= 0, then the value from rz_type_db_set_bits() is used.

Definition at line 161 of file type.c.

161  {
162  rz_return_if_fail(typedb);
163  typedb->target->addr_bits = addr_bits;
164 }

References rz_type_target_t::addr_bits, rz_return_if_fail, and rz_type_db_t::target.

Referenced by rz_analysis_set_bits().

◆ rz_type_db_set_bits()

RZ_API void rz_type_db_set_bits ( RzTypeDB typedb,
int  bits 
)

Set the RzType target architecture bits.

Important for calculating some types size, especially pointers's size.

Parameters
typedbRzTypeDB instance
bitsArchitecture bits to set

Definition at line 145 of file type.c.

145  {
146  typedb->target->bits = bits;
147  // Also set the new default type
148  set_default_type(typedb->target, bits);
149 }
static void set_default_type(RzTypeTarget *target, int bits)
Definition: type.c:113

References rz_type_target_t::bits, bits(), set_default_type(), and rz_type_db_t::target.

Referenced by rz_analysis_set_bits().

◆ rz_type_db_set_cpu()

RZ_API void rz_type_db_set_cpu ( RzTypeDB typedb,
const char *  cpu 
)

Set the RzType target architecture CPU.

Important for calculating some types size, especially pointers's size.

Parameters
typedbRzTypeDB instance
cpuArchitecture name to set

Definition at line 189 of file type.c.

189  {
190  free(typedb->target->cpu);
191  typedb->target->cpu = cpu ? strdup(cpu) : NULL;
192 }
static ut32 cpu[32]
Definition: analysis_or1k.c:21

References cpu, rz_type_target_t::cpu, free(), NULL, strdup(), and rz_type_db_t::target.

Referenced by rz_analysis_set_cpu().

◆ rz_type_db_set_endian()

RZ_API void rz_type_db_set_endian ( RzTypeDB typedb,
bool  big_endian 
)

Set the RzType target architecture CPU.

Important for calculating complex types layout.

Parameters
typedbRzTypeDB instance
big_endianTrue if the big endian, false if the opposite

Definition at line 202 of file type.c.

202  {
203  typedb->target->big_endian = big_endian;
204 }
bool big_endian
Definition: rz_type.h:25

References rz_type_target_t::big_endian, and rz_type_db_t::target.

Referenced by cb_bigendian(), and rz_analysis_set_big_endian().

◆ rz_type_db_set_os()

RZ_API void rz_type_db_set_os ( RzTypeDB typedb,
const char *  os 
)

Set the RzType target architecture operating system.

Important for calculating some types size, especially pointers's size.

Parameters
typedbRzTypeDB instance
osOperating system name to set

Definition at line 175 of file type.c.

175  {
176  free(typedb->target->os);
177  typedb->target->os = os ? strdup(os) : NULL;
178 }

References free(), NULL, rz_type_target_t::os, strdup(), and rz_type_db_t::target.

Referenced by analysis_set_os().

◆ rz_type_db_struct_bitsize()

RZ_API ut64 rz_type_db_struct_bitsize ( const RzTypeDB typedb,
RZ_NONNULL RzBaseType btype 
)

Returns the struct type size in bits (target dependent)

Parameters
typedbTypes Database instance
btypeThe base type

Definition at line 707 of file type.c.

707  {
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 }
voidpf void uLong size
Definition: ioapi.h:138
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References RZ_BASE_TYPE_KIND_STRUCT, rz_return_val_if_fail, rz_type_db_get_bitsize(), rz_vector_foreach, rz_type_struct_member_t::type, and ut64().

Referenced by rz_type_db_base_get_bitsize(), and rz_type_db_get_bitsize().

◆ rz_type_db_struct_names()

RZ_API RZ_OWN RzList* rz_type_db_struct_names ( RzTypeDB typedb)

Returns the list of all struct names.

Parameters
typedbTypes Database instance

Definition at line 405 of file type.c.

405  {
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 }
static RzSocket * s
Definition: rtr.c:28

References NULL, RZ_BASE_TYPE_KIND_STRUCT, rz_list_append(), rz_list_free(), rz_list_new(), rz_return_val_if_fail, rz_type_db_get_base_types_of_kind(), and s.

Referenced by autocmplt_cmd_arg_struct_type().

◆ rz_type_db_typedef_bitsize()

RZ_API ut64 rz_type_db_typedef_bitsize ( const RzTypeDB typedb,
RZ_NONNULL RzBaseType btype 
)

Returns the typedef type size in bits (target dependent)

Parameters
typedbTypes Database instance
btypeThe base type

Definition at line 740 of file type.c.

740  {
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 }

References RZ_BASE_TYPE_KIND_TYPEDEF, rz_return_val_if_fail, rz_type_db_get_bitsize(), and RZ_TYPE_KIND_IDENTIFIER.

Referenced by rz_type_db_base_get_bitsize(), and rz_type_db_get_bitsize().

◆ rz_type_db_typedef_names()

RZ_API RZ_OWN RzList* rz_type_db_typedef_names ( RzTypeDB typedb)

Returns the list of all typedef (type aliases) names.

Parameters
typedbTypes Database instance

Definition at line 423 of file type.c.

423  {
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 }

References rz_base_type_t::name, NULL, RZ_BASE_TYPE_KIND_TYPEDEF, rz_list_append(), rz_list_free(), rz_list_new(), rz_return_val_if_fail, and rz_type_db_get_base_types_of_kind().

Referenced by autocmplt_cmd_arg_alias_type().

◆ rz_type_db_union_bitsize()

RZ_API ut64 rz_type_db_union_bitsize ( const RzTypeDB typedb,
RZ_NONNULL RzBaseType btype 
)

Returns the union type size in bits (target dependent)

Parameters
typedbTypes Database instance
btypeThe base type

Definition at line 723 of file type.c.

723  {
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 }
#define RZ_MAX(x, y)

References RZ_BASE_TYPE_KIND_UNION, RZ_MAX, rz_return_val_if_fail, rz_type_db_get_bitsize(), rz_vector_foreach, rz_type_union_member_t::type, and ut64().

Referenced by rz_type_db_base_get_bitsize(), and rz_type_db_get_bitsize().

◆ rz_type_db_union_names()

RZ_API RZ_OWN RzList* rz_type_db_union_names ( RzTypeDB typedb)

Returns the list of all union names.

Parameters
typedbTypes Database instance

Definition at line 387 of file type.c.

387  {
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 }

References rz_base_type_t::name, NULL, RZ_BASE_TYPE_KIND_UNION, rz_list_append(), rz_list_free(), rz_list_new(), rz_return_val_if_fail, and rz_type_db_get_base_types_of_kind().

Referenced by autocmplt_cmd_arg_union_type().

◆ rz_type_declaration_as_string()

RZ_API RZ_OWN char* rz_type_declaration_as_string ( const RzTypeDB typedb,
RZ_NONNULL const RzType type 
)

Returns the type C declaration representation.

Parameters
typedbTypes Database instance
typeRzType type

Definition at line 829 of file type.c.

829  {
830  rz_return_val_if_fail(typedb && type, NULL);
831 
833 }

References NULL, rz_return_val_if_fail, rz_type_as_pretty_string(), RZ_TYPE_PRINT_NO_END_SEMICOLON, RZ_TYPE_PRINT_ZERO_VLA, and type.

◆ rz_type_exists()

RZ_API bool rz_type_exists ( RzTypeDB typedb,
RZ_NONNULL const char *  name 
)

Checks if the type exists in the Type database.

Parameters
typedbTypes Database instance
nameName of the type

Definition at line 462 of file type.c.

462  {
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 }

References NULL, rz_return_val_if_fail, and rz_type_db_get_base_type().

◆ rz_type_free()

RZ_API void rz_type_free ( RZ_NULLABLE RzType type)

Frees the RzType.

Doesn't free the underlying RzBaseType, only the RzType wrapper. Same goes for the RzCallable. Both are stored in the corresponding hashtables and should not be touched until deleted explicitly.

Parameters
typeRzType type

Definition at line 1273 of file type.c.

1273  {
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 }
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
Definition: type.c:1273

References free(), RZ_TYPE_KIND_ARRAY, RZ_TYPE_KIND_CALLABLE, RZ_TYPE_KIND_IDENTIFIER, RZ_TYPE_KIND_POINTER, and type.

Referenced by c_parser_get_primitive_type(), c_parser_get_typedef(), c_parser_new_enum_naked_type(), c_parser_new_enum_type(), c_parser_new_primitive_type(), c_parser_new_structure_naked_type(), c_parser_new_structure_type(), c_parser_new_typedef(), c_parser_new_typedef_naked_type(), c_parser_new_union_naked_type(), c_parser_new_union_type(), c_parser_new_unspecified_naked_type(), get_callable_type(), parse_sole_type_name(), parse_struct_member(), parse_type_mfunction(), parse_type_pointer(), parse_type_procedure(), parse_union_member(), rz_analysis_dwarf_integrate_functions(), rz_analysis_fcn_vars_add_types(), rz_analysis_function_blocks_switch_type_handler(), rz_analysis_function_set_type(), rz_analysis_function_set_var(), rz_analysis_function_vars_bp_handler(), rz_analysis_function_vars_regs_handler(), rz_analysis_function_vars_sp_handler(), rz_analysis_var_global_free(), rz_analysis_var_global_set_type(), rz_type_array_of_base_type(), rz_type_base_struct_member_free(), rz_type_base_type_free(), rz_type_base_union_member_free(), rz_type_callable_arg_free(), rz_type_callable_free(), rz_type_integral_set_sign(), rz_type_pointer_of_base_type(), type_match(), var_free(), and var_type_set_str().

◆ rz_type_get_base_type()

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.

Parameters
typedbType Database instance
typeRzType type pointer

Definition at line 1251 of file type.c.

1251  {
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 }
RZ_API RZ_BORROW const char * rz_type_identifier(RZ_NONNULL const RzType *type)
Returns the type C identifier.
Definition: type.c:1155

References NULL, rz_return_val_if_fail, rz_type_db_get_base_type(), rz_type_identifier(), and type.

Referenced by base_type_to_format_unfold().

◆ rz_type_identifier()

RZ_API RZ_BORROW const char* rz_type_identifier ( RZ_NONNULL const RzType type)

Returns the type C identifier.

In case of the compound types it returns the name of identifier For example, for "char **ptr" it will return "char", for "const int **arr[56][76]" it will return "int"

Parameters
typeRzType type

Definition at line 1155 of file type.c.

1155  {
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 }

References NULL, rz_return_val_if_fail, RZ_TYPE_KIND_ARRAY, RZ_TYPE_KIND_CALLABLE, RZ_TYPE_KIND_IDENTIFIER, RZ_TYPE_KIND_POINTER, and type.

Referenced by ds_show_flags(), get_base_type_typeclass(), get_type_typeclass(), parse_typedef_node(), rz_core_print_disasm(), rz_type_get_base_type(), rz_type_integral_set_sign(), type_to_format_pair(), and types_xrefs_all().

◆ rz_type_identifier_declaration_as_string()

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.

Parameters
typedbTypes Database instance
typeRzType type

Definition at line 841 of file type.c.

841  {
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 }
@ RZ_TYPE_PRINT_UNFOLD_ANON_ONLY_STRICT
Definition: rz_type.h:218

References NULL, rz_return_val_if_fail, rz_type_as_pretty_string(), RZ_TYPE_PRINT_NO_END_SEMICOLON, RZ_TYPE_PRINT_UNFOLD_ANON_ONLY_STRICT, RZ_TYPE_PRINT_ZERO_VLA, and type.

Referenced by callable_as_string().

◆ rz_type_kind()

RZ_API int rz_type_kind ( RzTypeDB typedb,
RZ_NONNULL const char *  name 
)

Returns the kind (RzBaseTypeKind) of the type.

Parameters
typedbTypes Database instance
nameName of the type

Definition at line 474 of file type.c.

474  {
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 }

References rz_base_type_t::kind, rz_return_val_if_fail, and rz_type_db_get_base_type().

◆ rz_types_equal()

RZ_API bool rz_types_equal ( RZ_NONNULL const RzType type1,
RZ_NONNULL const RzType type2 
)

Checks if two types are identical.

Parameters
type1RzType pointer
type2RzType pointer

Definition at line 1218 of file type.c.

1218  {
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 }
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

References rz_return_val_if_fail, RZ_TYPE_KIND_ARRAY, RZ_TYPE_KIND_CALLABLE, RZ_TYPE_KIND_IDENTIFIER, RZ_TYPE_KIND_POINTER, and rz_warn_if_reached.

Referenced by typecmp(), and types_xrefs().

◆ set_default_type()

static void set_default_type ( RzTypeTarget target,
int  bits 
)
static

Definition at line 113 of file type.c.

113  {
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 }

References bits(), rz_type_target_t::default_type, free(), rz_warn_if_reached, and strdup().

Referenced by rz_type_db_set_bits().

◆ type_as_pretty_string()

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 
)
static

Definition at line 948 of file type.c.

948  {
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 }
voidpf void * buf
Definition: ioapi.h:138
RZ_API size_t rz_str_nlen(const char *s, size_t n)
Definition: str.c:1949
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_TYPE_PRINT_SHOW_TYPEDEF
Definition: rz_type.h:223
@ RZ_TYPE_PRINT_UNFOLD_ANON_ONLY
Definition: rz_type.h:217
@ RZ_TYPE_PRINT_END_NEWLINE
Definition: rz_type.h:222
@ RZ_TYPE_PRINT_MULTILINE
Definition: rz_type.h:216
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82
RzStrBuf * arraybuf
Definition: type.c:850
RzStrBuf * pointerbuf
Definition: type.c:849
RzStrBuf * typename
Definition: type.c:848
RzBaseTypeStruct struct_data
Definition: rz_type.h:118
RzType * type
Definition: rz_type.h:113
RzBaseTypeUnion union_data
Definition: rz_type.h:120
RzVector members
Definition: rz_type.h:104
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
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

References PrettyHelperBufs::arraybuf, rz_base_type_enum_t::cases, rz_base_type_t::enum_data, free(), i, rz_base_type_t::kind, rz_base_type_struct_t::members, rz_base_type_union_t::members, rz_type_enum_case_t::name, rz_type_struct_member_t::name, rz_type_union_member_t::name, rz_base_type_t::name, NULL, PFMT64x, PrettyHelperBufs::pointerbuf, RZ_BASE_TYPE_KIND_ATOMIC, RZ_BASE_TYPE_KIND_ENUM, RZ_BASE_TYPE_KIND_STRUCT, RZ_BASE_TYPE_KIND_TYPEDEF, RZ_BASE_TYPE_KIND_UNION, rz_return_val_if_fail, rz_str_nlen(), rz_strbuf_append(), rz_strbuf_appendf(), rz_strbuf_drain(), rz_strbuf_free(), rz_strbuf_length(), rz_strbuf_new(), rz_strbuf_slice(), rz_type_db_get_base_type(), rz_type_is_callable_ptr_nested(), RZ_TYPE_KIND_CALLABLE, RZ_TYPE_KIND_IDENTIFIER, RZ_TYPE_KIND_POINTER, RZ_TYPE_PRINT_ANONYMOUS, RZ_TYPE_PRINT_END_NEWLINE, RZ_TYPE_PRINT_MULTILINE, RZ_TYPE_PRINT_NO_END_SEMICOLON, RZ_TYPE_PRINT_SHOW_TYPEDEF, RZ_TYPE_PRINT_UNFOLD_ANON_ONLY, RZ_TYPE_PRINT_UNFOLD_ANON_ONLY_STRICT, RZ_TYPE_PRINT_ZERO_VLA, rz_vector_foreach, rz_vector_len(), rz_warn_if_reached, rz_base_type_t::struct_data, type, rz_type_struct_member_t::type, rz_type_union_member_t::type, rz_base_type_t::type, type_decl_as_pretty_string(), PrettyHelperBufs::typename, rz_base_type_t::union_data, and rz_type_enum_case_t::val.

Referenced by rz_type_as_pretty_string().

◆ type_decl_as_pretty_string()

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 
)
static

Definition at line 853 of file type.c.

853  {
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 }
#define PFMT64d
Definition: rz_types.h:394
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 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 RZ_OWN char * rz_type_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the type C representation.
Definition: type.c:817

References PrettyHelperBufs::arraybuf, free(), rz_base_type_t::kind, rz_base_type_t::name, NULL, PFMT64d, PrettyHelperBufs::pointerbuf, RZ_BASE_TYPE_KIND_ATOMIC, RZ_BASE_TYPE_KIND_ENUM, RZ_BASE_TYPE_KIND_STRUCT, RZ_BASE_TYPE_KIND_TYPEDEF, RZ_BASE_TYPE_KIND_UNION, RZ_LOG_ERROR, rz_return_val_if_fail, rz_strbuf_append(), rz_strbuf_appendf(), rz_type_as_string(), rz_type_callable_as_string(), rz_type_callable_ptr_as_string(), rz_type_db_get_base_type(), rz_type_is_callable_ptr_nested(), RZ_TYPE_KIND_ARRAY, RZ_TYPE_KIND_CALLABLE, RZ_TYPE_KIND_IDENTIFIER, RZ_TYPE_KIND_POINTER, rz_warn_if_reached, strdup(), type, rz_base_type_t::type, and PrettyHelperBufs::typename.

Referenced by type_as_pretty_string().

◆ types_ht_free()

static void types_ht_free ( HtPPKv *  kv)
static

Definition at line 12 of file type.c.

12  {
13  free(kv->key);
14  rz_type_base_type_free(kv->value);
15 }

References free(), and rz_type_base_type_free().

Referenced by rz_type_db_new(), and rz_type_db_purge().