Rizin
unix-like reverse engineering framework and cli tools
type_pdb.c File Reference
#include <rz_bin.h>
#include <rz_core.h>
#include <rz_type.h>
#include <rz_pdb.h>
#include <rz_analysis.h>
#include "../bin/pdb/pdb.h"

Go to the source code of this file.

Functions

static RzTypeparse_type (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type, char *name)
 
static RzTypeparse_regular_type (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type, char *name)
 
static RzTypeparse_type_modifier (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
 
static RzTypeparse_type_pointer (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type, char *name)
 
static RzTypeparse_type_procedure (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type, char *name)
 
static RzTypeparse_type_array (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
 
static void parse_type_arglist (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *arglist, RzPVector *vec)
 
static RzTypeparse_type_mfunction (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info, char *name)
 
static RzTypeparse_type_onemethod (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info)
 
static RzTypeparse_type_member (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info, char *name)
 
static RzTypeparse_type_nest (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info)
 
static RzTypeparse_union (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
 Parses union into BaseType and saves it into hashtable. More...
 
static RzTypeUnionMemberparse_union_member (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info)
 Parses union member. More...
 
static RzTypeparse_structure (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
 Parses structures into BaseType and saves them into hashtable. More...
 
static RzTypeStructMemberparse_struct_member (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info)
 Parses struct member. More...
 
static RzTypeparse_enum (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
 Parses enum into BaseType and saves it into SDB. More...
 
static RzTypeEnumCaseparse_enumerate (RzPdbTpiType *type)
 Parse enum case. More...
 
static bool is_parsable_type (const TpiLeafType type)
 
static char * create_type_name_from_offset (ut64 offset)
 Create a type name from offset. More...
 
static RzTypeparse_type_static_member (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info, char *name)
 
static bool is_tpitype_unnamed (const char *name)
 
static RzBaseTypeget_tpitype_basetype (const RzTypeDB *typedb, RzPdbTpiType *type, const char *name)
 
static RzTypecreate_rztype (RzPdbTpiType *type, RzTypeIdentifierKind kind, const char *name)
 
static void parse_types (const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
 Delegate the type parsing to appropriate function. More...
 
RZ_API void rz_parse_pdb_types (const RzTypeDB *typedb, const RzPdb *pdb)
 Saves PDB types from TPI stream into the type database. More...
 

Function Documentation

◆ create_rztype()

static RzType* create_rztype ( RzPdbTpiType type,
RzTypeIdentifierKind  kind,
const char *  name 
)
static

Definition at line 426 of file type_pdb.c.

426  {
427  RzType *t = RZ_NEW0(RzType);
428  if (!t) {
429  return NULL;
430  }
432  t->identifier.kind = kind;
434  return t;
435 }
#define NULL
Definition: cris-opc.c:27
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 type
Definition: mipsasm.c:17
@ RZ_TYPE_KIND_IDENTIFIER
Definition: rz_type.h:128
#define RZ_NEW0(x)
Definition: rz_types.h:284
Definition: z80asm.h:102
RzTypeKind kind
Definition: rz_type.h:155
struct rz_type_t::@292::@294 identifier
static char * create_type_name_from_offset(ut64 offset)
Create a type name from offset.
Definition: type_pdb.c:46
static bool is_tpitype_unnamed(const char *name)
Definition: type_pdb.c:410

References create_type_name_from_offset(), rz_type_t::identifier, is_tpitype_unnamed(), rz_type_t::kind, NULL, RZ_NEW0, RZ_TYPE_KIND_IDENTIFIER, strdup(), and type.

Referenced by parse_structure(), and parse_union().

◆ create_type_name_from_offset()

static char* create_type_name_from_offset ( ut64  offset)
static

Create a type name from offset.

Parameters
offset
Returns
char* Name or NULL if error

Definition at line 46 of file type_pdb.c.

46  {
47  int offset_length = snprintf(NULL, 0, "type_0x%" PFMT64x, offset);
48  char *str = malloc(offset_length + 1);
49  snprintf(str, offset_length + 1, "type_0x%" PFMT64x, offset);
50  return str;
51 }
voidpf uLong offset
Definition: ioapi.h:144
snprintf
Definition: kernel.h:364
void * malloc(size_t size)
Definition: malloc.c:123
#define PFMT64x
Definition: rz_types.h:393

References malloc(), NULL, PFMT64x, snprintf, and cmd_descs_generate::str.

Referenced by create_rztype(), get_tpitype_basetype(), parse_enum(), parse_type_nest(), and parse_type_procedure().

◆ get_tpitype_basetype()

static RzBaseType* get_tpitype_basetype ( const RzTypeDB typedb,
RzPdbTpiType type,
const char *  name 
)
inlinestatic

Definition at line 414 of file type_pdb.c.

414  {
415  RzBaseType *base_type;
416  if (is_tpitype_unnamed(name)) {
417  char *tmp_name = create_type_name_from_offset(type->type_index);
418  base_type = rz_type_db_get_base_type(typedb, tmp_name);
419  free(tmp_name);
420  } else {
421  base_type = rz_type_db_get_base_type(typedb, name);
422  }
423  return base_type;
424 }
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 void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References create_type_name_from_offset(), free(), is_tpitype_unnamed(), rz_type_db_get_base_type(), and type.

Referenced by parse_enum(), parse_structure(), and parse_union().

◆ is_parsable_type()

static bool is_parsable_type ( const TpiLeafType  type)
static

Definition at line 30 of file type_pdb.c.

30  {
32  return (type == LF_STRUCTURE ||
33  type == LF_UNION ||
34  type == LF_ENUM ||
35  type == LF_CLASS ||
36  type == LF_CLASS_19 ||
38 }
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
@ LF_STRUCTURE_19
Definition: tpi.h:200
@ LF_CLASS
Definition: tpi.h:174
@ LF_UNION
Definition: tpi.h:176
@ LF_STRUCTURE
Definition: tpi.h:175
@ LF_CLASS_19
Definition: tpi.h:199
@ LF_ENUM
Definition: tpi.h:177

References LF_CLASS, LF_CLASS_19, LF_ENUM, LF_STRUCTURE, LF_STRUCTURE_19, LF_UNION, rz_return_val_if_fail, and type.

Referenced by rz_parse_pdb_types().

◆ is_tpitype_unnamed()

static bool is_tpitype_unnamed ( const char *  name)
inlinestatic

Definition at line 410 of file type_pdb.c.

410  {
411  return !name || !strcmp(name, "<unnamed-tag>") || !strcmp(name, "<anonymous-tag>");
412 }

Referenced by create_rztype(), get_tpitype_basetype(), and parse_enum().

◆ parse_enum()

static RzType * parse_enum ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type 
)
static

Parses enum into BaseType and saves it into SDB.

Parameters
tRzTypeDB instance
streamTPI Stream
typeCurrent type

Definition at line 683 of file type_pdb.c.

683  {
684  rz_return_val_if_fail(typedb && type, NULL);
685  Tpi_LF_Enum *lf_enum = type->type_data;
686  // assert all member functions we need info from
687  RzBaseType *base_type = NULL;
689  if (name) {
690  base_type = get_tpitype_basetype(typedb, type, name);
691  if (base_type) {
692  if (base_type->kind != RZ_BASE_TYPE_KIND_ENUM) {
693  RZ_LOG_WARN("PDB: Type of %s (enum) conflicts with already defined type (%s), redefining it.\n",
695  rz_type_db_delete_base_type((RzTypeDB *)typedb, base_type);
696  base_type = NULL;
697  } else if (type->parsed || rz_bin_pdb_type_is_fwdref(type)) {
698  return base_type->type ? rz_type_clone(base_type->type) : NULL;
699  } else if (base_type->attrs != RZ_TYPE_TYPECLASS_INVALID) {
700  RZ_LOG_INFO("%s : Redefining type %s.\n", __FUNCTION__, name);
701  }
702  }
703  }
704 
705  if (!base_type) {
707  if (!base_type) {
708  return NULL;
709  }
710 
712  if (!utype) {
713  rz_type_base_type_free(base_type);
714  return NULL;
715  }
716  RzType *btype = parse_type(typedb, stream, utype, NULL);
717  if (!btype) {
718  rz_type_base_type_free(base_type);
719  return NULL;
720  }
721  base_type->name = is_tpitype_unnamed(name) ? create_type_name_from_offset(type->type_index) : strdup(name);
722  base_type->size = rz_type_db_get_bitsize(typedb, btype);
723  base_type->type = btype;
724  base_type->attrs = RZ_TYPE_TYPECLASS_INVALID;
725  rz_type_db_save_base_type(typedb, base_type);
726 
728  return rz_type_clone(base_type->type);
729  }
730  }
731  rz_vector_clear(&base_type->enum_data.cases);
733  RzListIter *it;
734  RzPdbTpiType *member_info;
735  rz_list_foreach (members, it, member_info) {
736  if (member_info->leaf_type == LF_INDEX) {
739  it = rz_list_head(members);
740  if (!it) {
741  break;
742  }
743  member_info = rz_list_first(members);
744  }
745  RzTypeEnumCase *enum_case = parse_enumerate(member_info);
746  if (!enum_case) {
747  continue; // skip it, move forward
748  }
749  void *element = rz_vector_push(&base_type->enum_data.cases, enum_case);
750  if (!element) {
751  rz_type_base_enum_case_free(enum_case, NULL);
752  return NULL;
753  }
754  free(enum_case);
755  }
756  if (base_type->attrs == RZ_TYPE_TYPECLASS_INVALID) {
757  base_type->attrs = RZ_TYPE_TYPECLASS_NONE;
758  rz_list_append(stream->print_type, base_type);
759  }
760  type->parsed = true;
761  return base_type->type ? rz_type_clone(base_type->type) : NULL;
762 }
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 void rz_type_base_enum_case_free(void *e, void *user)
Definition: base.c:8
RZ_API RZ_OWN RzBaseType * rz_type_base_type_new(RzBaseTypeKind kind)
Allocates a new instance of RzBaseType given the kind.
Definition: base.c:162
RZ_API void rz_type_db_save_base_type(const RzTypeDB *typedb, const RzBaseType *type)
Saves RzBaseType into the Types DB.
Definition: base.c:191
RZ_API RZ_BORROW const char * rz_type_base_type_kind_as_string(RzBaseTypeKind kind)
Returns string representing the kind of base type.
Definition: base.c:33
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
voidpf stream
Definition: ioapi.h:138
RZ_API RZ_BORROW void * rz_list_first(RZ_NONNULL const RzList *list)
Returns the first element of the list.
Definition: list.c:77
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
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
@ RZ_BASE_TYPE_KIND_ENUM
Definition: rz_type.h:75
@ RZ_TYPE_TYPECLASS_NONE
Definition: rz_type.h:62
@ RZ_TYPE_TYPECLASS_INVALID
Definition: rz_type.h:69
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
RZ_API void rz_vector_clear(RzVector *vec)
Definition: vector.c:68
ut32 utype
Definition: tpi.h:493
RzVector cases
Definition: rz_type.h:108
char * name
Definition: rz_type.h:112
RzType * type
Definition: rz_type.h:113
RzBaseTypeEnum enum_data
Definition: rz_type.h:119
RzBaseTypeKind kind
Definition: rz_type.h:115
RzTypeAttribute attrs
Definition: rz_type.h:116
ut16 leaf_type
Definition: rz_pdb.h:147
RZ_API ut64 rz_bin_pdb_get_type_val(RZ_NONNULL RzPdbTpiType *type)
Get the numeric value inside the type.
Definition: tpi.c:507
RZ_API RZ_BORROW RzList * rz_bin_pdb_get_type_members(RZ_NONNULL RzPdbTpiStream *stream, RzPdbTpiType *t)
Get the RzPdbTpiType member list.
Definition: tpi.c:406
RZ_API RZ_BORROW RzPdbTpiType * rz_bin_pdb_get_type_by_index(RZ_NONNULL RzPdbTpiStream *stream, ut32 index)
Get RzPdbTpiType that matches tpi stream index.
Definition: tpi.c:1844
RZ_API RZ_BORROW char * rz_bin_pdb_get_type_name(RZ_NONNULL RzPdbTpiType *type)
Get the name of the type.
Definition: tpi.c:447
RZ_API bool rz_bin_pdb_type_is_fwdref(RZ_NONNULL RzPdbTpiType *t)
Return true if type is forward definition.
Definition: tpi.c:372
@ LF_INDEX
Definition: tpi.h:158
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 RZ_OWN RzType * rz_type_clone(RZ_BORROW RZ_NONNULL const RzType *type)
Creates an exact clone of the RzType.
Definition: type.c:1181
static RzBaseType * get_tpitype_basetype(const RzTypeDB *typedb, RzPdbTpiType *type, const char *name)
Definition: type_pdb.c:414
static RzTypeEnumCase * parse_enumerate(RzPdbTpiType *type)
Parse enum case.
Definition: type_pdb.c:657
static RzType * parse_type(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type, char *name)
Definition: type_pdb.c:153

References rz_base_type_t::attrs, rz_base_type_enum_t::cases, create_type_name_from_offset(), rz_base_type_t::enum_data, free(), get_tpitype_basetype(), is_tpitype_unnamed(), rz_base_type_t::kind, tpi_types::leaf_type, LF_INDEX, rz_base_type_t::name, NULL, parse_enumerate(), parse_type(), RZ_BASE_TYPE_KIND_ENUM, rz_bin_pdb_get_type_by_index(), rz_bin_pdb_get_type_members(), rz_bin_pdb_get_type_name(), rz_bin_pdb_get_type_val(), rz_bin_pdb_type_is_fwdref(), rz_list_append(), rz_list_first(), RZ_LOG_INFO, RZ_LOG_WARN, rz_return_val_if_fail, rz_type_base_enum_case_free(), rz_type_base_type_free(), rz_type_base_type_kind_as_string(), rz_type_base_type_new(), rz_type_clone(), rz_type_db_delete_base_type(), rz_type_db_get_bitsize(), rz_type_db_save_base_type(), RZ_TYPE_TYPECLASS_INVALID, RZ_TYPE_TYPECLASS_NONE, rz_vector_clear(), rz_vector_push(), rz_base_type_t::size, strdup(), type, rz_base_type_t::type, and Tpi_LF_Enum::utype.

Referenced by parse_regular_type(), and parse_types().

◆ parse_enumerate()

static RzTypeEnumCase * parse_enumerate ( RzPdbTpiType type)
static

Parse enum case.

Parameters
type_infoCurrent type info (enum case)
Returns
RzTypeEnumCase* parsed enum case, NULL if fail

Definition at line 657 of file type_pdb.c.

657  {
658  rz_return_val_if_fail(type && type->leaf_type == LF_ENUMERATE, NULL);
659 
660  char *name = NULL;
661  ut64 value = 0;
662  // sometimes, the type doesn't have get_val for some reason
666  if (!cas) {
667  goto cleanup;
668  }
669  cas->name = strdup(name);
670  cas->val = value;
671  return cas;
672 cleanup:
673  return NULL;
674 }
static int value
Definition: cmd_api.c:93
void cleanup(void)
Definition: enough.c:244
@ LF_ENUMERATE
Definition: tpi.h:172
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References cleanup(), LF_ENUMERATE, rz_type_enum_case_t::name, NULL, rz_bin_pdb_get_type_name(), rz_bin_pdb_get_type_val(), RZ_NEW0, rz_return_val_if_fail, strdup(), type, ut64(), rz_type_enum_case_t::val, and value.

Referenced by parse_enum().

◆ parse_regular_type()

static RzType * parse_regular_type ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type,
char *  name 
)
static

Definition at line 74 of file type_pdb.c.

74  {
75  rz_return_val_if_fail(type && stream && typedb, NULL);
76  switch (type->leaf_type) {
77  case LF_CLASS:
78  case LF_CLASS_19:
79  // TODO: https://github.com/rizinorg/rizin/issues/1205
80  RZ_LOG_INFO("%s : LF_CLASS is not handled for now.\n", __FUNCTION__);
81  break;
82  case LF_STRUCTURE:
83  case LF_STRUCTURE_19:
84  return parse_structure(typedb, stream, type);
85  case LF_MODIFIER:
86  return parse_type_modifier(typedb, stream, type);
87  case LF_ARRAY:
88  return parse_type_array(typedb, stream, type);
89  case LF_BITFIELD:
90  // TODO: we don't have BITFIELD type for now https://github.com/rizinorg/rizin/issues/1240
91  RZ_LOG_INFO("%s : LF_BITFIELD is not handled for now.\n", __FUNCTION__);
92  break;
93  case LF_POINTER:
94  return parse_type_pointer(typedb, stream, type, name);
95  case LF_PROCEDURE:
96  return parse_type_procedure(typedb, stream, type, name);
97  case LF_UNION:
98  return parse_union(typedb, stream, type);
99  case LF_ENUM:
100  return parse_enum(typedb, stream, type);
101  default:
102  RZ_LOG_INFO("%s : unsupported leaf type 0x%x\n", __FUNCTION__, type->leaf_type);
103  break;
104  }
105  return NULL;
106 }
@ LF_PROCEDURE
Definition: tpi.h:133
@ LF_POINTER
Definition: tpi.h:127
@ LF_MODIFIER
Definition: tpi.h:126
@ LF_ARRAY
Definition: tpi.h:173
@ LF_BITFIELD
Definition: tpi.h:148
static RzType * parse_structure(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
Parses structures into BaseType and saves them into hashtable.
Definition: type_pdb.c:444
static RzType * parse_type_procedure(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type, char *name)
Definition: type_pdb.c:197
static RzType * parse_type_modifier(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
Definition: type_pdb.c:108
static RzType * parse_type_pointer(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type, char *name)
Definition: type_pdb.c:131
static RzType * parse_union(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
Parses union into BaseType and saves it into hashtable.
Definition: type_pdb.c:577
static RzType * parse_enum(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
Parses enum into BaseType and saves it into SDB.
Definition: type_pdb.c:683
static RzType * parse_type_array(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
Definition: type_pdb.c:53

References LF_ARRAY, LF_BITFIELD, LF_CLASS, LF_CLASS_19, LF_ENUM, LF_MODIFIER, LF_POINTER, LF_PROCEDURE, LF_STRUCTURE, LF_STRUCTURE_19, LF_UNION, NULL, parse_enum(), parse_structure(), parse_type_array(), parse_type_modifier(), parse_type_pointer(), parse_type_procedure(), parse_union(), RZ_LOG_INFO, rz_return_val_if_fail, and type.

Referenced by parse_type().

◆ parse_struct_member()

static RzTypeStructMember * parse_struct_member ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type_info 
)
static

Parses struct member.

Parameters
typedbTypes DB instance
streamTPI Stream
type_infoCurrent RzPdbTpiType (member)
Returns
RzTypeStructMember* parsed member, NULL if fail

Definition at line 352 of file type_pdb.c.

352  {
353  rz_return_val_if_fail(type_info, NULL);
354  char *name = NULL;
355  ut64 offset = 0;
356  RzType *type = NULL;
357  switch (type_info->leaf_type) {
358  case LF_ONEMETHOD: {
359  name = rz_bin_pdb_get_type_name(type_info);
360  type = parse_type_onemethod(typedb, stream, type_info);
361  break;
362  }
363  case LF_MEMBER: {
364  offset = rz_bin_pdb_get_type_val(type_info);
365  name = rz_bin_pdb_get_type_name(type_info);
366  type = parse_type_member(typedb, stream, type_info, name);
367  break;
368  }
369  case LF_STMEMBER: {
370  name = rz_bin_pdb_get_type_name(type_info);
371  type = parse_type_static_member(typedb, stream, type_info, name);
372  break;
373  }
374  case LF_NESTTYPE: {
375  name = rz_bin_pdb_get_type_name(type_info);
376  type = parse_type_nest(typedb, stream, type_info);
377  break;
378  }
379  case LF_BCLASS:
380  // For structure, we don't need base class for now
381  goto cleanup;
382  case LF_METHOD:
383  // TODO: need to handle overloaded methods here
384  goto cleanup;
385  case LF_VFUNCTAB:
386  // For structure, we don't need vtable for now
387  goto cleanup;
388  default:
389  RZ_LOG_ERROR("%s : unsupported leaf type 0x%x\n", __FUNCTION__, type_info->leaf_type);
390  goto cleanup;
391  }
392  if (!type) {
393  RZ_LOG_INFO("%s : couldn't parse structure member type!\n", __FUNCTION__);
394  return NULL;
395  }
396 
398  if (!member) {
399  goto cleanup;
400  }
401  member->name = strdup(name);
402  member->type = type;
403  member->offset = offset;
404  return member;
405 cleanup:
407  return NULL;
408 }
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
@ LF_NESTTYPE
Definition: tpi.h:186
@ LF_MEMBER
Definition: tpi.h:183
@ LF_METHOD
Definition: tpi.h:185
@ LF_ONEMETHOD
Definition: tpi.h:187
@ LF_BCLASS
Definition: tpi.h:154
@ LF_STMEMBER
Definition: tpi.h:184
@ LF_VFUNCTAB
Definition: tpi.h:163
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
Definition: type.c:1273
static RzType * parse_type_member(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info, char *name)
Definition: type_pdb.c:288
static RzType * parse_type_nest(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info)
Definition: type_pdb.c:309
static RzType * parse_type_static_member(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info, char *name)
Definition: type_pdb.c:299
static RzType * parse_type_onemethod(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info)
Definition: type_pdb.c:274

References cleanup(), tpi_types::leaf_type, LF_BCLASS, LF_MEMBER, LF_METHOD, LF_NESTTYPE, LF_ONEMETHOD, LF_STMEMBER, LF_VFUNCTAB, rz_type_struct_member_t::name, NULL, rz_type_struct_member_t::offset, parse_type_member(), parse_type_nest(), parse_type_onemethod(), parse_type_static_member(), rz_bin_pdb_get_type_name(), rz_bin_pdb_get_type_val(), RZ_LOG_ERROR, RZ_LOG_INFO, RZ_NEW0, rz_return_val_if_fail, rz_type_free(), strdup(), type, rz_type_struct_member_t::type, and ut64().

Referenced by parse_structure().

◆ parse_structure()

static RzType * parse_structure ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type 
)
static

Parses structures into BaseType and saves them into hashtable.

Parameters
tRzTypeDB instance
streamTPI Stream
typeCurrent type

Definition at line 444 of file type_pdb.c.

444  {
445  rz_return_val_if_fail(typedb && stream && type, NULL);
446 
447  RzBaseType *base_type = NULL;
449  if (name) {
450  base_type = get_tpitype_basetype(typedb, type, name);
451  if (base_type) {
452  if (base_type->kind != RZ_BASE_TYPE_KIND_STRUCT) {
453  RZ_LOG_WARN("PDB: Type of %s (struct) conflicts with already defined type (%s), redefining it.\n",
455  rz_type_db_delete_base_type((RzTypeDB *)typedb, base_type);
456  base_type = NULL;
457  } else if (type->parsed || rz_bin_pdb_type_is_fwdref(type)) {
458  return base_type->type ? rz_type_clone(base_type->type) : create_rztype(type, RZ_TYPE_IDENTIFIER_KIND_STRUCT, name);
459  } else if (base_type->attrs != RZ_TYPE_TYPECLASS_INVALID) {
460  RZ_LOG_INFO("%s : Redefining type %s.\n", __FUNCTION__, name);
461  }
462  }
463  }
464 
465  if (!base_type) {
467  if (!base_type) {
468  return NULL;
469  }
470 
472  if (!typ) {
473  rz_type_base_type_free(base_type);
474  return NULL;
475  }
476  base_type->type = typ;
477  base_type->name = strdup(typ->identifier.name);
478  base_type->attrs = RZ_TYPE_TYPECLASS_INVALID;
479  rz_type_db_save_base_type(typedb, base_type);
480 
482  return rz_type_clone(base_type->type);
483  }
484  }
485  rz_vector_clear(&base_type->struct_data.members);
487  RzListIter *it;
488  RzPdbTpiType *member_info;
489  rz_list_foreach (members, it, member_info) {
490  if (member_info->leaf_type == LF_INDEX) {
493  it = rz_list_head(members);
494  if (!it) {
495  break;
496  }
497  member_info = rz_list_first(members);
498  }
499  RzTypeStructMember *struct_member = parse_struct_member(typedb, stream, member_info);
500  if (!struct_member) {
501  continue; // skip the failure
502  }
503  void *element = rz_vector_push(&base_type->struct_data.members, struct_member);
504  if (!element) {
505  rz_type_base_struct_member_free(struct_member, NULL);
506  return NULL;
507  }
508  free(struct_member);
509  }
510  base_type->size = rz_bin_pdb_get_type_val(type);
511  if (base_type->attrs == RZ_TYPE_TYPECLASS_INVALID) {
512  base_type->attrs = RZ_TYPE_TYPECLASS_NONE;
513  rz_list_append(stream->print_type, base_type);
514  }
515  type->parsed = true;
516  return base_type->type ? rz_type_clone(base_type->type) : NULL;
517 }
RZ_API void rz_type_base_struct_member_free(void *e, void *user)
Definition: base.c:14
@ RZ_BASE_TYPE_KIND_STRUCT
Definition: rz_type.h:73
@ RZ_TYPE_IDENTIFIER_KIND_STRUCT
Definition: rz_type.h:136
RzBaseTypeStruct struct_data
Definition: rz_type.h:118
static RzType * create_rztype(RzPdbTpiType *type, RzTypeIdentifierKind kind, const char *name)
Definition: type_pdb.c:426
static RzTypeStructMember * parse_struct_member(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info)
Parses struct member.
Definition: type_pdb.c:352

References rz_base_type_t::attrs, create_rztype(), free(), get_tpitype_basetype(), rz_type_t::identifier, rz_base_type_t::kind, tpi_types::leaf_type, LF_INDEX, rz_base_type_struct_t::members, rz_base_type_t::name, NULL, parse_struct_member(), RZ_BASE_TYPE_KIND_STRUCT, rz_bin_pdb_get_type_by_index(), rz_bin_pdb_get_type_members(), rz_bin_pdb_get_type_name(), rz_bin_pdb_get_type_val(), rz_bin_pdb_type_is_fwdref(), rz_list_append(), rz_list_first(), RZ_LOG_INFO, RZ_LOG_WARN, rz_return_val_if_fail, rz_type_base_struct_member_free(), rz_type_base_type_free(), rz_type_base_type_kind_as_string(), rz_type_base_type_new(), rz_type_clone(), rz_type_db_delete_base_type(), rz_type_db_save_base_type(), RZ_TYPE_IDENTIFIER_KIND_STRUCT, RZ_TYPE_TYPECLASS_INVALID, RZ_TYPE_TYPECLASS_NONE, rz_vector_clear(), rz_vector_push(), rz_base_type_t::size, strdup(), rz_base_type_t::struct_data, type, and rz_base_type_t::type.

Referenced by parse_regular_type(), and parse_types().

◆ parse_type()

static RzType * parse_type ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type,
char *  name 
)
static

Definition at line 153 of file type_pdb.c.

153  {
154  rz_return_val_if_fail(type && typedb, NULL);
155  RzType *typ;
156  if (type->leaf_type == LF_SIMPLE_TYPE) {
157  Tpi_LF_SimpleType *simple_type = type->type_data;
158  char *error_msg = NULL;
159  typ = rz_type_parse_string_single(typedb->parser, simple_type->type, &error_msg);
160  if (error_msg) {
161  RZ_LOG_ERROR("%s : Error parsing complex type member \"%s\" type:\n%s\n", __FUNCTION__, simple_type->type, error_msg);
162  RZ_FREE(error_msg);
163  }
164  return typ;
165  } else {
166  if (type->leaf_type == LF_POINTER) {
167  return parse_type_pointer(typedb, stream, type, name);
168  } else {
169  return parse_regular_type(typedb, stream, type, name);
170  }
171  }
172 }
RZ_API RZ_OWN RzType * rz_type_parse_string_single(RzTypeParser *parser, const char *code, char **error_msg)
Parses the single C type definition.
Definition: c_cpp_parser.c:309
#define RZ_FREE(x)
Definition: rz_types.h:369
char * type
Definition: tpi.h:586
RzTypeParser * parser
Definition: rz_type.h:37
@ LF_SIMPLE_TYPE
Definition: tpi.h:246
static RzType * parse_regular_type(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type, char *name)
Definition: type_pdb.c:74

References LF_POINTER, LF_SIMPLE_TYPE, NULL, parse_regular_type(), parse_type_pointer(), rz_type_db_t::parser, RZ_FREE, RZ_LOG_ERROR, rz_return_val_if_fail, rz_type_parse_string_single(), type, and Tpi_LF_SimpleType::type.

Referenced by parse_enum(), parse_type_arglist(), parse_type_array(), parse_type_member(), parse_type_mfunction(), parse_type_modifier(), parse_type_nest(), parse_type_pointer(), parse_type_procedure(), and parse_type_static_member().

◆ parse_type_arglist()

static void parse_type_arglist ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType arglist,
RzPVector vec 
)
static

Definition at line 174 of file type_pdb.c.

174  {
175  rz_return_if_fail(arglist && typedb && vec);
176  Tpi_LF_Arglist *lf_arglist = arglist->type_data;
177  if (!vec) {
178  return;
179  }
180  ut32 *ptr_types = lf_arglist->arg_type;
181  for (int i = 0; i < lf_arglist->count; i++) {
182  RzPdbTpiType *stype = rz_bin_pdb_get_type_by_index(stream, *ptr_types++);
183  if (!stype) {
184  continue;
185  }
186  RzType *type = parse_type(typedb, stream, stype, NULL);
187  if (!type) {
188  continue;
189  }
191  arg->name = rz_str_newf("arg%d", i);
192  arg->type = type;
193  rz_pvector_push(vec, arg);
194  }
195 }
lzma_index ** i
Definition: index.h:629
uint32_t ut32
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
ut32 * arg_type
Definition: tpi.h:332
ut32 count
Definition: tpi.h:331
const char * name
Definition: sparc-opc.c:1838
void * type_data
Definition: rz_pdb.h:149

References Tpi_LF_Arglist::arg_type, Tpi_LF_Arglist::count, i, arg::name, NULL, parse_type(), rz_bin_pdb_get_type_by_index(), RZ_NEW0, rz_pvector_push(), rz_return_if_fail, rz_str_newf(), type, and tpi_types::type_data.

Referenced by parse_type_mfunction(), and parse_type_procedure().

◆ parse_type_array()

static RzType * parse_type_array ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type 
)
static

Definition at line 53 of file type_pdb.c.

53  {
54  rz_return_val_if_fail(type && stream && typedb, NULL);
55  Tpi_LF_Array *lf_array = type->type_data;
57  if (!element) {
58  return NULL;
59  }
60  RzType *element_type = parse_type(typedb, stream, element, NULL);
61  if (!element_type) {
62  return NULL;
63  }
64  RzType *typ = RZ_NEW0(RzType);
65  if (!typ) {
66  return NULL;
67  }
68  typ->kind = RZ_TYPE_KIND_ARRAY;
69  typ->array.type = element_type;
70  typ->array.count = rz_bin_pdb_get_type_val(type);
71  return typ;
72 }
@ RZ_TYPE_KIND_ARRAY
Definition: rz_type.h:130
ut32 element_type
Definition: tpi.h:435
struct rz_type_t::@292::@296 array

References rz_type_t::array, Tpi_LF_Array::element_type, rz_type_t::kind, NULL, parse_type(), rz_bin_pdb_get_type_by_index(), rz_bin_pdb_get_type_val(), RZ_NEW0, rz_return_val_if_fail, RZ_TYPE_KIND_ARRAY, and type.

Referenced by parse_regular_type().

◆ parse_type_member()

static RzType * parse_type_member ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type_info,
char *  name 
)
static

Definition at line 288 of file type_pdb.c.

288  {
289  rz_return_val_if_fail(type_info && typedb, NULL);
290  Tpi_LF_Member *lf_member = type_info->type_data;
291 
293  if (!utype) {
294  return NULL;
295  }
296  return parse_type(typedb, stream, utype, name);
297 }
ut32 index
Definition: tpi.h:538

References Tpi_LF_Member::index, NULL, parse_type(), rz_bin_pdb_get_type_by_index(), rz_return_val_if_fail, and tpi_types::type_data.

Referenced by parse_struct_member(), and parse_union_member().

◆ parse_type_mfunction()

static RzType * parse_type_mfunction ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type_info,
char *  name 
)
static

Definition at line 238 of file type_pdb.c.

238  {
239  rz_return_val_if_fail(type_info && stream && typedb, NULL);
240  Tpi_LF_MFcuntion *lf_mfunction = type_info->type_data;
242  RzCallable *callable = RZ_NEW0(RzCallable);
243  if (!type || !callable) {
244  free(type);
245  free(callable);
246  return NULL;
247  }
248  type->kind = RZ_TYPE_KIND_CALLABLE;
249  type->callable = callable;
250  type->callable->name = strdup(name);
251  type->callable->cc = rz_bin_pdb_calling_convention_as_string(lf_mfunction->call_conv);
252  // parse return type
253  RzPdbTpiType *ret_type = rz_bin_pdb_get_type_by_index(stream, lf_mfunction->return_type);
254  if (ret_type) {
255  type->callable->ret = parse_type(typedb, stream, ret_type, name);
256  if (!type->callable->ret) {
257  type->callable->noret = true;
258  }
259  }
260  // parse parameter list
262  if (!type->callable->args) {
264  return NULL;
265  }
266  RzPdbTpiType *arglist = rz_bin_pdb_get_type_by_index(stream, lf_mfunction->arglist);
267  if (arglist) {
268  parse_type_arglist(typedb, stream, arglist, type->callable->args);
269  }
270  rz_type_func_save((RzTypeDB *)typedb, callable);
271  return type;
272 }
@ RZ_TYPE_KIND_CALLABLE
Definition: rz_type.h:131
RZ_API RzPVector * rz_pvector_new(RzPVectorFree free)
Definition: vector.c:302
void(* RzPVectorFree)(void *e)
Definition: rz_vector.h:43
ut32 return_type
Definition: tpi.h:319
RzPdbTpiCallingConvention call_conv
Definition: tpi.h:322
ut32 arglist
Definition: tpi.h:325
RZ_API RZ_OWN char * rz_bin_pdb_calling_convention_as_string(RZ_NONNULL RzPdbTpiCallingConvention idx)
Parses calling convention type as string.
Definition: tpi.c:35
RZ_API bool rz_type_func_save(RzTypeDB *typedb, RZ_NONNULL RzCallable *callable)
Stores RzCallable type in the types database.
Definition: function.c:147
RZ_API void rz_type_callable_arg_free(RzCallableArg *arg)
Frees the RzCallableArg.
Definition: function.c:101
static void parse_type_arglist(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *arglist, RzPVector *vec)
Definition: type_pdb.c:174

References Tpi_LF_MFcuntion::arglist, Tpi_LF_MFcuntion::call_conv, free(), NULL, parse_type(), parse_type_arglist(), Tpi_LF_MFcuntion::return_type, rz_bin_pdb_calling_convention_as_string(), rz_bin_pdb_get_type_by_index(), RZ_NEW0, rz_pvector_new(), rz_return_val_if_fail, rz_type_callable_arg_free(), rz_type_free(), rz_type_func_save(), RZ_TYPE_KIND_CALLABLE, strdup(), type, and tpi_types::type_data.

Referenced by parse_type_onemethod().

◆ parse_type_modifier()

static RzType * parse_type_modifier ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type 
)
static

Definition at line 108 of file type_pdb.c.

108  {
109  rz_return_val_if_fail(type && stream && typedb, NULL);
110  Tpi_LF_Modifier *lf_modifier = type->type_data;
112  if (m_utype) {
113  RzType *typ = parse_type(typedb, stream, m_utype, NULL);
114  if (typ && lf_modifier->umodifier.bits.const_) {
115  switch (typ->kind) {
117  typ->identifier.is_const = true;
118  break;
120  typ->pointer.is_const = true;
121  break;
122  default:
123  break;
124  }
125  }
126  return typ;
127  }
128  return NULL;
129 }
@ RZ_TYPE_KIND_POINTER
Definition: rz_type.h:129
ut32 modified_type
Definition: tpi.h:346
TpiCVModifier umodifier
Definition: tpi.h:347
struct rz_type_t::@292::@295 pointer
ut16 const_
Definition: tpi.h:338
struct TpiCVModifier::@210 bits

References TpiCVModifier::bits, TpiCVModifier::const_, rz_type_t::identifier, rz_type_t::kind, Tpi_LF_Modifier::modified_type, NULL, parse_type(), rz_type_t::pointer, rz_bin_pdb_get_type_by_index(), rz_return_val_if_fail, RZ_TYPE_KIND_IDENTIFIER, RZ_TYPE_KIND_POINTER, type, and Tpi_LF_Modifier::umodifier.

Referenced by parse_regular_type().

◆ parse_type_nest()

static RzType * parse_type_nest ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type_info 
)
static

Definition at line 309 of file type_pdb.c.

309  {
310  rz_return_val_if_fail(type_info && stream && typedb, NULL);
311  Tpi_LF_NestType *lf_nest = type_info->type_data;
313  if (!utype) {
314  return NULL;
315  }
316  char *name = rz_bin_pdb_get_type_name(utype);
317  if (name) {
318  RzBaseType *b_type = rz_type_db_get_base_type(typedb, name);
319  if (b_type && b_type->type) {
320  if (b_type->type->kind == RZ_TYPE_KIND_IDENTIFIER) {
321  return rz_type_clone(b_type->type);
322  }
323  }
324  return NULL;
325  }
326 
327  RzType *n_type = parse_type(typedb, stream, utype, NULL);
328  if (!n_type) {
329  return NULL;
330  }
332  if (!btype) {
333  return NULL;
334  }
335  btype->name = name ? strdup(name) : create_type_name_from_offset(lf_nest->index);
336  btype->type = n_type;
337  rz_type_db_save_base_type(typedb, btype);
338  if (n_type->kind == RZ_TYPE_KIND_IDENTIFIER) {
339  return rz_type_clone(n_type);
340  }
341  return NULL;
342 }
@ RZ_BASE_TYPE_KIND_TYPEDEF
Definition: rz_type.h:76
ut32 index
Definition: tpi.h:509

References create_type_name_from_offset(), Tpi_LF_NestType::index, rz_type_t::kind, rz_base_type_t::name, NULL, parse_type(), RZ_BASE_TYPE_KIND_TYPEDEF, rz_bin_pdb_get_type_by_index(), rz_bin_pdb_get_type_name(), rz_return_val_if_fail, rz_type_base_type_new(), rz_type_clone(), rz_type_db_get_base_type(), rz_type_db_save_base_type(), RZ_TYPE_KIND_IDENTIFIER, strdup(), rz_base_type_t::type, and tpi_types::type_data.

Referenced by parse_struct_member(), and parse_union_member().

◆ parse_type_onemethod()

static RzType * parse_type_onemethod ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type_info 
)
static

