Rizin
unix-like reverse engineering framework and cli tools
tpi.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014 inisider <inisider@gmail.com>
2 // SPDX-FileCopyrightText: 2021 Basstorm <basstorm@nyist.edu.cn>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include "pdb.h"
6 
8  /* https://llvm.org/docs/PDB/RzPdbTpiStream.html#type-indices
9  .---------------------------.------.----------.
10  | Unused | Mode | Kind |
11  '---------------------------'------'----------'
12  |+32 |+12 |+8 |+0
13  */
14  return idx < stream->header.TypeIndexBegin;
15  // return ((value & 0x00000000FFF00) <= 0x700 && (value & 0x00000000000FF) <
16  // 0x80);
17 }
18 
19 int tpi_type_node_cmp(const void *incoming, const RBNode *in_tree, void *user) {
20  ut32 ia = *(ut32 *)incoming;
21  ut32 ta = container_of(in_tree, const RzPdbTpiType, rb)->type_index;
22  if (ia < ta) {
23  return -1;
24  } else if (ia > ta) {
25  return 1;
26  }
27  return 0;
28 }
29 
36  switch (idx) {
37  case NEAR_C:
38  case FAR_C:
39  return strdup("__cdecl");
40  case NEAR_PASCAL:
41  case FAR_PASCAL:
42  return strdup("__pascal");
43  case NEAR_FAST:
44  case FAR_FAST:
45  return strdup("__fastcall");
46  case NEAR_STD:
47  case FAR_STD:
48  return strdup("__stdcall");
49  case NEAR_SYS:
50  case FAR_SYS:
51  return strdup("__syscall");
52  case THISCALL:
53  return strdup("__thiscall");
54  case NEAR_VEC:
55  return strdup("__vectorcall");
56  default:
57  return NULL;
58  }
59 }
60 
62  /* https://llvm.org/docs/PDB/RzPdbTpiStream.html#type-indices
63  .---------------------------.------.----------.
64  | Unused | Mode | Kind |
65  '---------------------------'------'----------'
66  |+32 |+12 |+8 |+0
67  */
68  // because mode is only number between 0-7, 1 byte is enough
69  return (type & 0x0000000000F00) >> 8;
70 }
71 
73  /* https://llvm.org/docs/PDB/RzPdbTpiStream.html#type-indices
74  .---------------------------.------.----------.
75  | Unused | Mode | Kind |
76  '---------------------------'------'----------'
77  |+32 |+12 |+8 |+0
78  */
79  return (type & 0x00000000000FF);
80 }
81 
83  p->bits.packed = GET_BF(value, 0, 1);
84  p->bits.ctor = GET_BF(value, 1, 1);
85  p->bits.ovlops = GET_BF(value, 2, 1);
86  p->bits.isnested = GET_BF(value, 3, 1);
87  p->bits.packed = GET_BF(value, 4, 1);
88  p->bits.opassign = GET_BF(value, 5, 1);
89  p->bits.opcast = GET_BF(value, 6, 1);
90  p->bits.fwdref = GET_BF(value, 7, 1);
91  p->bits.scoped = GET_BF(value, 8, 1);
92  p->bits.hasuniquename = GET_BF(value, 9, 1);
93  p->bits.sealed = GET_BF(value, 10, 1);
94  p->bits.hfa = GET_BF(value, 11, 2);
95  p->bits.intrinsic = GET_BF(value, 13, 1);
96  p->bits.mocom = GET_BF(value, 14, 2);
97 }
98 
100  f->bits.access = GET_BF(value, 0, 2);
101  f->bits.mprop = GET_BF(value, 2, 3);
102  f->bits.pseudo = GET_BF(value, 5, 1);
103  f->bits.noinherit = GET_BF(value, 6, 1);
104  f->bits.noconstruct = GET_BF(value, 7, 1);
105  f->bits.compgenx = GET_BF(value, 8, 1);
106  f->bits.sealed = GET_BF(value, 9, 1);
107 }
108 
110  f->bits.cxxreturnudt = GET_BF(value, 0, 1);
111  f->bits.ctor = GET_BF(value, 1, 1);
112  f->bits.ctorvbase = GET_BF(value, 2, 1);
113 }
114 
116  p->bits.ptrtype = GET_BF(value, 0, 5);
117  p->bits.ptrmode = GET_BF(value, 5, 3);
118  p->bits.flat32 = GET_BF(value, 8, 1);
119  p->bits.volatile_ = GET_BF(value, 9, 1);
120  p->bits.const_ = GET_BF(value, 10, 1);
121  p->bits.unaligned = GET_BF(value, 11, 1);
122  p->bits.restrict_ = GET_BF(value, 12, 1);
123  p->bits.size = GET_BF(value, 13, 6);
124  p->bits.mocom = GET_BF(value, 19, 1);
125  p->bits.lref = GET_BF(value, 20, 1);
126  p->bits.rref = GET_BF(value, 21, 1);
127  p->bits.unused = GET_BF(value, 22, 10);
128 }
129 
131  m->bits.const_ = GET_BF(value, 0, 1);
132  m->bits.volatile_ = GET_BF(value, 1, 1);
133  m->bits.unaligned = GET_BF(value, 2, 1);
134 }
135 
144  if (!type) {
145  RZ_LOG_ERROR("Error allocating memory.\n");
146  return NULL;
147  }
148  type->leaf_type = LF_SIMPLE_TYPE;
149  type->type_index = idx;
150  // For simple type we don't set length
151  type->length = 0;
153  if (!simple_type) {
154  RZ_LOG_ERROR("Error allocating memory.\n");
155  free(type);
156  return NULL;
157  }
158  type->type_data = simple_type;
159  RzStrBuf *buf;
161  switch (kind) {
162  case PDB_NONE:
163  simple_type->size = 0;
164  buf = rz_strbuf_new("notype_t");
165  break;
166  case PDB_VOID:
167  simple_type->size = 0;
168  buf = rz_strbuf_new("void");
169  break;
170  case PDB_SIGNED_CHAR:
171  case PDB_NARROW_CHAR:
172  simple_type->size = 1;
173  buf = rz_strbuf_new("char");
174  break;
175  case PDB_UNSIGNED_CHAR:
176  simple_type->size = 1;
177  buf = rz_strbuf_new("unsigned char");
178  break;
179  case PDB_WIDE_CHAR:
180  simple_type->size = 4;
181  buf = rz_strbuf_new("wchar_t");
182  break;
183  case PDB_CHAR16:
184  simple_type->size = 2;
185  buf = rz_strbuf_new("char16_t");
186  break;
187  case PDB_CHAR32:
188  simple_type->size = 4;
189  buf = rz_strbuf_new("char32_t");
190  break;
191  case PDB_BYTE:
192  simple_type->size = 1;
193  buf = rz_strbuf_new("uint8_t");
194  break;
195  case PDB_SBYTE:
196  simple_type->size = 1;
197  buf = rz_strbuf_new("int8_t");
198  break;
199  case PDB_INT16:
200  case PDB_INT16_SHORT:
201  simple_type->size = 2;
202  buf = rz_strbuf_new("int16_t");
203  break;
204  case PDB_UINT16:
205  case PDB_UINT16_SHORT:
206  simple_type->size = 2;
207  buf = rz_strbuf_new("uint16_t");
208  break;
209  case PDB_INT32:
210  case PDB_INT32_LONG:
211  simple_type->size = 4;
212  buf = rz_strbuf_new("int32_t");
213  break;
214  case PDB_UINT32:
215  case PDB_UINT32_LONG:
216  simple_type->size = 4;
217  buf = rz_strbuf_new("uint32_t");
218  break;
219  case PDB_INT64:
220  case PDB_INT64_QUAD:
221  simple_type->size = 8;
222  buf = rz_strbuf_new("int64_t");
223  break;
224  case PDB_UINT64:
225  case PDB_UINT64_QUAD:
226  simple_type->size = 8;
227  buf = rz_strbuf_new("uint64_t");
228  break;
229  case PDB_INT128:
230  case PDB_INT128_OCT:
231  simple_type->size = 16;
232  buf = rz_strbuf_new("int128_t");
233  break;
234  case PDB_UINT128:
235  case PDB_UINT128_OCT:
236  simple_type->size = 16;
237  buf = rz_strbuf_new("uint128_t");
238  break;
239  case PDB_FLOAT16:
240  simple_type->size = 2;
241  buf = rz_strbuf_new("float");
242  break;
243  case PDB_FLOAT32:
244  case PDB_FLOAT32_PP:
245  simple_type->size = 4;
246  buf = rz_strbuf_new("float");
247  break;
248  case PDB_FLOAT48:
249  simple_type->size = 6;
250  buf = rz_strbuf_new("float");
251  break;
252  case PDB_FLOAT64:
253  simple_type->size = 8;
254  buf = rz_strbuf_new("double");
255  break;
256  case PDB_FLOAT80:
257  simple_type->size = 10;
258  buf = rz_strbuf_new("long double");
259  break;
260  case PDB_FLOAT128:
261  simple_type->size = 16;
262  buf = rz_strbuf_new("long double");
263  break;
264  case PDB_COMPLEX16:
265  simple_type->size = 2;
266  buf = rz_strbuf_new("float _Complex");
267  break;
268  case PDB_COMPLEX32:
269  case PDB_COMPLEX32_PP:
270  simple_type->size = 4;
271  buf = rz_strbuf_new("float _Complex");
272  break;
273  case PDB_COMPLEX48:
274  simple_type->size = 6;
275  buf = rz_strbuf_new("float _Complex");
276  break;
277  case PDB_COMPLEX64:
278  simple_type->size = 8;
279  buf = rz_strbuf_new("double _Complex");
280  break;
281  case PDB_COMPLEX80:
282  simple_type->size = 10;
283  buf = rz_strbuf_new("long double _Complex");
284  break;
285  case PDB_COMPLEX128:
286  simple_type->size = 16;
287  buf = rz_strbuf_new("long double _Complex");
288  break;
289  case PDB_BOOL8:
290  simple_type->size = 1;
291  buf = rz_strbuf_new("bool");
292  break;
293  case PDB_BOOL16:
294  simple_type->size = 2;
295  buf = rz_strbuf_new("bool");
296  break;
297  case PDB_BOOL32:
298  simple_type->size = 4;
299  buf = rz_strbuf_new("bool");
300  break;
301  case PDB_BOOL64:
302  simple_type->size = 8;
303  buf = rz_strbuf_new("bool");
304  break;
305  case PDB_BOOL128:
306  simple_type->size = 16;
307  buf = rz_strbuf_new("bool");
308  break;
309  default:
310  simple_type->size = 0;
311  buf = rz_strbuf_new("unknown_t");
312  break;
313  }
315  if (mode) {
316  rz_strbuf_append(buf, " *");
317  }
318  switch (mode) {
319  case NEAR_POINTER:
320  simple_type->size = 2;
321  break;
322  case FAR_POINTER:
323  case HUGE_POINTER:
324  case NEAR_POINTER32:
325  case FAR_POINTER32:
326  simple_type->size = 4;
327  break;
328  case NEAR_POINTER64:
329  simple_type->size = 8;
330  break;
331  case NEAR_POINTER128:
332  simple_type->size = 16;
333  break;
334  default:
335  break;
336  }
337  simple_type->type = rz_strbuf_drain(buf);
338  // We just insert once
339  rz_rbtree_insert(&stream->types, &type->type_index, &type->rb, tpi_type_node_cmp, NULL);
340  return type;
341 }
342 
344  switch (numeric->type_index) {
345  case LF_CHAR:
346  return *(st8 *)(numeric->data);
347  case LF_SHORT:
348  return *(st16 *)(numeric->data);
349  case LF_USHORT:
350  return *(ut16 *)(numeric->data);
351  case LF_LONG:
352  return *(st32 *)(numeric->data);
353  case LF_ULONG:
354  return *(ut32 *)(numeric->data);
355  case LF_QUADWORD:
356  return *(st64 *)(numeric->data);
357  case LF_UQUADWORD:
358  return *(ut64 *)(numeric->data);
359  default:
360  if (numeric->type_index >= 0x8000) {
361  return 0;
362  }
363  return *(ut16 *)(numeric->data);
364  }
365 }
373  rz_return_val_if_fail(t, false); // return val stands for we do nothing for it
374  switch (t->leaf_type) {
375  case LF_UNION: {
376  Tpi_LF_Union *lf = (Tpi_LF_Union *)t->type_data;
377  return lf->prop.bits.fwdref ? true : false;
378  }
379  case LF_STRUCTURE:
380  case LF_CLASS: {
381  Tpi_LF_Structure *lf = (Tpi_LF_Structure *)t->type_data;
382  return lf->prop.bits.fwdref ? true : false;
383  }
384  case LF_STRUCTURE_19:
385  case LF_CLASS_19: {
386  Tpi_LF_Structure_19 *lf = (Tpi_LF_Structure_19 *)t->type_data;
387  return lf->prop.bits.fwdref ? true : false;
388  }
389  case LF_ENUM: {
390  Tpi_LF_Enum *lf = (Tpi_LF_Enum *)t->type_data;
391  return lf->prop.bits.fwdref ? true : false;
392  }
393  default:
395  return false;
396  }
397 }
398 
408  RzPdbTpiType *tmp;
409  switch (t->leaf_type) {
410  case LF_FIELDLIST: {
411  Tpi_LF_FieldList *lf = t->type_data;
412  return lf->substructs;
413  }
414  case LF_UNION: {
416  Tpi_LF_FieldList *lf_union = tmp ? tmp->type_data : NULL;
417  return lf_union ? lf_union->substructs : NULL;
418  }
419  case LF_STRUCTURE:
420  case LF_CLASS: {
422  Tpi_LF_FieldList *lf_struct = tmp ? tmp->type_data : NULL;
423  return lf_struct ? lf_struct->substructs : NULL;
424  }
425  case LF_STRUCTURE_19:
426  case LF_CLASS_19: {
428  Tpi_LF_FieldList *lf_struct19 = tmp ? tmp->type_data : NULL;
429  return lf_struct19 ? lf_struct19->substructs : NULL;
430  }
431  case LF_ENUM: {
433  Tpi_LF_FieldList *lf_enum = tmp ? tmp->type_data : NULL;
434  return lf_enum ? lf_enum->substructs : NULL;
435  }
436  default:
437  return NULL;
438  }
439 }
440 
449  switch (type->leaf_type) {
450  case LF_MEMBER: {
451  Tpi_LF_Member *lf_member = type->type_data;
452  return lf_member->name.name;
453  }
454  case LF_STMEMBER: {
455  Tpi_LF_StaticMember *lf_stmember = type->type_data;
456  return lf_stmember->name.name;
457  }
458  case LF_ONEMETHOD: {
459  Tpi_LF_OneMethod *lf_onemethod = type->type_data;
460  return lf_onemethod->name.name;
461  }
462  case LF_METHOD: {
463  Tpi_LF_Method *lf_method = type->type_data;
464  return lf_method->name.name;
465  }
466  case LF_NESTTYPE: {
467  Tpi_LF_NestType *lf_nesttype = type->type_data;
468  return lf_nesttype->name.name;
469  }
470  case LF_ENUM: {
471  Tpi_LF_Enum *lf_enum = type->type_data;
472  return lf_enum->name.name;
473  }
474  case LF_ENUMERATE: {
475  Tpi_LF_Enumerate *lf_enumerate = type->type_data;
476  return lf_enumerate->name.name;
477  }
478  case LF_CLASS:
479  case LF_STRUCTURE: {
480  Tpi_LF_Structure *lf_struct = type->type_data;
481  return lf_struct->name.name;
482  }
483  case LF_CLASS_19:
484  case LF_STRUCTURE_19: {
485  Tpi_LF_Structure_19 *lf_struct_19 = type->type_data;
486  return lf_struct_19->name.name;
487  }
488  case LF_ARRAY: {
489  Tpi_LF_Array *lf_array = type->type_data;
490  return lf_array->name.name;
491  }
492  case LF_UNION: {
493  Tpi_LF_Union *lf_union = type->type_data;
494  return lf_union->name.name;
495  }
496  default:
497  return NULL;
498  }
499 }
500 
509  switch (type->leaf_type) {
510  case LF_ONEMETHOD: {
511  Tpi_LF_OneMethod *lf_onemethod = type->type_data;
512  return lf_onemethod->offset_in_vtable;
513  }
514  case LF_MEMBER: {
515  Tpi_LF_Member *lf_member = type->type_data;
516  return get_numeric_val(&lf_member->offset);
517  }
518  case LF_ENUMERATE: {
519  Tpi_LF_Enumerate *lf_enumerate = type->type_data;
520  return get_numeric_val(&lf_enumerate->enum_value);
521  }
522  case LF_CLASS:
523  case LF_STRUCTURE: {
524  Tpi_LF_Structure *lf_struct = type->type_data;
525  return get_numeric_val(&lf_struct->size);
526  }
527  case LF_CLASS_19:
528  case LF_STRUCTURE_19: {
529  Tpi_LF_Structure_19 *lf_struct_19 = type->type_data;
530  return get_numeric_val(&lf_struct_19->size);
531  }
532  case LF_ARRAY: {
533  Tpi_LF_Array *lf_array = type->type_data;
534  return get_numeric_val(&lf_array->size);
535  }
536  case LF_UNION: {
537  Tpi_LF_Union *lf_union = type->type_data;
538  return get_numeric_val(&lf_union->size);
539  }
540  case LF_INDEX: {
541  Tpi_LF_Index *lf_index = type->type_data;
542  return lf_index->index;
543  }
544  default:
545  return 0;
546  }
547 }
548 
549 static void free_snumeric(Tpi_Type_Numeric *numeric) {
550  switch (numeric->type_index) {
551  case LF_CHAR:
552  case LF_SHORT:
553  case LF_USHORT:
554  case LF_LONG:
555  case LF_ULONG:
556  case LF_QUADWORD:
557  case LF_UQUADWORD:
558  RZ_FREE(numeric->data);
559  break;
560  default:
561  if (numeric->type_index >= 0x8000) {
562  eprintf("%s::not supproted type\n", __FUNCTION__);
563  break;
564  }
565  RZ_FREE(numeric->data);
566  }
567 }
568 
569 static void free_tpi_type(void *type_info) {
570  rz_return_if_fail(type_info);
571  RzPdbTpiType *type = (RzPdbTpiType *)type_info;
572  switch (type->leaf_type) {
573  case LF_ENUMERATE: {
574  Tpi_LF_Enumerate *lf_en = (Tpi_LF_Enumerate *)type->type_data;
575  free_snumeric(&(lf_en->enum_value));
576  RZ_FREE(lf_en->name.name);
577  break;
578  }
579  case LF_NESTTYPE: {
580  Tpi_LF_NestType *lf_nest = (Tpi_LF_NestType *)type->type_data;
581  RZ_FREE(lf_nest->name.name);
582  break;
583  }
584  case LF_METHOD: {
585  Tpi_LF_Method *lf_meth = (Tpi_LF_Method *)type->type_data;
586  RZ_FREE(lf_meth->name.name);
587  break;
588  }
589  case LF_MEMBER: {
590  Tpi_LF_Member *lf_mem = (Tpi_LF_Member *)type->type_data;
591  free_snumeric(&lf_mem->offset);
592  RZ_FREE(lf_mem->name.name);
593  break;
594  }
595  case LF_STMEMBER: {
596  Tpi_LF_StaticMember *lf_stmem = (Tpi_LF_StaticMember *)type->type_data;
597  RZ_FREE(lf_stmem->name.name);
598  break;
599  }
600  case LF_FIELDLIST: {
601  Tpi_LF_FieldList *lf_fieldlist = (Tpi_LF_FieldList *)type->type_data;
602  rz_list_free(lf_fieldlist->substructs);
603  break;
604  }
605  case LF_CLASS:
606  case LF_STRUCTURE: {
607  Tpi_LF_Structure *lf_class = (Tpi_LF_Structure *)type->type_data;
608  free_snumeric(&lf_class->size);
609  RZ_FREE(lf_class->name.name);
610  RZ_FREE(lf_class->mangled_name.name);
611  break;
612  }
613  case LF_CLASS_19:
614  case LF_STRUCTURE_19: {
615  Tpi_LF_Structure_19 *lf_class_19 = (Tpi_LF_Structure_19 *)type->type_data;
616  free_snumeric(&lf_class_19->size);
617  RZ_FREE(lf_class_19->name.name);
618  RZ_FREE(lf_class_19->mangled_name.name);
619  break;
620  }
621  case LF_UNION: {
622  Tpi_LF_Union *lf_union = (Tpi_LF_Union *)type->type_data;
623  free_snumeric(&lf_union->size);
624  RZ_FREE(lf_union->name.name);
625  RZ_FREE(lf_union->mangled_name.name);
626  break;
627  }
628  case LF_ONEMETHOD: {
629  Tpi_LF_OneMethod *lf_onemethod = (Tpi_LF_OneMethod *)type->type_data;
630  RZ_FREE(lf_onemethod->name.name);
631  break;
632  }
633  case LF_BCLASS: {
634  Tpi_LF_BClass *lf_bclass = (Tpi_LF_BClass *)type->type_data;
635  free_snumeric(&lf_bclass->offset);
636  break;
637  }
638  case LF_VBCLASS:
639  case LF_IVBCLASS: {
640  Tpi_LF_VBClass *lf_vbclass = (Tpi_LF_VBClass *)type->type_data;
641  free_snumeric(&lf_vbclass->vb_pointer_offset);
643  break;
644  }
645  case LF_ENUM: {
646  Tpi_LF_Enum *lf_enum = (Tpi_LF_Enum *)type->type_data;
647  RZ_FREE(lf_enum->name.name);
648  RZ_FREE(lf_enum->mangled_name.name);
649  break;
650  }
651  case LF_ARRAY: {
652  Tpi_LF_Array *lf_array = (Tpi_LF_Array *)type->type_data;
653  free_snumeric(&lf_array->size);
654  RZ_FREE(lf_array->name.name);
655  break;
656  }
657  case LF_ARGLIST: {
658  Tpi_LF_Arglist *lf_arglist = (Tpi_LF_Arglist *)type->type_data;
659  RZ_FREE(lf_arglist->arg_type);
660  break;
661  }
662  case LF_VTSHAPE: {
663  Tpi_LF_Vtshape *lf_vtshape = (Tpi_LF_Vtshape *)type->type_data;
664  RZ_FREE(lf_vtshape->vt_descriptors);
665  break;
666  }
667  case LF_SIMPLE_TYPE: {
668  Tpi_LF_SimpleType *lf_simple = (Tpi_LF_SimpleType *)type->type_data;
669  RZ_FREE(lf_simple->type);
670  break;
671  }
672  case LF_METHODLIST: {
673  Tpi_LF_MethodList *lf_mlist = (Tpi_LF_MethodList *)type->type_data;
674  rz_list_free(lf_mlist->members);
675  break;
676  }
677  case LF_POINTER:
678  break;
679  case LF_PROCEDURE:
680  break;
681  case LF_MODIFIER:
682  break;
683  case LF_MFUNCTION:
684  break;
685  case LF_BITFIELD:
686  break;
687  case LF_INDEX:
688  break;
689  case LF_VFUNCTAB:
690  break;
691  default:
693  break;
694  }
695  free(type->type_data);
696  free(type);
697 }
698 
699 static void free_tpi_rbtree(RBNode *node, void *user) {
700  rz_return_if_fail(node);
703 }
704 
706  if (!stream) {
707  return;
708  }
710  rz_list_free(stream->print_type);
711  free(stream);
712 }
713 
714 static void skip_padding(RzBuffer *buf, ut16 len, ut16 *read_len, bool has_length) {
715  while (*read_len < len) {
716  ut8 byt;
717  if (!rz_buf_read8(buf, &byt)) {
718  break;
719  }
720  if (has_length && ((byt & 0xf0) == 0xf0 || byt == 0)) {
721  *read_len += 1;
722  } else if ((byt & 0xf0) == 0xf0) {
723  *read_len += 1;
724  } else {
725  rz_buf_seek(buf, -1, RZ_BUF_CUR);
726  break;
727  }
728  }
729 }
730 
731 static bool has_non_padding(RzBuffer *buf, ut16 len, ut16 *read_len) {
732  while (*read_len < len) {
733  ut8 byt;
734  if (!rz_buf_read8(buf, &byt)) {
735  break;
736  }
737  rz_buf_seek(buf, -1, RZ_BUF_CUR);
738  if ((byt & 0xf0) != 0xf0) {
739  return true;
740  }
741  return false;
742  }
743  return false;
744 }
745 
746 static bool parse_type_numeric(RzBuffer *buf, Tpi_Type_Numeric *numeric, ut16 *read_len) {
747  numeric->data = 0;
748  numeric->is_integer = true;
749  if (!rz_buf_read_le16(buf, &numeric->type_index)) {
750  return false;
751  }
752  *read_len += sizeof(ut16);
753  switch (numeric->type_index) {
754  case LF_CHAR:
755  numeric->data = RZ_NEW0(st8);
756  if (!rz_buf_read8(buf, numeric->data)) {
757  RZ_FREE(numeric->data);
758  return false;
759  }
760  *read_len += sizeof(st8);
761  break;
762  case LF_SHORT:
763  numeric->data = RZ_NEW0(st16);
764  if (!rz_buf_read_le16(buf, numeric->data)) {
765  RZ_FREE(numeric->data);
766  return false;
767  }
768  *read_len += sizeof(st16);
769  break;
770  case LF_USHORT:
771  numeric->data = RZ_NEW0(ut16);
772  if (!rz_buf_read_le16(buf, numeric->data)) {
773  RZ_FREE(numeric->data);
774  return false;
775  }
776  *read_len += sizeof(ut16);
777  break;
778  case LF_LONG:
779  numeric->data = RZ_NEW0(st32);
780  if (!rz_buf_read_le32(buf, numeric->data)) {
781  RZ_FREE(numeric->data);
782  return false;
783  }
784  *read_len += sizeof(st32);
785  break;
786  case LF_ULONG:
787  numeric->data = RZ_NEW0(ut32);
788  if (!rz_buf_read_le32(buf, numeric->data)) {
789  RZ_FREE(numeric->data);
790  return false;
791  }
792  *read_len += sizeof(ut32);
793  break;
794  case LF_QUADWORD:
795  numeric->data = RZ_NEW0(st64);
796  if (!rz_buf_read_le64(buf, numeric->data)) {
797  RZ_FREE(numeric->data);
798  return false;
799  }
800  *read_len += sizeof(st64);
801  break;
802  case LF_UQUADWORD:
803  numeric->data = RZ_NEW0(ut64);
804  if (!rz_buf_read_le64(buf, numeric->data)) {
805  RZ_FREE(numeric->data);
806  return false;
807  }
808  *read_len += sizeof(ut64);
809  break;
810  default:
811  if (numeric->type_index >= 0x8000) {
812  numeric->is_integer = false;
813  RZ_LOG_ERROR("%s: Skipping unsupported type (%d)\n", __FUNCTION__,
814  numeric->type_index);
815  return false;
816  }
817  numeric->data = RZ_NEW0(ut16);
818  *(ut16 *)(numeric->data) = numeric->type_index;
819  return true;
820  }
821  return true;
822 }
823 
825  ut16 size = 0;
826  while (*read_len < len) {
827  ut8 byt;
828  if (!rz_buf_read8(buf, &byt)) {
829  break;
830  }
831  *(read_len) += 1;
832  size++;
833  if (!byt) {
835  str->name = (char *)rz_mem_alloc(size);
836  if (!str->name) {
837  str->name = NULL;
838  RZ_LOG_ERROR("Error allocating memory.\n");
839  return;
840  }
841  rz_buf_read(buf, (ut8 *)str->name, size);
842  str->size = size;
843  break;
844  }
845  }
846 }
847 
851  if (!enumerate) {
852  return NULL;
853  }
854  ut16 fldattr;
855  if (!rz_buf_read_le16(buf, &fldattr)) {
856  RZ_FREE(enumerate);
857  return NULL;
858  }
859  parse_codeview_fld_attribute(&enumerate->fldattr, fldattr);
860  *read_len += sizeof(ut16);
861  if (!parse_type_numeric(buf, &enumerate->enum_value, read_len)) {
862  RZ_FREE(enumerate);
863  return NULL;
864  }
865  if (!enumerate->enum_value.is_integer) {
866  RZ_LOG_ERROR("Integer expected!\n");
867  free_snumeric(&enumerate->enum_value);
868  RZ_FREE(enumerate);
869  return NULL;
870  }
871  parse_type_string(buf, &enumerate->name, len, read_len);
872  skip_padding(buf, len, read_len, false);
873  return enumerate;
874 }
875 
879  if (!index) {
880  return NULL;
881  }
882  ut16 fldattr;
883  if (!rz_buf_read_le16(buf, &fldattr)) {
884  RZ_FREE(index);
885  return NULL;
886  }
887  parse_codeview_fld_attribute(&index->fldattr, fldattr);
888  *read_len += sizeof(ut16);
889  if (!rz_buf_read_le32(buf, &index->index)) {
890  RZ_FREE(index);
891  return NULL;
892  }
893  *read_len += sizeof(ut32);
894  skip_padding(buf, len, read_len, false);
895  return index;
896 }
897 
901  if (!nest) {
902  return NULL;
903  }
904  if (!rz_buf_read_le16(buf, &nest->pad)) {
905  RZ_FREE(nest);
906  return NULL;
907  }
908  *read_len += sizeof(ut16);
909  if (!rz_buf_read_le32(buf, &nest->index)) {
910  RZ_FREE(nest);
911  return NULL;
912  }
913  *read_len += sizeof(ut32);
914  parse_type_string(buf, &nest->name, len, read_len);
915  skip_padding(buf, len, read_len, false);
916  return nest;
917 }
918 
922  if (!vftab) {
923  return NULL;
924  }
925  if (!rz_buf_read_le16(buf, &vftab->pad)) {
926  RZ_FREE(vftab);
927  return NULL;
928  }
929  *read_len += sizeof(ut16);
930  if (!rz_buf_read_le32(buf, &vftab->index)) {
931  RZ_FREE(vftab);
932  return NULL;
933  }
934  *read_len += sizeof(ut32);
935  return vftab;
936 }
937 
941  if (!method) {
942  return NULL;
943  }
944  if (!rz_buf_read_le16(buf, &method->count)) {
945  RZ_FREE(method);
946  return NULL;
947  }
948  *read_len += sizeof(ut16);
949  if (!rz_buf_read_le32(buf, &method->mlist)) {
950  RZ_FREE(method);
951  return NULL;
952  }
953  *read_len += sizeof(ut32);
954  parse_type_string(buf, &method->name, len, read_len);
955  skip_padding(buf, len, read_len, false);
956  return method;
957 }
958 
962  if (!member) {
963  return NULL;
964  }
965  ut16 fldattr;
966  if (!rz_buf_read_le16(buf, &fldattr)) {
967  RZ_FREE(member);
968  return NULL;
969  }
970  parse_codeview_fld_attribute(&member->fldattr, fldattr);
971  *read_len += sizeof(ut16);
972  if (!rz_buf_read_le32(buf, &member->index)) {
973  RZ_FREE(member);
974  return NULL;
975  }
976  *read_len += sizeof(ut32);
977  if (!parse_type_numeric(buf, &member->offset, read_len)) {
978  RZ_FREE(member);
979  return NULL;
980  }
981  if (!member->offset.is_integer) {
982  RZ_LOG_ERROR("Integer expected!\n");
983  free_snumeric(&member->offset);
984  RZ_FREE(member);
985  return NULL;
986  }
987  parse_type_string(buf, &member->name, len, read_len);
988  skip_padding(buf, len, read_len, false);
989  return member;
990 }
991 
995  if (!member) {
996  return NULL;
997  }
998  ut16 fldattr;
999  if (!rz_buf_read_le16(buf, &fldattr)) {
1000  RZ_FREE(member);
1001  return NULL;
1002  }
1003  parse_codeview_fld_attribute(&member->fldattr, fldattr);
1004  *read_len += sizeof(ut16);
1005  if (!rz_buf_read_le32(buf, &member->index)) {
1006  RZ_FREE(member);
1007  return NULL;
1008  }
1009  *read_len += sizeof(ut32);
1010  parse_type_string(buf, &member->name, len, read_len);
1011  skip_padding(buf, len, read_len, false);
1012  return member;
1013 }
1014 
1018  if (!onemethod) {
1019  return NULL;
1020  }
1021  ut16 fldattr;
1022  if (!rz_buf_read_le16(buf, &fldattr)) {
1023  RZ_FREE(onemethod);
1024  return NULL;
1025  }
1026  parse_codeview_fld_attribute(&onemethod->fldattr, fldattr);
1027  *read_len += sizeof(ut16);
1028  if (!rz_buf_read_le32(buf, &onemethod->index)) {
1029  RZ_FREE(onemethod);
1030  return NULL;
1031  }
1032  *read_len += sizeof(ut32);
1033  onemethod->offset_in_vtable = 0;
1034  if (onemethod->fldattr.bits.mprop == MTintro ||
1035  onemethod->fldattr.bits.mprop == MTpureintro) {
1036  if (!rz_buf_read_le32(buf, &onemethod->offset_in_vtable)) {
1037  RZ_FREE(onemethod);
1038  }
1039  *read_len += sizeof(ut32);
1040  }
1041  parse_type_string(buf, &onemethod->name, len, read_len);
1042  skip_padding(buf, len, read_len, false);
1043  return onemethod;
1044 }
1045 
1048  Tpi_LF_BClass *bclass = RZ_NEW0(Tpi_LF_BClass);
1049  if (!bclass) {
1050  return NULL;
1051  }
1052  ut16 fldattr;
1053  if (!rz_buf_read_le16(buf, &fldattr)) {
1054  RZ_FREE(bclass);
1055  return NULL;
1056  }
1057  parse_codeview_fld_attribute(&bclass->fldattr, fldattr);
1058  *read_len += sizeof(ut16);
1059  if (!rz_buf_read_le32(buf, &bclass->index)) {
1060  RZ_FREE(bclass);
1061  return NULL;
1062  }
1063  *read_len += sizeof(ut32);
1064  if (!parse_type_numeric(buf, &bclass->offset, read_len)) {
1065  RZ_FREE(bclass);
1066  return NULL;
1067  }
1068  if (!bclass->offset.is_integer) {
1069  RZ_LOG_ERROR("Integer expected!\n");
1070  free_snumeric(&bclass->offset);
1071  RZ_FREE(bclass);
1072  return NULL;
1073  }
1074  skip_padding(buf, len, read_len, false);
1075  return bclass;
1076 }
1077 
1081  if (!bclass) {
1082  return NULL;
1083  }
1084  ut16 fldattr;
1085  if (!rz_buf_read_le16(buf, &fldattr)) {
1086  RZ_FREE(bclass);
1087  return NULL;
1088  }
1089  parse_codeview_fld_attribute(&bclass->fldattr, fldattr);
1090  *read_len += sizeof(ut16);
1091  if (!rz_buf_read_le32(buf, &bclass->direct_vbclass_idx)) {
1092  RZ_FREE(bclass);
1093  return NULL;
1094  }
1095  *read_len += sizeof(ut32);
1096  if (!rz_buf_read_le32(buf, &bclass->vb_pointer_idx)) {
1097  RZ_FREE(bclass);
1098  return NULL;
1099  }
1100  *read_len += sizeof(ut32);
1101  parse_type_numeric(buf, &bclass->vb_pointer_offset, read_len);
1102  if (!bclass->vb_pointer_offset.is_integer) {
1103  RZ_LOG_ERROR("Integer expected!\n");
1104  free_snumeric(&bclass->vb_pointer_offset);
1105  RZ_FREE(bclass);
1106  return NULL;
1107  }
1108  parse_type_numeric(buf, &bclass->vb_offset_from_vbtable, read_len);
1109  if (!bclass->vb_offset_from_vbtable.is_integer) {
1110  RZ_LOG_ERROR("Integer expected!\n");
1112  RZ_FREE(bclass);
1113  return NULL;
1114  }
1115  skip_padding(buf, len, read_len, false);
1116  return bclass;
1117 }
1118 
1122  if (!fieldlist) {
1123  return NULL;
1124  }
1126  if (!fieldlist->substructs) {
1127  goto error;
1128  }
1129 
1130  ut16 read_len = sizeof(ut16);
1131  while (read_len < len) {
1133  if (!type) {
1134  rz_list_free(fieldlist->substructs);
1135  goto error;
1136  }
1137  type->length = 0;
1138  type->type_index = 0;
1139  if (!rz_buf_read_le16(buf, &type->leaf_type)) {
1140  RZ_FREE(type);
1141  rz_list_free(fieldlist->substructs);
1142  goto error;
1143  }
1144  read_len += sizeof(ut16);
1145  switch (type->leaf_type) {
1146  case LF_ENUMERATE:
1147  type->type_data = parse_type_enumerate(buf, len, &read_len);
1148  break;
1149  case LF_NESTTYPE:
1150  type->type_data = parse_type_nesttype(buf, len, &read_len);
1151  break;
1152  case LF_VFUNCTAB:
1153  type->type_data = parse_type_vfunctab(buf, len, &read_len);
1154  break;
1155  case LF_METHOD:
1156  type->type_data = parse_type_method(buf, len, &read_len);
1157  break;
1158  case LF_MEMBER:
1159  type->type_data = parse_type_member(buf, len, &read_len);
1160  break;
1161  case LF_ONEMETHOD:
1162  type->type_data = parse_type_onemethod(buf, len, &read_len);
1163  break;
1164  case LF_BCLASS:
1165  type->type_data = parse_type_bclass(buf, len, &read_len);
1166  break;
1167  case LF_VBCLASS:
1168  case LF_IVBCLASS:
1169  type->type_data = parse_type_vbclass(buf, len, &read_len);
1170  break;
1171  case LF_STMEMBER:
1172  type->type_data = parse_type_staticmember(buf, len, &read_len);
1173  break;
1174  case LF_INDEX:
1175  type->type_data = parse_type_index(buf, len, &read_len);
1176  break;
1177  default:
1178  RZ_LOG_ERROR("%s: Unsupported leaf type 0x%" PFMT32x "\n", __FUNCTION__,
1179  type->leaf_type);
1180  RZ_FREE(type);
1181  rz_list_free(fieldlist->substructs);
1182  goto error;
1183  }
1184  if (!type->type_data) {
1185  RZ_FREE(type);
1186  rz_list_free(fieldlist->substructs);
1187  goto error;
1188  }
1189  rz_list_append(fieldlist->substructs, type);
1190  }
1191  return fieldlist;
1192 error:
1193  RZ_FREE(fieldlist);
1194  return NULL;
1195 }
1196 
1199  Tpi_LF_Enum *_enum = RZ_NEW0(Tpi_LF_Enum);
1200  if (!_enum) {
1201  return NULL;
1202  }
1203  ut16 read_bytes = sizeof(ut16); // include leaf_type
1204  if (!rz_buf_read_le16(buf, &_enum->count)) {
1205  RZ_FREE(_enum);
1206  return NULL;
1207  }
1208  read_bytes += sizeof(ut16);
1209  ut16 prop;
1210  if (!rz_buf_read_le16(buf, &prop)) {
1211  RZ_FREE(_enum);
1212  return NULL;
1213  }
1214  parse_codeview_property(&_enum->prop, prop);
1215  read_bytes += sizeof(ut16);
1216  if (!rz_buf_read_le32(buf, &_enum->utype)) {
1217  RZ_FREE(_enum);
1218  return NULL;
1219  }
1220  read_bytes += sizeof(ut32);
1221  if (!rz_buf_read_le32(buf, &_enum->field_list)) {
1222  RZ_FREE(_enum);
1223  return NULL;
1224  }
1225  read_bytes += sizeof(ut32);
1226  parse_type_string(buf, &_enum->name, len, &read_bytes);
1227  if (has_non_padding(buf, len, &read_bytes)) {
1228  parse_type_string(buf, &_enum->mangled_name, len, &read_bytes);
1229  }
1230  skip_padding(buf, len, &read_bytes, true);
1231  return _enum;
1232 }
1233 
1237  if (!structure) {
1238  return NULL;
1239  }
1240  ut16 read_bytes = sizeof(ut16);
1241  if (!rz_buf_read_le16(buf, &structure->count)) {
1242  RZ_FREE(structure);
1243  return NULL;
1244  }
1245  read_bytes += sizeof(ut16);
1246  ut16 prop;
1247  if (!rz_buf_read_le16(buf, &prop)) {
1248  RZ_FREE(structure);
1249  return NULL;
1250  }
1251  parse_codeview_property(&structure->prop, prop);
1252  read_bytes += sizeof(ut16);
1253  if (!rz_buf_read_le32(buf, &structure->field_list)) {
1254  RZ_FREE(structure);
1255  return NULL;
1256  }
1257  read_bytes += sizeof(ut32);
1258  if (!rz_buf_read_le32(buf, &structure->derived)) {
1259  RZ_FREE(structure);
1260  return NULL;
1261  }
1262  read_bytes += sizeof(ut32);
1263  if (!rz_buf_read_le32(buf, &structure->vshape)) {
1264  RZ_FREE(structure);
1265  return NULL;
1266  }
1267  read_bytes += sizeof(ut32);
1268  if (!parse_type_numeric(buf, &structure->size, &read_bytes)) {
1269  RZ_FREE(structure);
1270  return NULL;
1271  }
1272  if (!structure->size.is_integer) {
1273  RZ_LOG_ERROR("Integer expected!\n");
1274  free_snumeric(&structure->size);
1275  RZ_FREE(structure);
1276  return NULL;
1277  }
1278  parse_type_string(buf, &structure->name, len, &read_bytes);
1279  if (has_non_padding(buf, len, &read_bytes)) {
1280  parse_type_string(buf, &structure->mangled_name, len, &read_bytes);
1281  }
1282  skip_padding(buf, len, &read_bytes, true);
1283  return structure;
1284 }
1285 
1289  if (!structure) {
1290  return NULL;
1291  }
1292  ut16 read_bytes = sizeof(ut16);
1293  ut16 prop;
1294  if (!rz_buf_read_le16(buf, &prop)) {
1295  RZ_FREE(structure);
1296  return NULL;
1297  }
1298  parse_codeview_property(&structure->prop, prop);
1299  read_bytes += sizeof(ut16);
1300  if (!rz_buf_read_le16(buf, &structure->unknown)) {
1301  RZ_FREE(structure);
1302  return NULL;
1303  }
1304  read_bytes += sizeof(ut16);
1305  if (!rz_buf_read_le32(buf, &structure->field_list)) {
1306  RZ_FREE(structure);
1307  return NULL;
1308  }
1309  read_bytes += sizeof(ut32);
1310  if (!rz_buf_read_le32(buf, &structure->derived)) {
1311  RZ_FREE(structure);
1312  return NULL;
1313  }
1314  read_bytes += sizeof(ut32);
1315  if (!rz_buf_read_le32(buf, &structure->vshape)) {
1316  RZ_FREE(structure);
1317  return NULL;
1318  }
1319  read_bytes += sizeof(ut32);
1320  if (!parse_type_numeric(buf, &structure->unknown1, &read_bytes)) {
1321  RZ_FREE(structure);
1322  return NULL;
1323  }
1324  if (!parse_type_numeric(buf, &structure->size, &read_bytes)) {
1325  RZ_FREE(structure);
1326  return NULL;
1327  }
1328  if (!structure->size.is_integer) {
1329  RZ_LOG_ERROR("Integer expected!\n");
1330  free_snumeric(&structure->size);
1331  RZ_FREE(structure);
1332  return NULL;
1333  }
1334  parse_type_string(buf, &structure->name, len, &read_bytes);
1335  if (has_non_padding(buf, len, &read_bytes)) {
1336  parse_type_string(buf, &structure->mangled_name, len, &read_bytes);
1337  }
1338  skip_padding(buf, len, &read_bytes, true);
1339  return structure;
1340 }
1341 
1345  if (!pointer) {
1346  return NULL;
1347  }
1348  ut16 read_bytes = sizeof(ut16);
1349  if (!rz_buf_read_le32(buf, &pointer->utype)) {
1350  RZ_FREE(pointer);
1351  return NULL;
1352  }
1353  read_bytes += sizeof(ut32);
1354  ut32 ptrattr;
1355  if (!rz_buf_read_le32(buf, &ptrattr)) {
1356  RZ_FREE(pointer);
1357  return NULL;
1358  }
1359  parse_codeview_pointer_attribute(&pointer->ptr_attr, ptrattr);
1360  read_bytes += sizeof(ut32);
1361  if (pointer->ptr_attr.bits.ptrmode == PTR_MODE_PMFUNC ||
1362  pointer->ptr_attr.bits.ptrmode == PTR_MODE_PMEM) {
1363  read_bytes += sizeof(ut32);
1364  if (!rz_buf_read_le32(buf, &pointer->pmember.pmclass)) {
1365  RZ_FREE(pointer);
1366  return NULL;
1367  }
1368  read_bytes += sizeof(ut16);
1369  if (!rz_buf_read_le16(buf, &pointer->pmember.pmtype)) {
1370  RZ_FREE(pointer);
1371  return NULL;
1372  }
1373  } else if (pointer->ptr_attr.bits.ptrtype == PTR_BASE_TYPE) {
1374  read_bytes += sizeof(ut32);
1375  if (!rz_buf_read_le32(buf, &pointer->pbase.index)) {
1376  RZ_FREE(pointer);
1377  return NULL;
1378  }
1379  }
1380  skip_padding(buf, len, &read_bytes, true);
1381  return pointer;
1382 }
1383 
1386  Tpi_LF_Array *array = RZ_NEW0(Tpi_LF_Array);
1387  if (!array) {
1388  return NULL;
1389  }
1390  ut16 read_bytes = sizeof(ut16);
1391  if (!rz_buf_read_le32(buf, &array->element_type)) {
1392  RZ_FREE(array);
1393  return NULL;
1394  }
1395  read_bytes += sizeof(ut32);
1396  if (!rz_buf_read_le32(buf, &array->index_type)) {
1397  RZ_FREE(array);
1398  return NULL;
1399  }
1400  read_bytes += sizeof(ut32);
1401  if (!parse_type_numeric(buf, &array->size, &read_bytes)) {
1402  RZ_FREE(array);
1403  return NULL;
1404  }
1405  if (!array->size.is_integer) {
1406  RZ_LOG_ERROR("Integer expected!\n");
1407  free_snumeric(&array->size);
1408  RZ_FREE(array);
1409  return NULL;
1410  }
1411  parse_type_string(buf, &array->name, len, &read_bytes);
1412  skip_padding(buf, len, &read_bytes, true);
1413  return array;
1414 }
1415 
1419  if (!modifier) {
1420  return NULL;
1421  }
1422  ut16 read_bytes = sizeof(ut16);
1423  if (!rz_buf_read_le32(buf, &modifier->modified_type)) {
1424  RZ_FREE(modifier);
1425  return NULL;
1426  }
1427  read_bytes += sizeof(ut32);
1428  ut16 umodifier;
1429  if (!rz_buf_read_le16(buf, &umodifier)) {
1430  RZ_FREE(modifier);
1431  return NULL;
1432  }
1433  parse_codeview_modifier(&modifier->umodifier, umodifier);
1434  read_bytes += sizeof(ut16);
1435  skip_padding(buf, len, &read_bytes, true);
1436  return modifier;
1437 }
1438 
1442  if (!arglist) {
1443  return NULL;
1444  }
1445  ut16 read_bytes = sizeof(ut16);
1446  if (!rz_buf_read_le32(buf, &arglist->count)) {
1447  RZ_FREE(arglist);
1448  return NULL;
1449  }
1450  read_bytes += sizeof(ut32);
1451  arglist->arg_type = (ut32 *)malloc(sizeof(ut32) * arglist->count);
1452  if (!arglist->arg_type) {
1453  RZ_LOG_ERROR("Error allocating memory.\n");
1454  RZ_FREE(arglist);
1455  return NULL;
1456  }
1457  for (size_t i = 0; i < arglist->count; i++) {
1458  if (!rz_buf_read_le32(buf, &arglist->arg_type[i])) {
1459  RZ_FREE(arglist->arg_type);
1460  RZ_FREE(arglist);
1461  return NULL;
1462  }
1463  read_bytes += sizeof(ut32);
1464  }
1465  skip_padding(buf, len, &read_bytes, true);
1466 
1467  return arglist;
1468 }
1469 
1473  if (!mfunc) {
1474  return NULL;
1475  }
1476  ut16 read_bytes = sizeof(ut16);
1477  if (!rz_buf_read_le32(buf, &mfunc->return_type)) {
1478  RZ_FREE(mfunc);
1479  return NULL;
1480  }
1481  read_bytes += sizeof(ut32);
1482  if (!rz_buf_read_le32(buf, &mfunc->class_type)) {
1483  RZ_FREE(mfunc);
1484  return NULL;
1485  }
1486  read_bytes += sizeof(ut32);
1487  if (!rz_buf_read_le32(buf, &mfunc->this_type)) {
1488  RZ_FREE(mfunc);
1489  return NULL;
1490  }
1491  read_bytes += sizeof(ut32);
1492  if (!rz_buf_read8(buf, (ut8 *)&mfunc->call_conv)) {
1493  RZ_FREE(mfunc);
1494  return NULL;
1495  }
1496  read_bytes += sizeof(ut8);
1497  ut8 funcattr;
1498  if (!rz_buf_read8(buf, &funcattr)) {
1499  RZ_FREE(mfunc);
1500  return NULL;
1501  }
1502  parse_codeview_func_attribute(&mfunc->func_attr, funcattr);
1503  read_bytes += sizeof(ut8);
1504  if (!rz_buf_read_le16(buf, &mfunc->parm_count)) {
1505  RZ_FREE(mfunc);
1506  return NULL;
1507  }
1508  read_bytes += sizeof(ut16);
1509  if (!rz_buf_read_le32(buf, &mfunc->arglist)) {
1510  RZ_FREE(mfunc);
1511  return NULL;
1512  }
1513  read_bytes += sizeof(ut32);
1514  if (!rz_buf_read_le32(buf, (ut32 *)&mfunc->this_adjust)) {
1515  RZ_FREE(mfunc);
1516  return NULL;
1517  }
1518  read_bytes += sizeof(ut32);
1519  skip_padding(buf, len, &read_bytes, true);
1520  return mfunc;
1521 }
1522 
1526  if (!mlist) {
1527  return NULL;
1528  }
1529  mlist->members = rz_list_newf(free);
1530  if (!mlist->members) {
1531  RZ_LOG_ERROR("Error allocating memory.\n");
1532  goto error;
1533  }
1534  ut16 read_bytes = sizeof(ut16);
1535  while (read_bytes < len) {
1537  if (!member) {
1538  continue;
1539  }
1540  ut16 fldattr;
1541  if (!rz_buf_read_le16(buf, &fldattr)) {
1542  RZ_FREE(member);
1543  rz_list_free(mlist->members);
1544  RZ_FREE(mlist);
1545  return NULL;
1546  }
1547  parse_codeview_fld_attribute(&member->fldattr, fldattr);
1548  read_bytes += sizeof(ut16);
1549  if (!rz_buf_read_le16(buf, &member->pad)) {
1550  RZ_FREE(member);
1551  rz_list_free(mlist->members);
1552  RZ_FREE(mlist);
1553  return NULL;
1554  }
1555  read_bytes += sizeof(ut16);
1556  if (!rz_buf_read_le32(buf, &member->type)) {
1557  RZ_FREE(member);
1558  rz_list_free(mlist->members);
1559  RZ_FREE(mlist);
1560  return NULL;
1561  }
1562  read_bytes += sizeof(ut32);
1563  member->optional_offset = 0;
1564  if (member->fldattr.bits.mprop == MTintro ||
1565  member->fldattr.bits.mprop == MTpureintro) {
1566  if (!rz_buf_read_le32(buf, &member->optional_offset)) {
1567  RZ_FREE(member);
1568  rz_list_free(mlist->members);
1569  RZ_FREE(mlist);
1570  return NULL;
1571  }
1572  read_bytes += sizeof(ut32);
1573  }
1574  rz_list_append(mlist->members, member);
1575  }
1576  skip_padding(buf, len, &read_bytes, true);
1577  return mlist;
1578 
1579 error:
1580  RZ_FREE(mlist);
1581  return NULL;
1582 }
1583 
1587  if (!proc) {
1588  return NULL;
1589  }
1590  ut16 read_bytes = sizeof(ut16);
1591  if (!rz_buf_read_le32(buf, &proc->return_type)) {
1592  RZ_FREE(proc);
1593  return NULL;
1594  }
1595  read_bytes += sizeof(ut32);
1596  if (!rz_buf_read8(buf, (ut8 *)&proc->call_conv)) {
1597  RZ_FREE(proc);
1598  return NULL;
1599  }
1600  read_bytes += sizeof(ut8);
1601  ut8 funcattr;
1602  if (!rz_buf_read8(buf, &funcattr)) {
1603  RZ_FREE(proc);
1604  return NULL;
1605  }
1606  parse_codeview_func_attribute(&proc->func_attr, funcattr);
1607  read_bytes += sizeof(ut8);
1608  if (!rz_buf_read_le16(buf, &proc->parm_count)) {
1609  RZ_FREE(proc);
1610  return NULL;
1611  }
1612  read_bytes += sizeof(ut16);
1613  if (!rz_buf_read_le32(buf, &proc->arg_list)) {
1614  RZ_FREE(proc);
1615  return NULL;
1616  }
1617  read_bytes += sizeof(ut32);
1618  skip_padding(buf, len, &read_bytes, true);
1619  return proc;
1620 }
1621 
1625  if (!unin) {
1626  return NULL;
1627  }
1628  ut16 read_bytes = sizeof(ut16);
1629  if (!rz_buf_read_le16(buf, &unin->count)) {
1630  RZ_FREE(unin);
1631  return NULL;
1632  }
1633  read_bytes += sizeof(ut16);
1634  ut16 prop;
1635  if (!rz_buf_read_le16(buf, &prop)) {
1636  RZ_FREE(unin);
1637  return NULL;
1638  }
1639  parse_codeview_property(&unin->prop, prop);
1640  read_bytes += sizeof(ut16);
1641  if (!rz_buf_read_le32(buf, &unin->field_list)) {
1642  RZ_FREE(unin);
1643  return NULL;
1644  }
1645  read_bytes += sizeof(ut32);
1646  if (!parse_type_numeric(buf, &unin->size, &read_bytes)) {
1647  RZ_FREE(unin);
1648  }
1649  if (!unin->size.is_integer) {
1650  RZ_LOG_ERROR("Integer expected!\n");
1651  free_snumeric(&unin->size);
1652  RZ_FREE(unin);
1653  return NULL;
1654  }
1655  parse_type_string(buf, &unin->name, len, &read_bytes);
1656  if (has_non_padding(buf, len, &read_bytes)) {
1657  parse_type_string(buf, &unin->mangled_name, len, &read_bytes);
1658  }
1659 
1660  skip_padding(buf, len, &read_bytes, true);
1661  return unin;
1662 }
1663 
1667  if (!bf) {
1668  return NULL;
1669  }
1670  ut16 read_bytes = sizeof(ut16);
1671  if (!rz_buf_read_le32(buf, &bf->base_type)) {
1672  RZ_FREE(bf);
1673  return NULL;
1674  }
1675  read_bytes += sizeof(ut32);
1676  if (!rz_buf_read8(buf, &bf->length)) {
1677  RZ_FREE(bf);
1678  return NULL;
1679  }
1680  read_bytes += sizeof(ut8);
1681  if (!rz_buf_read8(buf, &bf->position)) {
1682  RZ_FREE(bf);
1683  return NULL;
1684  }
1685  read_bytes += sizeof(ut8);
1686  skip_padding(buf, len, &read_bytes, true);
1687  return bf;
1688 }
1689 
1693  if (!vt) {
1694  return NULL;
1695  }
1696  ut16 read_bytes = sizeof(ut16);
1697  if (!rz_buf_read_le16(buf, &vt->count)) {
1698  RZ_FREE(vt);
1699  return NULL;
1700  }
1701  read_bytes += sizeof(ut16);
1702  ut16 size = (4 * vt->count + (vt->count % 2) * 4) / 8;
1703  vt->vt_descriptors = (char *)malloc(size);
1704  if (!vt->vt_descriptors) {
1705  RZ_LOG_ERROR("Error allocating memory.\n");
1706  RZ_FREE(vt);
1707  return NULL;
1708  }
1710  read_bytes += size;
1711  skip_padding(buf, len, &read_bytes, true);
1712  return vt;
1713 }
1714 
1716  if (!buf || !type) {
1717  return false;
1718  }
1719  if (!rz_buf_read_le16(buf, &type->length)) {
1720  return false;
1721  }
1722  if (!rz_buf_read_le16(buf, &type->leaf_type)) {
1723  return false;
1724  }
1725  switch (type->leaf_type) {
1726  case LF_FIELDLIST:
1727  type->type_data = parse_type_fieldlist(buf, type->length);
1728  break;
1729  case LF_ENUM:
1730  type->type_data = parse_type_enum(buf, type->length);
1731  break;
1732  case LF_CLASS:
1733  case LF_STRUCTURE:
1734  type->type_data = parse_type_struct(buf, type->length);
1735  break;
1736  case LF_CLASS_19:
1737  case LF_STRUCTURE_19:
1738  type->type_data = parse_type_struct_19(buf, type->length);
1739  break;
1740  case LF_POINTER:
1741  type->type_data = parse_type_pointer(buf, type->length);
1742  break;
1743  case LF_ARRAY:
1744  type->type_data = parse_type_array(buf, type->length);
1745  break;
1746  case LF_MODIFIER:
1747  type->type_data = parse_type_modifier(buf, type->length);
1748  break;
1749  case LF_ARGLIST:
1750  type->type_data = parse_type_arglist(buf, type->length);
1751  break;
1752  case LF_MFUNCTION:
1753  type->type_data = parse_type_mfunction(buf, type->length);
1754  break;
1755  case LF_METHODLIST:
1756  type->type_data = parse_type_methodlist(buf, type->length);
1757  break;
1758  case LF_PROCEDURE:
1759  type->type_data = parse_type_procedure(buf, type->length);
1760  break;
1761  case LF_UNION:
1762  type->type_data = parse_type_union(buf, type->length);
1763  break;
1764  case LF_BITFIELD:
1765  type->type_data = parse_type_bitfield(buf, type->length);
1766  break;
1767  case LF_VTSHAPE:
1768  type->type_data = parse_type_vtshape(buf, type->length);
1769  break;
1770  default:
1771  RZ_LOG_ERROR("%s: unsupported leaf type: 0x%" PFMT32x "\n", __FUNCTION__, type->leaf_type);
1772  return false;
1773  }
1774  return true;
1775 }
1776 
1778  return rz_buf_read_le32(buf, &s->header.Version) &&
1779  rz_buf_read_le32(buf, &s->header.HeaderSize) &&
1780  rz_buf_read_le32(buf, &s->header.TypeIndexBegin) &&
1781  rz_buf_read_le32(buf, &s->header.TypeIndexEnd) &&
1782  rz_buf_read_le32(buf, &s->header.TypeRecordBytes) &&
1783 
1784  rz_buf_read_le16(buf, &s->header.HashStreamIndex) &&
1785  rz_buf_read_le16(buf, &s->header.HashAuxStreamIndex) &&
1786  rz_buf_read_le32(buf, &s->header.HashKeySize) &&
1787  rz_buf_read_le32(buf, &s->header.NumHashBuckets) &&
1788 
1789  rz_buf_read_le32(buf, (ut32 *)&s->header.HashValueBufferOffset) &&
1790  rz_buf_read_le32(buf, &s->header.HashValueBufferLength) &&
1791 
1792  rz_buf_read_le32(buf, (ut32 *)&s->header.IndexOffsetBufferOffset) &&
1793  rz_buf_read_le32(buf, &s->header.IndexOffsetBufferLength) &&
1794 
1795  rz_buf_read_le32(buf, (ut32 *)&s->header.HashAdjBufferOffset) &&
1796  rz_buf_read_le32(buf, &s->header.HashAdjBufferLength);
1797 }
1798 
1800  if (!pdb || !stream) {
1801  return false;
1802  }
1803  if (stream->stream_idx != PDB_STREAM_TPI) {
1804  RZ_LOG_ERROR("Error TPI stream index.\n");
1805  return false;
1806  }
1807  pdb->s_tpi = RZ_NEW0(RzPdbTpiStream);
1808  RzPdbTpiStream *s = pdb->s_tpi;
1809  if (!s) {
1810  RZ_LOG_ERROR("Error allocating memory.\n");
1811  return false;
1812  }
1813  s->types = NULL;
1814  RzBuffer *buf = stream->stream_data;
1815  if (!parse_tpi_stream_header(s, buf)) {
1816  return false;
1817  }
1818  if (s->header.HeaderSize != sizeof(RzPdbTpiStreamHeader)) {
1819  RZ_LOG_ERROR("Corrupted TPI stream.\n");
1820  return false;
1821  }
1822  RzPdbTpiType *type;
1823  for (ut32 i = s->header.TypeIndexBegin; i < s->header.TypeIndexEnd; i++) {
1825  if (!type) {
1826  continue;
1827  }
1828  type->type_index = i;
1829  if (!parse_tpi_types(buf, type) || !type->type_data) {
1830  RZ_LOG_ERROR("Parse TPI type error. idx in stream: 0x%" PFMT32x "\n", i);
1831  RZ_FREE(type);
1832  return false;
1833  }
1834  rz_rbtree_insert(&s->types, &type->type_index, &type->rb, tpi_type_node_cmp, NULL);
1835  }
1836  return true;
1837 }
1838 
1846  if (index == 0) {
1847  return NULL;
1848  }
1849 
1850  RBNode *node = rz_rbtree_find(stream->types, &index, tpi_type_node_cmp, NULL);
1851  if (!node) {
1852  if (!is_simple_type(stream, index)) {
1853  return NULL;
1854  } else {
1855  return parse_simple_type(stream, index);
1856  }
1857  }
1859  return type;
1860 }
size_t len
Definition: 6502dis.c:15
#define PFMT32x
#define RZ_IPI
Definition: analysis_wasm.c:11
lzma_index ** i
Definition: index.h:629
static int value
Definition: cmd_api.c:93
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define ut8
Definition: dcpu16.h:8
uint16_t ut16
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf stream
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_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
void * malloc(size_t size)
Definition: malloc.c:123
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")
#define header(is_bt, len_min, ret_op)
int type
Definition: mipsasm.c:17
int idx
Definition: setup.py:197
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API st64 rz_buf_seek(RZ_NONNULL RzBuffer *b, st64 addr, int whence)
Modify the current cursor position in the buffer.
Definition: buf.c:1166
#define RZ_BUF_CUR
Definition: rz_buf.h:15
RZ_API bool rz_buf_read8(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut8 *result)
Read a byte at the cursor in the buffer.
Definition: buf.c:860
#define rz_buf_read_le16(b, result)
Read a big endian or little endian (ut16, ut32, ut64) at the specified offset in the buffer and shift...
Definition: rz_buf.h:266
#define rz_buf_read_le32(b, result)
Definition: rz_buf.h:267
#define rz_buf_read_le64(b, result)
Definition: rz_buf.h:268
RZ_API st64 rz_buf_read(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API void * rz_mem_alloc(int sz)
Definition: mem.c:357
RzPdbTpiCallingConvention
Definition: rz_pdb.h:84
@ THISCALL
Definition: rz_pdb.h:96
@ NEAR_PASCAL
Definition: rz_pdb.h:87
@ NEAR_FAST
Definition: rz_pdb.h:89
@ FAR_PASCAL
Definition: rz_pdb.h:88
@ FAR_FAST
Definition: rz_pdb.h:90
@ NEAR_C
Definition: rz_pdb.h:85
@ NEAR_SYS
Definition: rz_pdb.h:94
@ NEAR_VEC
Definition: rz_pdb.h:109
@ FAR_C
Definition: rz_pdb.h:86
@ FAR_SYS
Definition: rz_pdb.h:95
@ NEAR_STD
Definition: rz_pdb.h:92
@ FAR_STD
Definition: rz_pdb.h:93
@ PDB_STREAM_TPI
Definition: rz_pdb.h:164
#define GET_BF(value, start, len)
Definition: rz_pdb.h:19
RZ_API RBNode * rz_rbtree_find(RBNode *root, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:267
RZ_API void rz_rbtree_free(RZ_NULLABLE RBNode *root, RBNodeFree freefn, void *user)
Definition: rbtree.c:281
RZ_API bool rz_rbtree_insert(RBNode **root, void *data, RBNode *node, RBComparator cmp, void *user)
Returns true if the node was inserted successfully.
Definition: rbtree.c:291
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
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
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_FREE(x)
Definition: rz_types.h:369
#define container_of(ptr, type, member)
Definition: rz_types.h:650
#define RZ_BORROW
Definition: rz_types.h:63
#define st8
Definition: rz_types_base.h:16
#define st64
Definition: rz_types_base.h:10
#define st16
Definition: rz_types_base.h:14
#define st32
Definition: rz_types_base.h:12
#define f(i)
Definition: sha256.c:46
ut32 * arg_type
Definition: tpi.h:332
ut32 count
Definition: tpi.h:331
Tpi_Type_String name
Definition: tpi.h:438
ut32 index_type
Definition: tpi.h:436
Tpi_Type_Numeric size
Definition: tpi.h:437
ut32 element_type
Definition: tpi.h:435
TpiCVFldattr fldattr
Definition: tpi.h:566
ut32 index
Definition: tpi.h:567
Tpi_Type_Numeric offset
Definition: tpi.h:568
ut32 base_type
Definition: tpi.h:478
ut8 length
Definition: tpi.h:479
ut8 position
Definition: tpi.h:480
ut16 count
Definition: tpi.h:491
ut32 utype
Definition: tpi.h:493
ut32 field_list
Definition: tpi.h:494
TpiCVProperty prop
Definition: tpi.h:492
Tpi_Type_String name
Definition: tpi.h:495
Tpi_Type_String mangled_name
Definition: tpi.h:496
Tpi_Type_String name
Definition: tpi.h:503
TpiCVFldattr fldattr
Definition: tpi.h:501
Tpi_Type_Numeric enum_value
Definition: tpi.h:502
RzList * substructs
Definition: tpi.h:581
ut32 index
Definition: tpi.h:553
TpiCVFldattr fldattr
Definition: tpi.h:552
ut32 class_type
Definition: tpi.h:320
ut32 this_type
Definition: tpi.h:321
ut32 return_type
Definition: tpi.h:319
TpiCVFuncattr func_attr
Definition: tpi.h:323
ut16 parm_count
Definition: tpi.h:324
RzPdbTpiCallingConvention call_conv
Definition: tpi.h:322
ut32 arglist
Definition: tpi.h:325
st32 this_adjust
Definition: tpi.h:326
Tpi_Type_String name
Definition: tpi.h:540
TpiCVFldattr fldattr
Definition: tpi.h:537
Tpi_Type_Numeric offset
Definition: tpi.h:539
ut32 index
Definition: tpi.h:538
RzList * members
Definition: tpi.h:533
ut32 mlist
Definition: tpi.h:520
ut16 count
Definition: tpi.h:519
Tpi_Type_String name
Definition: tpi.h:521
ut32 modified_type
Definition: tpi.h:346
TpiCVModifier umodifier
Definition: tpi.h:347
ut32 index
Definition: tpi.h:509
ut16 pad
Definition: tpi.h:508
Tpi_Type_String name
Definition: tpi.h:510
ut32 index
Definition: tpi.h:559
Tpi_Type_String name
Definition: tpi.h:561
ut32 offset_in_vtable
Definition: tpi.h:560
TpiCVFldattr fldattr
Definition: tpi.h:558
TpiCVPointerAttr ptr_attr
Definition: tpi.h:410
struct Tpi_LF_Pointer::@212::@215 pbase
ut32 utype
Definition: tpi.h:409
struct Tpi_LF_Pointer::@212::@214 pmember
char * type
Definition: tpi.h:586
Tpi_Type_String name
Definition: tpi.h:547
TpiCVFldattr fldattr
Definition: tpi.h:545
ut32 field_list
Definition: tpi.h:457
TpiCVProperty prop
Definition: tpi.h:455
Tpi_Type_String mangled_name
Definition: tpi.h:463
Tpi_Type_Numeric size
Definition: tpi.h:461
Tpi_Type_String name
Definition: tpi.h:462
Tpi_Type_Numeric unknown1
Definition: tpi.h:460
Tpi_Type_Numeric size
Definition: tpi.h:448
ut16 count
Definition: tpi.h:443
ut32 vshape
Definition: tpi.h:447
Tpi_Type_String name
Definition: tpi.h:449
ut32 field_list
Definition: tpi.h:445
Tpi_Type_String mangled_name
Definition: tpi.h:450
ut32 derived
Definition: tpi.h:446
TpiCVProperty prop
Definition: tpi.h:444
ut16 count
Definition: tpi.h:468
TpiCVProperty prop
Definition: tpi.h:469
ut32 field_list
Definition: tpi.h:470
Tpi_Type_String name
Definition: tpi.h:472
Tpi_Type_String mangled_name
Definition: tpi.h:473
Tpi_Type_Numeric size
Definition: tpi.h:471
TpiCVFldattr fldattr
Definition: tpi.h:573
ut32 direct_vbclass_idx
Definition: tpi.h:574
Tpi_Type_Numeric vb_pointer_offset
Definition: tpi.h:576
Tpi_Type_Numeric vb_offset_from_vbtable
Definition: tpi.h:577
ut32 vb_pointer_idx
Definition: tpi.h:575
ut32 index
Definition: tpi.h:515
ut16 pad
Definition: tpi.h:514
char * vt_descriptors
Definition: tpi.h:486
ut16 count
Definition: tpi.h:485
TpiCVFldattr fldattr
Definition: tpi.h:526
void * data
Definition: tpi.h:430
bool is_integer
Definition: tpi.h:431
ut16 type_index
Definition: tpi.h:429
char * name
Definition: tpi.h:424
RzPdbTpiStream * s_tpi
Definition: rz_pdb.h:247
ut16 leaf_type
Definition: rz_pdb.h:147
void * type_data
Definition: rz_pdb.h:149
struct Proc * proc
static Tpi_LF_Bitfield * parse_type_bitfield(RzBuffer *buf, ut16 len)
Definition: tpi.c:1664
static Tpi_LF_VBClass * parse_type_vbclass(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:1078
RZ_API ut64 rz_bin_pdb_get_type_val(RZ_NONNULL RzPdbTpiType *type)
Get the numeric value inside the type.
Definition: tpi.c:507
static void free_tpi_type(void *type_info)
Definition: tpi.c:569
static bool is_simple_type(RzPdbTpiStream *stream, ut32 idx)
Definition: tpi.c:7
static void parse_codeview_modifier(TpiCVModifier *m, ut16 value)
Definition: tpi.c:130
static Tpi_LF_Arglist * parse_type_arglist(RzBuffer *buf, ut16 len)
Definition: tpi.c:1439
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
static Tpi_LF_Enum * parse_type_enum(RzBuffer *buf, ut16 len)
Definition: tpi.c:1197
static void free_tpi_rbtree(RBNode *node, void *user)
Definition: tpi.c:699
static Tpi_LF_BClass * parse_type_bclass(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:1046
static Tpi_LF_Union * parse_type_union(RzBuffer *buf, ut16 len)
Definition: tpi.c:1622
RZ_IPI bool parse_tpi_stream(RzPdb *pdb, RzPdbMsfStream *stream)
Definition: tpi.c:1799
static void parse_codeview_pointer_attribute(TpiCVPointerAttr *p, ut32 value)
Definition: tpi.c:115
static Tpi_LF_NestType * parse_type_nesttype(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:898
static bool parse_type_numeric(RzBuffer *buf, Tpi_Type_Numeric *numeric, ut16 *read_len)
Definition: tpi.c:746
static Tpi_LF_FieldList * parse_type_fieldlist(RzBuffer *buf, ut16 len)
Definition: tpi.c:1119
static Tpi_LF_OneMethod * parse_type_onemethod(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:1015
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
static Tpi_LF_Structure * parse_type_struct(RzBuffer *buf, ut16 len)
Definition: tpi.c:1234
static Tpi_LF_Structure_19 * parse_type_struct_19(RzBuffer *buf, ut16 len)
Definition: tpi.c:1286
static Tpi_LF_Modifier * parse_type_modifier(RzBuffer *buf, ut16 len)
Definition: tpi.c:1416
static bool parse_tpi_types(RzBuffer *buf, RzPdbTpiType *type)
Definition: tpi.c:1715
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
static Tpi_LF_MFcuntion * parse_type_mfunction(RzBuffer *buf, ut16 len)
Definition: tpi.c:1470
RZ_IPI void free_tpi_stream(RzPdbTpiStream *stream)
Definition: tpi.c:705
static Tpi_LF_Vtshape * parse_type_vtshape(RzBuffer *buf, ut16 len)
Definition: tpi.c:1690
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
static Tpi_LF_Method * parse_type_method(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:938
static bool parse_tpi_stream_header(RzPdbTpiStream *s, RzBuffer *buf)
Definition: tpi.c:1777
static Tpi_LF_Enumerate * parse_type_enumerate(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:848
static void skip_padding(RzBuffer *buf, ut16 len, ut16 *read_len, bool has_length)
Definition: tpi.c:714
static Tpi_LF_MethodList * parse_type_methodlist(RzBuffer *buf, ut16 len)
Definition: tpi.c:1523
static ut64 get_numeric_val(Tpi_Type_Numeric *numeric)
Definition: tpi.c:343
static TpiSimpleTypeKind get_simple_type_kind(ut32 type)
Definition: tpi.c:72
static Tpi_LF_StaticMember * parse_type_staticmember(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:992
static Tpi_LF_Procedure * parse_type_procedure(RzBuffer *buf, ut16 len)
Definition: tpi.c:1584
static Tpi_LF_Member * parse_type_member(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:959
static TpiSimpleTypeMode get_simple_type_mode(ut32 type)
Definition: tpi.c:61
static void parse_codeview_func_attribute(TpiCVFuncattr *f, ut8 value)
Definition: tpi.c:109
int tpi_type_node_cmp(const void *incoming, const RBNode *in_tree, void *user)
Definition: tpi.c:19
static Tpi_LF_Pointer * parse_type_pointer(RzBuffer *buf, ut16 len)
Definition: tpi.c:1342
static Tpi_LF_VFuncTab * parse_type_vfunctab(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:919
static Tpi_LF_Index * parse_type_index(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:876
RZ_API bool rz_bin_pdb_type_is_fwdref(RZ_NONNULL RzPdbTpiType *t)
Return true if type is forward definition.
Definition: tpi.c:372
static bool has_non_padding(RzBuffer *buf, ut16 len, ut16 *read_len)
Definition: tpi.c:731
static Tpi_LF_Array * parse_type_array(RzBuffer *buf, ut16 len)
Definition: tpi.c:1384
static void free_snumeric(Tpi_Type_Numeric *numeric)
Definition: tpi.c:549
static void parse_type_string(RzBuffer *buf, Tpi_Type_String *str, ut16 len, ut16 *read_len)
Definition: tpi.c:824
static void parse_codeview_fld_attribute(TpiCVFldattr *f, ut16 value)
Definition: tpi.c:99
RZ_IPI RzPdbTpiType * parse_simple_type(RzPdbTpiStream *stream, ut32 idx)
Parses simple type if the idx represents one.
Definition: tpi.c:142
static void parse_codeview_property(TpiCVProperty *p, ut16 value)
Definition: tpi.c:82
@ PTR_MODE_PMEM
Definition: tpi.h:354
@ PTR_MODE_PMFUNC
Definition: tpi.h:355
TpiSimpleTypeKind
Definition: tpi.h:20
@ PDB_INT128_OCT
Definition: tpi.h:47
@ PDB_VOID
Definition: tpi.h:22
@ PDB_NONE
Definition: tpi.h:21
@ PDB_UINT16
Definition: tpi.h:38
@ PDB_INT128
Definition: tpi.h:49
@ PDB_BYTE
Definition: tpi.h:34
@ PDB_FLOAT64
Definition: tpi.h:56
@ PDB_COMPLEX16
Definition: tpi.h:60
@ PDB_BOOL128
Definition: tpi.h:72
@ PDB_BOOL32
Definition: tpi.h:70
@ PDB_COMPLEX80
Definition: tpi.h:65
@ PDB_UINT128
Definition: tpi.h:50
@ PDB_COMPLEX32
Definition: tpi.h:61
@ PDB_FLOAT48
Definition: tpi.h:55
@ PDB_UINT64_QUAD
Definition: tpi.h:44
@ PDB_INT16_SHORT
Definition: tpi.h:35
@ PDB_BOOL16
Definition: tpi.h:69
@ PDB_NARROW_CHAR
Definition: tpi.h:28
@ PDB_BOOL64
Definition: tpi.h:71
@ PDB_COMPLEX48
Definition: tpi.h:63
@ PDB_CHAR32
Definition: tpi.h:31
@ PDB_COMPLEX64
Definition: tpi.h:64
@ PDB_COMPLEX32_PP
Definition: tpi.h:62
@ PDB_CHAR16
Definition: tpi.h:30
@ PDB_BOOL8
Definition: tpi.h:68
@ PDB_UINT32_LONG
Definition: tpi.h:40
@ PDB_INT64
Definition: tpi.h:45
@ PDB_FLOAT32_PP
Definition: tpi.h:54
@ PDB_UINT64
Definition: tpi.h:46
@ PDB_UNSIGNED_CHAR
Definition: tpi.h:27
@ PDB_COMPLEX128
Definition: tpi.h:66
@ PDB_SIGNED_CHAR
Definition: tpi.h:26
@ PDB_FLOAT80
Definition: tpi.h:57
@ PDB_WIDE_CHAR
Definition: tpi.h:29
@ PDB_INT32_LONG
Definition: tpi.h:39
@ PDB_SBYTE
Definition: tpi.h:33
@ PDB_UINT16_SHORT
Definition: tpi.h:36
@ PDB_INT32
Definition: tpi.h:41
@ PDB_FLOAT32
Definition: tpi.h:53
@ PDB_FLOAT16
Definition: tpi.h:52
@ PDB_UINT32
Definition: tpi.h:42
@ PDB_UINT128_OCT
Definition: tpi.h:48
@ PDB_INT64_QUAD
Definition: tpi.h:43
@ PDB_FLOAT128
Definition: tpi.h:58
@ PDB_INT16
Definition: tpi.h:37
TpiSimpleTypeMode
Definition: tpi.h:9
@ NEAR_POINTER64
Definition: tpi.h:16
@ NEAR_POINTER
Definition: tpi.h:11
@ HUGE_POINTER
Definition: tpi.h:13
@ FAR_POINTER
Definition: tpi.h:12
@ FAR_POINTER32
Definition: tpi.h:15
@ NEAR_POINTER32
Definition: tpi.h:14
@ NEAR_POINTER128
Definition: tpi.h:17
@ LF_NESTTYPE
Definition: tpi.h:186
@ LF_MEMBER
Definition: tpi.h:183
@ LF_METHOD
Definition: tpi.h:185
@ LF_ULONG
Definition: tpi.h:212
@ LF_STRUCTURE_19
Definition: tpi.h:200
@ LF_ONEMETHOD
Definition: tpi.h:187
@ LF_BCLASS
Definition: tpi.h:154
@ LF_METHODLIST
Definition: tpi.h:149
@ LF_SIMPLE_TYPE
Definition: tpi.h:246
@ LF_CHAR
Definition: tpi.h:208
@ LF_USHORT
Definition: tpi.h:210
@ LF_PROCEDURE
Definition: tpi.h:133
@ LF_POINTER
Definition: tpi.h:127
@ LF_IVBCLASS
Definition: tpi.h:156
@ LF_VBCLASS
Definition: tpi.h:155
@ LF_QUADWORD
Definition: tpi.h:217
@ LF_CLASS
Definition: tpi.h:174
@ LF_LONG
Definition: tpi.h:211
@ LF_MODIFIER
Definition: tpi.h:126
@ LF_ENUMERATE
Definition: tpi.h:172
@ LF_STMEMBER
Definition: tpi.h:184
@ LF_MFUNCTION
Definition: tpi.h:134
@ LF_UNION
Definition: tpi.h:176
@ LF_STRUCTURE
Definition: tpi.h:175
@ LF_ARGLIST
Definition: tpi.h:144
@ LF_VTSHAPE
Definition: tpi.h:85
@ LF_INDEX
Definition: tpi.h:158
@ LF_ARRAY
Definition: tpi.h:173
@ LF_CLASS_19
Definition: tpi.h:199
@ LF_BITFIELD
Definition: tpi.h:148
@ LF_SHORT
Definition: tpi.h:209
@ LF_UQUADWORD
Definition: tpi.h:218
@ LF_FIELDLIST
Definition: tpi.h:146
@ LF_ENUM
Definition: tpi.h:177
@ LF_VFUNCTAB
Definition: tpi.h:163
@ MTpureintro
Definition: tpi.h:276
@ MTintro
Definition: tpi.h:274
@ PTR_BASE_TYPE
Definition: tpi.h:382
struct TpiCVFldattr::@209 bits
ut16 mprop
Definition: tpi.h:290
ut32 ptrtype
Definition: tpi.h:393
ut32 ptrmode
Definition: tpi.h:394
struct TpiCVPointerAttr::@211 bits
struct TpiCVProperty::@208 bits
ut16 fwdref
Definition: tpi.h:259
void error(const char *msg)
Definition: untgz.c:593
ut64(WINAPI *w32_GetEnabledXStateFeatures)()