Definition at line 274 of file type_pdb.c.

274  {
275  rz_return_val_if_fail(type_info && typedb, NULL);
276  Tpi_LF_OneMethod *lf_onemethod = type_info->type_data;
277  char *name = rz_bin_pdb_get_type_name(type_info);
278  RzPdbTpiType *utype = rz_bin_pdb_get_type_by_index(stream, lf_onemethod->index);
279  if (!utype) {
280  return NULL;
281  }
282  if (utype->leaf_type == LF_MFUNCTION) {
283  return parse_type_mfunction(typedb, stream, utype, name);
284  }
285  return NULL;
286 }
ut32 index
Definition: tpi.h:559
@ LF_MFUNCTION
Definition: tpi.h:134
static RzType * parse_type_mfunction(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info, char *name)
Definition: type_pdb.c:238

References Tpi_LF_OneMethod::index, tpi_types::leaf_type, LF_MFUNCTION, NULL, parse_type_mfunction(), rz_bin_pdb_get_type_by_index(), rz_bin_pdb_get_type_name(), rz_return_val_if_fail, and tpi_types::type_data.

Referenced by parse_struct_member(), and parse_union_member().

◆ parse_type_pointer()

static RzType * parse_type_pointer ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type,
char *  name 
)
static

Definition at line 131 of file type_pdb.c.

131  {
132  rz_return_val_if_fail(type && typedb, NULL);
133  Tpi_LF_Pointer *lf_pointer = type->type_data;
134  RzType *typ = RZ_NEW0(RzType);
135  if (!typ) {
136  goto error;
137  }
138  typ->kind = RZ_TYPE_KIND_POINTER;
139  RzPdbTpiType *p_utype = rz_bin_pdb_get_type_by_index(stream, lf_pointer->utype);
140  if (p_utype) {
141  RzType *tmp = parse_type(typedb, stream, p_utype, name);
142  if (!tmp) {
143  goto error;
144  }
145  typ->pointer.type = tmp;
146  return typ;
147  }
148 error:
149  rz_type_free(typ);
150  return NULL;
151 }
ut32 utype
Definition: tpi.h:409
void error(const char *msg)
Definition: untgz.c:593

References error(), rz_type_t::kind, NULL, parse_type(), rz_type_t::pointer, rz_bin_pdb_get_type_by_index(), RZ_NEW0, rz_return_val_if_fail, rz_type_free(), RZ_TYPE_KIND_POINTER, autogen_x86imm::tmp, type, and Tpi_LF_Pointer::utype.

Referenced by parse_regular_type(), and parse_type().

◆ parse_type_procedure()

static RzType * parse_type_procedure ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type,
char *  name 
)
static

Definition at line 197 of file type_pdb.c.

197  {
198  rz_return_val_if_fail(type && stream && typedb, NULL);
199  Tpi_LF_Procedure *lf_procedure = type->type_data;
200  RzType *typ = RZ_NEW0(RzType);
201  RzCallable *callable = RZ_NEW0(RzCallable);
202  if (!typ || !callable) {
203  free(typ);
204  free(callable);
205  return NULL;
206  }
208  typ->callable = callable;
209  if (!name) {
210  typ->callable->name = create_type_name_from_offset(type->type_index);
211  } else {
212  typ->callable->name = strdup(name);
213  }
214 
216  // parse return type
217  RzPdbTpiType *ret_type = rz_bin_pdb_get_type_by_index(stream, lf_procedure->return_type);
218  if (ret_type) {
219  typ->callable->ret = parse_type(typedb, stream, ret_type, name);
220  if (!typ->callable->ret) {
221  typ->callable->noret = true;
222  }
223  }
224  // parse parameter list
226  if (!typ->callable->args) {
227  rz_type_free(typ);
228  return NULL;
229  }
230  RzPdbTpiType *arglist = rz_bin_pdb_get_type_by_index(stream, lf_procedure->arg_list);
231  if (arglist) {
232  parse_type_arglist(typedb, stream, arglist, typ->callable->args);
233  }
234  rz_type_func_save((RzTypeDB *)typedb, callable);
235  return typ;
236 }
ut32 arg_list
Definition: tpi.h:314
RzPdbTpiCallingConvention call_conv
Definition: tpi.h:311
ut32 return_type
Definition: tpi.h:310
RzPVector * args
optional for the time being
Definition: rz_type.h:149
RZ_NULLABLE const char * cc
Definition: rz_type.h:150
RZ_NULLABLE char * name
Definition: rz_type.h:147
RZ_NULLABLE RzType * ret
Definition: rz_type.h:148
RzCallable * callable
Definition: rz_type.h:170

References Tpi_LF_Procedure::arg_list, rz_callable_at::args, Tpi_LF_Procedure::call_conv, rz_type_t::callable, rz_callable_at::cc, create_type_name_from_offset(), free(), rz_type_t::kind, rz_callable_at::name, rz_callable_at::noret, NULL, parse_type(), parse_type_arglist(), rz_callable_at::ret, Tpi_LF_Procedure::return_type, rz_bin_pdb_calling_convention_as_string(), rz_bin_pdb_get_type_by_index(), RZ_NEW0, rz_pvector_new(), rz_return_val_if_fail, rz_type_callable_arg_free(), rz_type_free(), rz_type_func_save(), RZ_TYPE_KIND_CALLABLE, strdup(), and type.

Referenced by parse_regular_type().

◆ parse_type_static_member()

static RzType* parse_type_static_member ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type_info,
char *  name 
)
static

Definition at line 299 of file type_pdb.c.

299  {
300  rz_return_val_if_fail(type_info && typedb, NULL);
301  Tpi_LF_StaticMember *lf_stmember = type_info->type_data;
302  RzPdbTpiType *utype = rz_bin_pdb_get_type_by_index(stream, lf_stmember->index);
303  if (!utype) {
304  return NULL;
305  }
306  return parse_type(typedb, stream, utype, name);
307 }

References Tpi_LF_StaticMember::index, NULL, parse_type(), rz_bin_pdb_get_type_by_index(), rz_return_val_if_fail, and tpi_types::type_data.

Referenced by parse_struct_member().

◆ parse_types()

static void parse_types ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type 
)
static

Delegate the type parsing to appropriate function.

Parameters
tRzTypeDB instance
streamTPI Stream
typeCurrent type

Definition at line 771 of file type_pdb.c.

771  {
772  rz_return_if_fail(typedb && type);
773 
774  switch (type->leaf_type) {
775  case LF_CLASS:
776  case LF_CLASS_19:
777  break;
778  case LF_STRUCTURE:
779  case LF_STRUCTURE_19:
780  parse_structure(typedb, stream, type);
781  break;
782  case LF_UNION:
783  parse_union(typedb, stream, type);
784  break;
785  case LF_ENUM:
786  parse_enum(typedb, stream, type);
787  break;
788  default:
789  // shouldn't happen, happens when someone modifies leafs that get here
790  // but not how they should be parsed
791  RZ_LOG_ERROR("Unknown type record");
792  break;
793  }
794 }

References LF_CLASS, LF_CLASS_19, LF_ENUM, LF_STRUCTURE, LF_STRUCTURE_19, LF_UNION, parse_enum(), parse_structure(), parse_union(), RZ_LOG_ERROR, rz_return_if_fail, and type.

Referenced by rz_parse_pdb_types().

◆ parse_union()

static RzType * parse_union ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type 
)
static

Parses union into BaseType and saves it into hashtable.

Parameters
typedbTypes DB instance
streamTPI Stream
type_infoCurrent RzPdbTpiType (enum case)

Definition at line 577 of file type_pdb.c.

577  {
578  rz_return_val_if_fail(typedb && stream && type, NULL);
579 
580  RzBaseType *base_type = NULL;
582  if (name) {
583  base_type = get_tpitype_basetype(typedb, type, name);
584  if (base_type) {
585  if (base_type->kind != RZ_BASE_TYPE_KIND_UNION) {
586  RZ_LOG_WARN("PDB: Type of %s (union) conflicts with already defined type (%s), redefining it.\n",
588  rz_type_db_delete_base_type((RzTypeDB *)typedb, base_type);
589  base_type = NULL;
590  } else if (type->parsed || rz_bin_pdb_type_is_fwdref(type)) {
591  return base_type->type ? rz_type_clone(base_type->type) : create_rztype(type, RZ_TYPE_IDENTIFIER_KIND_UNION, name);
592  } else if (base_type->attrs != RZ_TYPE_TYPECLASS_INVALID) {
593  RZ_LOG_INFO("%s : Redefining type %s.\n", __FUNCTION__, name);
594  }
595  }
596  }
597 
598  if (!base_type) {
600  if (!base_type) {
601  return NULL;
602  }
603 
605  if (!typ) {
606  rz_type_base_type_free(base_type);
607  return NULL;
608  }
609  base_type->type = typ;
610  base_type->name = strdup(typ->identifier.name);
611  base_type->attrs = RZ_TYPE_TYPECLASS_INVALID;
612  rz_type_db_save_base_type(typedb, base_type);
613 
615  return rz_type_clone(base_type->type);
616  }
617  }
618  rz_vector_clear(&base_type->union_data.members);
620  RzListIter *it;
621  RzPdbTpiType *member_info;
622  rz_list_foreach (members, it, member_info) {
623  if (member_info->leaf_type == LF_INDEX) {
626  it = rz_list_head(members);
627  if (!it) {
628  break;
629  }
630  member_info = rz_list_first(members);
631  }
632  RzTypeUnionMember *union_member = parse_union_member(typedb, stream, member_info);
633  if (!union_member) {
634  continue; // skip the failure
635  }
636  void *element = rz_vector_push(&base_type->union_data.members, union_member);
637  if (!element) {
638  rz_type_base_union_member_free(union_member, NULL);
639  return NULL;
640  }
641  free(union_member);
642  }
643  base_type->size = rz_bin_pdb_get_type_val(type);
644  if (base_type->attrs == RZ_TYPE_TYPECLASS_INVALID) {
645  base_type->attrs = RZ_TYPE_TYPECLASS_NONE;
646  rz_list_append(stream->print_type, base_type);
647  }
648  type->parsed = true;
649  return base_type->type ? rz_type_clone(base_type->type) : NULL;
650 }
RZ_API void rz_type_base_union_member_free(void *e, void *user)
Definition: base.c:21
@ RZ_BASE_TYPE_KIND_UNION
Definition: rz_type.h:74
@ RZ_TYPE_IDENTIFIER_KIND_UNION
Definition: rz_type.h:137
RzBaseTypeUnion union_data
Definition: rz_type.h:120
RzVector members
Definition: rz_type.h:104
static RzTypeUnionMember * parse_union_member(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info)
Parses union member.
Definition: type_pdb.c:527

References rz_base_type_t::attrs, create_rztype(), free(), get_tpitype_basetype(), rz_type_t::identifier, rz_base_type_t::kind, tpi_types::leaf_type, LF_INDEX, rz_base_type_union_t::members, rz_base_type_t::name, NULL, parse_union_member(), RZ_BASE_TYPE_KIND_UNION, rz_bin_pdb_get_type_by_index(), rz_bin_pdb_get_type_members(), rz_bin_pdb_get_type_name(), rz_bin_pdb_get_type_val(), rz_bin_pdb_type_is_fwdref(), rz_list_append(), rz_list_first(), RZ_LOG_INFO, RZ_LOG_WARN, rz_return_val_if_fail, rz_type_base_type_free(), rz_type_base_type_kind_as_string(), rz_type_base_type_new(), rz_type_base_union_member_free(), rz_type_clone(), rz_type_db_delete_base_type(), rz_type_db_save_base_type(), RZ_TYPE_IDENTIFIER_KIND_UNION, RZ_TYPE_TYPECLASS_INVALID, RZ_TYPE_TYPECLASS_NONE, rz_vector_clear(), rz_vector_push(), rz_base_type_t::size, strdup(), type, rz_base_type_t::type, and rz_base_type_t::union_data.

Referenced by parse_regular_type(), and parse_types().

◆ parse_union_member()

static RzTypeUnionMember * parse_union_member ( const RzTypeDB typedb,
RzPdbTpiStream stream,
RzPdbTpiType type_info 
)
static

Parses union member.

Parameters
typedbTypes DB instance
streamTPI Stream
type_infoCurrent RzPdbTpiType (member)
Returns
RzTypeUnionMember* parsed member, NULL if fail

Definition at line 527 of file type_pdb.c.

527  {
528  rz_return_val_if_fail(type_info && stream && typedb, NULL);
529  char *name = NULL;
530  ut64 offset = 0;
531  RzType *type = NULL;
532  switch (type_info->leaf_type) {
533  case LF_ONEMETHOD: {
534  name = rz_bin_pdb_get_type_name(type_info);
535  type = parse_type_onemethod(typedb, stream, type_info);
536  break;
537  }
538  case LF_MEMBER: {
539  offset = rz_bin_pdb_get_type_val(type_info);
540  name = rz_bin_pdb_get_type_name(type_info);
541  type = parse_type_member(typedb, stream, type_info, name);
542  break;
543  }
544  case LF_NESTTYPE: {
545  name = rz_bin_pdb_get_type_name(type_info);
546  type = parse_type_nest(typedb, stream, type_info);
547  break;
548  }
549  default:
550  RZ_LOG_ERROR("%s : unsupported leaf type 0x%x\n", __FUNCTION__, type_info->leaf_type);
551  goto cleanup;
552  }
553  if (!type) {
554  RZ_LOG_INFO("%s : couldn't parse union member type!\n", __FUNCTION__);
555  return NULL;
556  }
557 
559  if (!member) {
560  goto cleanup;
561  }
562  member->name = strdup(name);
563  member->type = type;
564  member->offset = offset;
565  return member;
566 cleanup:
568  return NULL;
569 }

References cleanup(), tpi_types::leaf_type, LF_MEMBER, LF_NESTTYPE, LF_ONEMETHOD, rz_type_union_member_t::name, NULL, rz_type_union_member_t::offset, parse_type_member(), parse_type_nest(), parse_type_onemethod(), rz_bin_pdb_get_type_name(), rz_bin_pdb_get_type_val(), RZ_LOG_ERROR, RZ_LOG_INFO, RZ_NEW0, rz_return_val_if_fail, rz_type_free(), strdup(), type, rz_type_union_member_t::type, and ut64().

Referenced by parse_union().

◆ rz_parse_pdb_types()

RZ_API void rz_parse_pdb_types ( const RzTypeDB typedb,
const RzPdb pdb 
)

Saves PDB types from TPI stream into the type database.

Parameters
tRzTypeDB instance
pdbPDB instance

Definition at line 802 of file type_pdb.c.

802  {
803  rz_return_if_fail(typedb && pdb);
804  RzPdbTpiStream *stream = pdb->s_tpi;
805  if (!stream) { // no TPI stream found
806  return;
807  }
808 
810  if (!stream->print_type) {
811  return;
812  }
813 
814  RBIter it;
816  rz_rbtree_foreach (stream->types, it, type, RzPdbTpiType, rb) {
817  if (type && is_parsable_type(type->leaf_type)) {
818  parse_types(typedb, stream, type);
819  }
820  }
821 }
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
#define rz_rbtree_foreach(root, it, data, struc, rb)
Definition: rz_rbtree.h:101
RzPdbTpiStream * s_tpi
Definition: rz_pdb.h:247
RzList * print_type
Definition: rz_pdb.h:157
static bool is_parsable_type(const TpiLeafType type)
Definition: type_pdb.c:30
static void parse_types(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type)
Delegate the type parsing to appropriate function.
Definition: type_pdb.c:771

References is_parsable_type(), parse_types(), tpi_stream_t::print_type, rz_list_new(), rz_rbtree_foreach, rz_return_if_fail, rz_pdb_t::s_tpi, and type.

Referenced by rz_core_pdb_load_info().