Rizin
unix-like reverse engineering framework and cli tools
rtti_itanium.c File Reference
#include <rz_analysis.h>
#include <rz_core.h>
#include <rz_flag.h>
#include <rz_cons.h>
#include <rz_cmd.h>

Go to the source code of this file.

Classes

struct  class_type_info_t
 
struct  base_class_type_info_t
 
struct  si_class_type_info_t
 
struct  vmi_class_type_info_t
 

Macros

#define VMI_CLASS_TYPE_INFO_NAME   "__vmi_class_type_info"
 
#define SI_CLASS_TYPE_INFO_NAME   "__si_class_type_info"
 
#define CLASS_TYPE_INFO_NAME   "__class_type_info"
 
#define NAME_BUF_SIZE   256
 
#define VT_WORD_SIZE(ctx)    (ctx->word_size)
 

Typedefs

typedef struct class_type_info_t class_type_info
 
typedef struct base_class_type_info_t base_class_type_info
 
typedef struct si_class_type_info_t si_class_type_info
 
typedef struct vmi_class_type_info_t vmi_class_type_info
 

Enumerations

enum  RTypeInfoType { RZ_TYPEINFO_TYPE_UNKNOWN , RZ_TYPEINFO_TYPE_CLASS , RZ_TYPEINFO_TYPE_SI_CLASS , RZ_TYPEINFO_TYPE_VMI_CLASS }
 

Functions

static bool rtti_itanium_read_type_name (RVTableContext *context, ut64 addr, class_type_info *cti)
 
static char * rtti_itanium_read_type_name_custom (RVTableContext *context, ut64 addr, ut64 *str_addr, bool *unique_name)
 
static void rtti_itanium_class_type_info_fini (class_type_info *cti)
 
static void rtti_itanium_class_type_info_free (class_type_info *cti)
 
static bool rtti_itanium_class_type_info_init (RVTableContext *context, ut64 addr, class_type_info *cti)
 
static class_type_infortti_itanium_class_type_info_new (RVTableContext *context, ut64 addr, ut64 source_vtable)
 
static void rtti_itanium_vmi_class_type_info_fini (vmi_class_type_info *vmi_cti)
 
static void rtti_itanium_vmi_class_type_info_free (vmi_class_type_info *cti)
 
static bool rtti_itanium_vmi_class_type_info_init (RVTableContext *context, ut64 addr, vmi_class_type_info *vmi_cti)
 
static vmi_class_type_infortti_itanium_vmi_class_type_info_new (RVTableContext *context, ut64 addr, ut64 source_vtable)
 
static void rtti_itanium_si_class_type_info_fini (si_class_type_info *si_cti)
 
static void rtti_itanium_si_class_type_info_free (si_class_type_info *cti)
 
static bool rtti_itanium_si_class_type_info_init (RVTableContext *context, ut64 addr, si_class_type_info *si_cti)
 
static si_class_type_infortti_itanium_si_class_type_info_new (RVTableContext *context, ut64 addr, ut64 source_vtable)
 
static const char * type_to_string (RTypeInfoType type)
 
static void rtti_itanium_print_class_type_info (class_type_info *cti, const char *prefix)
 
static void rtti_itanium_print_class_type_info_json (class_type_info *cti)
 
static void rtti_itanium_print_vmi_class_type_info (vmi_class_type_info *vmi_cti, const char *prefix)
 
static void rtti_itanium_print_vmi_class_type_info_json (vmi_class_type_info *vmi_cti)
 
static void rtti_itanium_print_si_class_type_info (si_class_type_info *si_cti, const char *prefix)
 
static void rtti_itanium_print_si_class_type_info_json (si_class_type_info *si_cti)
 
static RTypeInfoType rtti_itanium_type_info_type_from_flag (RVTableContext *context, ut64 atAddress)
 
static bool can_section_contain_rtti_vpointer (RzBinSection *section)
 
static class_type_infocreate_class_type (ut64 vtable_addr, char *name, ut64 name_addr, bool unique_name, ut64 typeinfo_addr, ut64 source_vtable)
 
static si_class_type_infocreate_si_class_type (ut64 vtable_addr, char *name, ut64 name_addr, bool unique_name, ut64 basetype_addr, ut64 typeinfo_addr, ut64 source_vtable)
 
static vmi_class_type_infocreate_vmi_class_type (ut64 vtable_addr, char *name, ut64 name_addr, bool unique_name, ut32 flags, ut32 base_count, base_class_type_info *bases, ut64 typeinfo_addr, ut64 source_vtable)
 
static class_type_inforaw_rtti_parse (RVTableContext *context, ut64 vtable_addr, ut64 rtti_addr)
 Try to parse as much valid looking RTTI as you can. More...
 
static class_type_infortti_itanium_type_info_new (RVTableContext *context, ut64 vtable_addr)
 
static void rtti_itanium_type_info_free (void *info)
 
RZ_API bool rz_analysis_rtti_itanium_print_at_vtable (RVTableContext *context, ut64 addr, RzOutputMode mode)
 
RZ_API char * rz_analysis_rtti_itanium_demangle_class_name (RVTableContext *context, const char *name)
 
static void recovery_apply_vtable (RVTableContext *context, const char *class_name, RVTableInfo *vtable_info)
 
static void add_class_bases (RVTableContext *context, const class_type_info *cti)
 Add any base class information about the type into analysis/classes. More...
 
static void detect_constructor_destructor (RzAnalysis *analysis, class_type_info *cti)
 
RZ_API void rz_analysis_rtti_itanium_recover_all (RVTableContext *context, RzList *vtables)
 

Macro Definition Documentation

◆ CLASS_TYPE_INFO_NAME

#define CLASS_TYPE_INFO_NAME   "__class_type_info"

Definition at line 13 of file rtti_itanium.c.

◆ NAME_BUF_SIZE

#define NAME_BUF_SIZE   256

Definition at line 14 of file rtti_itanium.c.

◆ SI_CLASS_TYPE_INFO_NAME

#define SI_CLASS_TYPE_INFO_NAME   "__si_class_type_info"

Definition at line 12 of file rtti_itanium.c.

◆ VMI_CLASS_TYPE_INFO_NAME

#define VMI_CLASS_TYPE_INFO_NAME   "__vmi_class_type_info"

Definition at line 11 of file rtti_itanium.c.

◆ VT_WORD_SIZE

#define VT_WORD_SIZE (   ctx)     (ctx->word_size)

Definition at line 16 of file rtti_itanium.c.

Typedef Documentation

◆ base_class_type_info

◆ class_type_info

◆ si_class_type_info

◆ vmi_class_type_info

Enumeration Type Documentation

◆ RTypeInfoType

Enumerator
RZ_TYPEINFO_TYPE_UNKNOWN 
RZ_TYPEINFO_TYPE_CLASS 
RZ_TYPEINFO_TYPE_SI_CLASS 
RZ_TYPEINFO_TYPE_VMI_CLASS 

Definition at line 19 of file rtti_itanium.c.

19  {
RTypeInfoType
Definition: rtti_itanium.c:19
@ RZ_TYPEINFO_TYPE_SI_CLASS
Definition: rtti_itanium.c:22
@ RZ_TYPEINFO_TYPE_CLASS
Definition: rtti_itanium.c:21
@ RZ_TYPEINFO_TYPE_VMI_CLASS
Definition: rtti_itanium.c:23
@ RZ_TYPEINFO_TYPE_UNKNOWN
Definition: rtti_itanium.c:20

Function Documentation

◆ add_class_bases()

static void add_class_bases ( RVTableContext *  context,
const class_type_info cti 
)
static

Add any base class information about the type into analysis/classes.

Parameters
context
cti

Definition at line 805 of file rtti_itanium.c.

805  {
806  class_type_info base_info;
807  int i;
808 
809  switch (cti->type) {
811  si_class_type_info *si_class = (void *)cti;
812  ut64 base_addr = si_class->base_class_addr;
813  base_addr += VT_WORD_SIZE(context); // offset to name
814  if (rtti_itanium_read_type_name(context, base_addr, &base_info)) {
815  // TODO in future, store the RTTI offset from vtable and use it
816  RzAnalysisBaseClass base = { .class_name = base_info.name, .offset = 0 };
817  rz_analysis_class_base_set(context->analysis, cti->name, &base);
819  }
820  } break;
822  vmi_class_type_info *vmi_class = (void *)cti;
823  for (i = 0; i < vmi_class->vmi_base_count; i++) {
824  base_class_type_info *base_class_info = vmi_class->vmi_bases + i;
825  ut64 base_addr = base_class_info->base_class_addr + VT_WORD_SIZE(context); // offset to name
826  if (rtti_itanium_read_type_name(context, base_addr, &base_info)) {
827  // TODO in future, store the RTTI offset from vtable and use it
828  RzAnalysisBaseClass base = { .class_name = base_info.name, .offset = 0 };
829  rz_analysis_class_base_set(context->analysis, cti->name, &base);
831  }
832  }
833  } break;
834  default: // other types have no parent classes
835  break;
836  }
837 }
lzma_index ** i
Definition: index.h:629
RZ_API RzAnalysisClassErr rz_analysis_class_base_set(RzAnalysis *analysis, const char *class_name, RzAnalysisBaseClass *base)
Definition: class.c:983
RZ_API void rz_analysis_class_base_fini(RzAnalysisBaseClass *base)
Definition: class.c:880
static bool rtti_itanium_read_type_name(RVTableContext *context, ut64 addr, class_type_info *cti)
Definition: rtti_itanium.c:75
#define VT_WORD_SIZE(ctx)
Definition: rtti_itanium.c:16
RTypeInfoType type
Definition: rtti_itanium.c:27
base_class_type_info * vmi_bases
Definition: rtti_itanium.c:66
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References base_class_type_info_t::base_class_addr, si_class_type_info_t::base_class_addr, i, class_type_info_t::name, rtti_itanium_read_type_name(), rz_analysis_class_base_fini(), rz_analysis_class_base_set(), RZ_TYPEINFO_TYPE_SI_CLASS, RZ_TYPEINFO_TYPE_VMI_CLASS, class_type_info_t::type, ut64(), vmi_class_type_info_t::vmi_base_count, vmi_class_type_info_t::vmi_bases, and VT_WORD_SIZE.

Referenced by rz_analysis_rtti_itanium_recover_all().

◆ can_section_contain_rtti_vpointer()

static bool can_section_contain_rtti_vpointer ( RzBinSection section)
static

Definition at line 474 of file rtti_itanium.c.

474  {
475  if (!section) {
476  return false;
477  }
478  if (section->is_data) {
479  return true;
480  }
481  return !strcmp(section->name, ".data.rel.ro") ||
482  !strcmp(section->name, ".data.rel.ro.local") ||
483  rz_str_endswith(section->name, "__const");
484 }
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
Definition: str.c:3329

References rz_str_endswith().

Referenced by raw_rtti_parse().

◆ create_class_type()

static class_type_info* create_class_type ( ut64  vtable_addr,
char *  name,
ut64  name_addr,
bool  unique_name,
ut64  typeinfo_addr,
ut64  source_vtable 
)
static

Definition at line 486 of file rtti_itanium.c.

486  {
488  if (!result) {
489  return NULL;
490  }
491  result->type = RZ_TYPEINFO_TYPE_CLASS;
492 
493  result->vtable_addr = vtable_addr;
494  result->name_addr = name_addr;
495  result->name = name;
496  result->name_unique = unique_name;
497  result->typeinfo_addr = typeinfo_addr;
498  result->class_vtable_addr = source_vtable;
499  return result;
500 }
#define NULL
Definition: cris-opc.c:27
const char * name
Definition: op.c:541
#define RZ_NEW0(x)
Definition: rz_types.h:284

References class_type_info_t::class_vtable_addr, name, class_type_info_t::name, class_type_info_t::name_addr, class_type_info_t::name_unique, NULL, RZ_NEW0, RZ_TYPEINFO_TYPE_CLASS, class_type_info_t::type, class_type_info_t::typeinfo_addr, and class_type_info_t::vtable_addr.

Referenced by raw_rtti_parse().

◆ create_si_class_type()

static si_class_type_info* create_si_class_type ( ut64  vtable_addr,
char *  name,
ut64  name_addr,
bool  unique_name,
ut64  basetype_addr,
ut64  typeinfo_addr,
ut64  source_vtable 
)
static

Definition at line 502 of file rtti_itanium.c.

502  {
504  if (!result) {
505  return NULL;
506  }
508  result->base_class_addr = basetype_addr;
509  result->vtable_addr = vtable_addr;
510  result->name_addr = name_addr;
511  result->name = name;
512  result->name_unique = unique_name;
513  result->typeinfo_addr = typeinfo_addr;
514  result->class_vtable_addr = source_vtable;
515  return result;
516 }
RTypeInfoType type
Definition: rtti_itanium.c:46

References si_class_type_info_t::base_class_addr, si_class_type_info_t::class_vtable_addr, name, si_class_type_info_t::name, si_class_type_info_t::name_addr, si_class_type_info_t::name_unique, NULL, RZ_NEW0, RZ_TYPEINFO_TYPE_SI_CLASS, si_class_type_info_t::type, si_class_type_info_t::typeinfo_addr, and si_class_type_info_t::vtable_addr.

Referenced by raw_rtti_parse().

◆ create_vmi_class_type()

static vmi_class_type_info* create_vmi_class_type ( ut64  vtable_addr,
char *  name,
ut64  name_addr,
bool  unique_name,
ut32  flags,
ut32  base_count,
base_class_type_info bases,
ut64  typeinfo_addr,
ut64  source_vtable 
)
static

Definition at line 518 of file rtti_itanium.c.

518  {
520  if (!result) {
521  return NULL;
522  }
524  result->vmi_bases = bases;
525  result->vmi_base_count = base_count;
526  result->vmi_flags = flags;
527  result->vtable_addr = vtable_addr;
528  result->name_addr = name_addr;
529  result->name = name;
530  result->name_unique = unique_name;
531  result->typeinfo_addr = typeinfo_addr;
532  result->class_vtable_addr = source_vtable;
533  return result;
534 }
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
RTypeInfoType type
Definition: rtti_itanium.c:57

References vmi_class_type_info_t::class_vtable_addr, flags, name, vmi_class_type_info_t::name, vmi_class_type_info_t::name_addr, vmi_class_type_info_t::name_unique, NULL, RZ_NEW0, RZ_TYPEINFO_TYPE_VMI_CLASS, vmi_class_type_info_t::type, vmi_class_type_info_t::typeinfo_addr, vmi_class_type_info_t::vmi_base_count, vmi_class_type_info_t::vmi_bases, vmi_class_type_info_t::vmi_flags, and vmi_class_type_info_t::vtable_addr.

Referenced by raw_rtti_parse().

◆ detect_constructor_destructor()

static void detect_constructor_destructor ( RzAnalysis analysis,
class_type_info cti 
)
static

Definition at line 839 of file rtti_itanium.c.

839  {
840  RzVector *vec = rz_analysis_class_method_get_all(analysis, cti->name);
841  RzAnalysisMethod *meth;
842  rz_vector_foreach(vec, meth) {
843  if (!rz_str_cmp(meth->real_name, cti->name, -1)) {
844  meth->method_type = RZ_ANALYSIS_CLASS_METHOD_CONSTRUCTOR;
845  rz_analysis_class_method_set(analysis, cti->name, meth);
846  continue;
847  } else if (rz_str_startswith(meth->real_name, "~") && !rz_str_cmp(meth->real_name + 1, cti->name, -1)) {
848  if (meth->method_type == RZ_ANALYSIS_CLASS_METHOD_VIRTUAL) {
849  meth->method_type = RZ_ANALYSIS_CLASS_METHOD_VIRTUAL_DESTRUCTOR;
850  } else {
851  meth->method_type = RZ_ANALYSIS_CLASS_METHOD_DESTRUCTOR;
852  }
853  rz_analysis_class_method_set(analysis, cti->name, meth);
854  continue;
855  }
856  }
857  rz_vector_free(vec);
858 }
RZ_API RzVector * rz_analysis_class_method_get_all(RzAnalysis *analysis, const char *class_name)
Definition: class.c:735
RZ_API RzAnalysisClassErr rz_analysis_class_method_set(RzAnalysis *analysis, const char *class_name, RzAnalysisMethod *meth)
Definition: class.c:770
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
RZ_API int rz_str_cmp(const char *dst, const char *orig, int len)
Definition: str.c:974
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
RZ_API void rz_vector_free(RzVector *vec)
Definition: vector.c:75

References class_type_info_t::name, rz_analysis_class_method_get_all(), rz_analysis_class_method_set(), rz_str_cmp(), rz_str_startswith(), rz_vector_foreach, and rz_vector_free().

Referenced by rz_analysis_rtti_itanium_recover_all().

◆ raw_rtti_parse()

static class_type_info* raw_rtti_parse ( RVTableContext *  context,
ut64  vtable_addr,
ut64  rtti_addr 
)
static

Try to parse as much valid looking RTTI as you can.

Parameters
context
vtable_addr
rtti_addr
Returns
class_type_info* NULL if not even default class RTTI could be parsed or error

Definition at line 544 of file rtti_itanium.c.

544  {
545  /*
546  rtti_ptr -----> | vptr |
547  |--------------------------------------|
548  | type_name |
549  |--------------------------------------| --- enough for __class_type_info
550  | __class_type_info *base_type |
551  |--------------------------------------| --- enough for __si_class_type_info
552  | uint flags | --- must be atleast 16bits, it's 32 bit for 64-bit Itanium ABI
553  |--------------------------------------|
554  | uint base_count |
555  |--------------------------------------|
556  | __base_class_type_info base_info[] |
557  |--------------------------------------|
558  |--------- ARRAY --------|
559  |-----__class_type_info *base_type-----|
560  |--------- long __offset_flags --------| ----- enough for __vmi_class_type_info
561  */
562  ut64 rtti_vptr = 0;
563  ut64 addr = rtti_addr;
564  if (!context->read_addr(context->analysis, addr, &rtti_vptr)) {
565  return NULL;
566  }
567  RzBinSection *rtti_section = context->analysis->binb.get_vsect_at(context->analysis->binb.bin, rtti_vptr);
568  if (rtti_vptr && !can_section_contain_rtti_vpointer(rtti_section)) {
569  ;
570  ;
571  ; // Right now ignore, seems that some binaries have some weird values inside there....
572  }
573  addr += VT_WORD_SIZE(context); // Move to the next member
574 
575  ut64 name_addr = 0;
576  bool name_unique = false;
577  char *type_name = rtti_itanium_read_type_name_custom(context, addr, &name_addr, &name_unique);
578  if (!type_name) {
579  return NULL;
580  }
581 
582  addr += VT_WORD_SIZE(context); // Move to the next member
583 
584  // Right now we already have atleast __class_type_info;
585 
586  ut64 base_type_rtti = 0;
587  if (!context->read_addr(context->analysis, addr, &base_type_rtti)) {
588  return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
589  }
590 
591  RzBinSection *base_type_rtti_section = context->analysis->binb.get_vsect_at(context->analysis->binb.bin, base_type_rtti);
592  if (can_section_contain_rtti_vpointer(base_type_rtti_section)) {
593  return (class_type_info *)create_si_class_type(rtti_vptr, type_name, name_addr, name_unique, base_type_rtti, rtti_addr, vtable_addr);
594  }
595 
596  // if it's not a valid base_type_rtti ptr, it might be flags for VMI
597  // assume uint are 32bit
598  ut64 integers = 0;
599  if (!context->read_addr(context->analysis, addr, &integers)) {
600  return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
601  }
602  ut32 vmi_flags = integers & 0xffffffff;
603  addr += 0x4;
604  if (!context->read_addr(context->analysis, addr, &integers)) {
605  return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
606  }
607  integers = integers & 0xffffffff;
608  if (integers < 1 || integers > 0xfffff) {
609  return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
610  }
611  ut32 vmi_base_count = integers;
612 
613  base_class_type_info *vmi_bases = calloc(sizeof(base_class_type_info), vmi_base_count);
614  if (!vmi_bases) {
615  return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
616  }
617  ut64 tmp_addr = addr + 0x4;
618 
619  int i;
620  for (i = 0; i < vmi_base_count; i++) {
621  if (!context->read_addr(context->analysis, tmp_addr, &integers)) {
622  free(vmi_bases);
623  return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
624  }
625  vmi_bases[i].base_class_addr = integers;
626  tmp_addr += VT_WORD_SIZE(context);
627  if (!context->read_addr(context->analysis, tmp_addr, &integers)) {
628  free(vmi_bases);
629  return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
630  }
631  vmi_bases[i].flags = integers;
632  tmp_addr += VT_WORD_SIZE(context);
633  }
634  return (class_type_info *)create_vmi_class_type(rtti_vptr, type_name, name_addr, name_unique, vmi_flags, vmi_base_count, vmi_bases, rtti_addr, vtable_addr);
635 }
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static si_class_type_info * create_si_class_type(ut64 vtable_addr, char *name, ut64 name_addr, bool unique_name, ut64 basetype_addr, ut64 typeinfo_addr, ut64 source_vtable)
Definition: rtti_itanium.c:502
static class_type_info * create_class_type(ut64 vtable_addr, char *name, ut64 name_addr, bool unique_name, ut64 typeinfo_addr, ut64 source_vtable)
Definition: rtti_itanium.c:486
static char * rtti_itanium_read_type_name_custom(RVTableContext *context, ut64 addr, ut64 *str_addr, bool *unique_name)
Definition: rtti_itanium.c:97
static vmi_class_type_info * create_vmi_class_type(ut64 vtable_addr, char *name, ut64 name_addr, bool unique_name, ut32 flags, ut32 base_count, base_class_type_info *bases, ut64 typeinfo_addr, ut64 source_vtable)
Definition: rtti_itanium.c:518
static bool can_section_contain_rtti_vpointer(RzBinSection *section)
Definition: rtti_itanium.c:474
static int addr
Definition: z80asm.c:58

References addr, base_class_type_info_t::base_class_addr, calloc(), can_section_contain_rtti_vpointer(), create_class_type(), create_si_class_type(), create_vmi_class_type(), base_class_type_info_t::flags, free(), i, NULL, rtti_itanium_read_type_name_custom(), ut64(), and VT_WORD_SIZE.

Referenced by rtti_itanium_type_info_new().

◆ recovery_apply_vtable()

static void recovery_apply_vtable ( RVTableContext *  context,
const char *  class_name,
RVTableInfo *  vtable_info 
)
static

Definition at line 761 of file rtti_itanium.c.

761  {
762  if (!vtable_info) {
763  return;
764  }
765 
767 
768  RzAnalysisVTable vtable = { .id = NULL, .offset = 0, .size = size, .addr = vtable_info->saddr };
769  rz_analysis_class_vtable_set(context->analysis, class_name, &vtable);
771 
772  RVTableMethodInfo *vmeth;
773  rz_vector_foreach(&vtable_info->methods, vmeth) {
774  RzAnalysisMethod meth;
775  if (!rz_analysis_class_method_exists_by_addr(context->analysis, class_name, vmeth->addr)) {
776  meth.addr = vmeth->addr;
777  meth.vtable_offset = vmeth->vtable_offset;
778  RzAnalysisFunction *fcn = rz_analysis_get_function_at(context->analysis, vmeth->addr);
779  meth.name = fcn ? rz_str_new(fcn->name) : rz_str_newf("virtual_%" PFMT64d, meth.vtable_offset);
780  // Temporarily set as attr name
781  meth.real_name = fcn ? rz_str_new(fcn->name) : rz_str_newf("virtual_%" PFMT64d, meth.vtable_offset);
782  meth.method_type = RZ_ANALYSIS_CLASS_METHOD_VIRTUAL;
783  } else {
784  RzAnalysisMethod exist_meth;
785  if (rz_analysis_class_method_get_by_addr(context->analysis, class_name, vmeth->addr, &exist_meth) == RZ_ANALYSIS_CLASS_ERR_SUCCESS) {
786  meth.addr = vmeth->addr;
787  meth.name = rz_str_new(exist_meth.name);
788  meth.real_name = rz_str_new(exist_meth.real_name);
789  meth.vtable_offset = vmeth->vtable_offset;
790  meth.method_type = RZ_ANALYSIS_CLASS_METHOD_VIRTUAL;
791  rz_analysis_class_method_fini(&exist_meth);
792  }
793  }
794  rz_analysis_class_method_set(context->analysis, class_name, &meth);
796  }
797 }
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
Definition: function.c:184
RZ_API bool rz_analysis_class_method_exists_by_addr(RzAnalysis *analysis, const char *class_name, ut64 addr)
Definition: class.c:643
RZ_API void rz_analysis_class_vtable_fini(RzAnalysisVTable *vtable)
Definition: class.c:1069
RZ_API RzAnalysisClassErr rz_analysis_class_vtable_set(RzAnalysis *analysis, const char *class_name, RzAnalysisVTable *vtable)
Definition: class.c:1153
RZ_API void rz_analysis_class_method_fini(RzAnalysisMethod *meth)
Definition: class.c:606
RZ_API RzAnalysisClassErr rz_analysis_class_method_get_by_addr(RzAnalysis *analysis, const char *class_name, ut64 addr, RzAnalysisMethod *method)
Definition: class.c:659
voidpf void uLong size
Definition: ioapi.h:138
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
#define PFMT64d
Definition: rz_types.h:394
RZ_API ut64 rz_analysis_vtable_info_get_size(RVTableContext *context, RVTableInfo *vtable)
Definition: vtable.c:37

References rz_analysis_function_t::name, NULL, PFMT64d, rz_analysis_class_method_exists_by_addr(), rz_analysis_class_method_fini(), rz_analysis_class_method_get_by_addr(), rz_analysis_class_method_set(), rz_analysis_class_vtable_fini(), rz_analysis_class_vtable_set(), rz_analysis_get_function_at(), rz_analysis_vtable_info_get_size(), rz_str_new(), rz_str_newf(), rz_vector_foreach, and ut64().

Referenced by rz_analysis_rtti_itanium_recover_all().

◆ rtti_itanium_class_type_info_fini()

static void rtti_itanium_class_type_info_fini ( class_type_info cti)
static

Definition at line 116 of file rtti_itanium.c.

116  {
117  if (cti) {
118  free(cti->name);
119  }
120 }

References free(), and class_type_info_t::name.

Referenced by rtti_itanium_class_type_info_free().

◆ rtti_itanium_class_type_info_free()

static void rtti_itanium_class_type_info_free ( class_type_info cti)
static

Definition at line 122 of file rtti_itanium.c.

122  {
123  if (cti == NULL) {
124  return;
125  }
126 
128  free(cti);
129 }
static void rtti_itanium_class_type_info_fini(class_type_info *cti)
Definition: rtti_itanium.c:116

References free(), NULL, and rtti_itanium_class_type_info_fini().

Referenced by rtti_itanium_class_type_info_new(), rtti_itanium_type_info_free(), and rz_analysis_rtti_itanium_print_at_vtable().

◆ rtti_itanium_class_type_info_init()

static bool rtti_itanium_class_type_info_init ( RVTableContext *  context,
ut64  addr,
class_type_info cti 
)
static

Definition at line 131 of file rtti_itanium.c.

131  {
133  ut64 at;
134  if (addr == UT64_MAX) {
135  return false;
136  }
137  if (!context->read_addr(context->analysis, addr, &at)) {
138  return false;
139  }
140  cti->vtable_addr = at;
142 }
#define UT64_MAX
Definition: rz_types_base.h:86

References addr, rtti_itanium_read_type_name(), RZ_TYPEINFO_TYPE_CLASS, class_type_info_t::type, ut64(), UT64_MAX, VT_WORD_SIZE, and class_type_info_t::vtable_addr.

Referenced by rtti_itanium_class_type_info_new().

◆ rtti_itanium_class_type_info_new()

static class_type_info* rtti_itanium_class_type_info_new ( RVTableContext *  context,
ut64  addr,
ut64  source_vtable 
)
static

Definition at line 144 of file rtti_itanium.c.

144  {
146  if (!result) {
147  return NULL;
148  }
149 
152  return NULL;
153  }
154 
155  result->class_vtable_addr = source_vtable;
156  result->typeinfo_addr = addr;
157 
158  return result;
159 }
static bool rtti_itanium_class_type_info_init(RVTableContext *context, ut64 addr, class_type_info *cti)
Definition: rtti_itanium.c:131
static void rtti_itanium_class_type_info_free(class_type_info *cti)
Definition: rtti_itanium.c:122

References addr, class_type_info_t::class_vtable_addr, NULL, rtti_itanium_class_type_info_free(), rtti_itanium_class_type_info_init(), RZ_NEW0, and class_type_info_t::typeinfo_addr.

Referenced by rtti_itanium_type_info_new().

◆ rtti_itanium_print_class_type_info()

static void rtti_itanium_print_class_type_info ( class_type_info cti,
const char *  prefix 
)
static

Definition at line 309 of file rtti_itanium.c.

309  {
310  rz_cons_printf("%sType Info at 0x%08" PFMT64x ":\n"
311  "%s Type Info type: %s\n"
312  "%s Belongs to class vtable: 0x%08" PFMT64x "\n"
313  "%s Reference to RTTI's type class: 0x%08" PFMT64x "\n"
314  "%s Reference to type's name: 0x%08" PFMT64x "\n"
315  "%s Type Name: %s\n"
316  "%s Name unique: %s\n",
317  prefix, cti->typeinfo_addr,
318  prefix, type_to_string(cti->type),
320  prefix, cti->vtable_addr,
321  prefix, cti->name_addr,
322  prefix, cti->name,
323  prefix, cti->name_unique ? "true" : "false");
324 }
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
unsigned short prefix[65536]
Definition: gun.c:163
static const char * type_to_string(RTypeInfoType type)
Definition: rtti_itanium.c:297
#define PFMT64x
Definition: rz_types.h:393

References class_type_info_t::class_vtable_addr, class_type_info_t::name, class_type_info_t::name_addr, class_type_info_t::name_unique, PFMT64x, prefix, rz_cons_printf(), class_type_info_t::type, type_to_string(), class_type_info_t::typeinfo_addr, and class_type_info_t::vtable_addr.

Referenced by rz_analysis_rtti_itanium_print_at_vtable().

◆ rtti_itanium_print_class_type_info_json()

static void rtti_itanium_print_class_type_info_json ( class_type_info cti)
static

Definition at line 326 of file rtti_itanium.c.

326  {
327  PJ *pj = pj_new();
328  if (!pj) {
329  return;
330  }
331 
332  pj_o(pj);
333  pj_ks(pj, "type", type_to_string(cti->type));
334  pj_kn(pj, "found_at", cti->typeinfo_addr);
335  pj_kn(pj, "class_vtable", cti->class_vtable_addr);
336  pj_kn(pj, "ref_to_type_class", cti->vtable_addr);
337  pj_kn(pj, "ref_to_type_name", cti->name_addr);
338  pj_ks(pj, "name", cti->name);
339  pj_kb(pj, "name_unique", cti->name_unique);
340  pj_end(pj);
341 
342  rz_cons_print(pj_string(pj));
343  pj_free(pj);
344 }
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
Definition: pj.c:177
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
Definition: rz_pj.h:12

References class_type_info_t::class_vtable_addr, class_type_info_t::name, class_type_info_t::name_addr, class_type_info_t::name_unique, pj_end(), pj_free(), pj_kb(), pj_kn(), pj_ks(), pj_new(), pj_o(), pj_string(), class_type_info_t::type, type_to_string(), class_type_info_t::typeinfo_addr, and class_type_info_t::vtable_addr.

Referenced by rz_analysis_rtti_itanium_print_at_vtable().

◆ rtti_itanium_print_si_class_type_info()

static void rtti_itanium_print_si_class_type_info ( si_class_type_info si_cti,
const char *  prefix 
)
static

Definition at line 408 of file rtti_itanium.c.

408  {
409  rz_cons_printf("%sType Info at 0x%08" PFMT64x ":\n"
410  "%s Type Info type: %s\n"
411  "%s Belongs to class vtable: 0x%08" PFMT64x "\n"
412  "%s Reference to RTTI's type class: 0x%08" PFMT64x "\n"
413  "%s Reference to type's name: 0x%08" PFMT64x "\n"
414  "%s Type Name: %s\n"
415  "%s Name unique: %s\n"
416  "%s Reference to parent's type info: 0x%08" PFMT64x "\n",
417  prefix, si_cti->typeinfo_addr,
418  prefix, type_to_string(si_cti->type),
419  prefix, si_cti->class_vtable_addr,
420  prefix, si_cti->vtable_addr,
421  prefix, si_cti->name_addr,
422  prefix, si_cti->name,
423  prefix, si_cti->name_unique ? "true" : "false",
424  prefix, si_cti->base_class_addr);
425 }

References si_class_type_info_t::base_class_addr, si_class_type_info_t::class_vtable_addr, si_class_type_info_t::name, si_class_type_info_t::name_addr, si_class_type_info_t::name_unique, PFMT64x, prefix, rz_cons_printf(), si_class_type_info_t::type, type_to_string(), si_class_type_info_t::typeinfo_addr, and si_class_type_info_t::vtable_addr.

Referenced by rz_analysis_rtti_itanium_print_at_vtable().

◆ rtti_itanium_print_si_class_type_info_json()

static void rtti_itanium_print_si_class_type_info_json ( si_class_type_info si_cti)
static

Definition at line 427 of file rtti_itanium.c.

427  {
428  PJ *pj = pj_new();
429  if (!pj) {
430  return;
431  }
432 
433  pj_o(pj);
434  pj_ks(pj, "type", type_to_string(si_cti->type));
435  pj_kn(pj, "found_at", si_cti->typeinfo_addr);
436  pj_kn(pj, "class_vtable", si_cti->class_vtable_addr);
437  pj_kn(pj, "ref_to_type_class", si_cti->vtable_addr);
438  pj_kn(pj, "ref_to_type_name", si_cti->name_addr);
439  pj_ks(pj, "name", si_cti->name);
440  pj_kb(pj, "name_unique", si_cti->name_unique);
441  pj_kn(pj, "ref_to_parent_type", si_cti->base_class_addr);
442  pj_end(pj);
443 
444  rz_cons_print(pj_string(pj));
445  pj_free(pj);
446 }

References si_class_type_info_t::base_class_addr, si_class_type_info_t::class_vtable_addr, si_class_type_info_t::name, si_class_type_info_t::name_addr, si_class_type_info_t::name_unique, pj_end(), pj_free(), pj_kb(), pj_kn(), pj_ks(), pj_new(), pj_o(), pj_string(), si_class_type_info_t::type, type_to_string(), si_class_type_info_t::typeinfo_addr, and si_class_type_info_t::vtable_addr.

Referenced by rz_analysis_rtti_itanium_print_at_vtable().

◆ rtti_itanium_print_vmi_class_type_info()

static void rtti_itanium_print_vmi_class_type_info ( vmi_class_type_info vmi_cti,
const char *  prefix 
)
static

Definition at line 346 of file rtti_itanium.c.

346  {
347  rz_cons_printf("%sType Info at 0x%08" PFMT64x ":\n"
348  "%s Type Info type: %s\n"
349  "%s Belongs to class vtable: 0x%08" PFMT64x "\n"
350  "%s Reference to RTTI's type class: 0x%08" PFMT64x "\n"
351  "%s Reference to type's name: 0x%08" PFMT64x "\n"
352  "%s Type Name: %s\n"
353  "%s Name unique: %s\n"
354  "%s Flags: 0x%x\n"
355  "%s Count of base classes: 0x%x"
356  "\n",
357  prefix, vmi_cti->typeinfo_addr,
358  prefix, type_to_string(vmi_cti->type),
359  prefix, vmi_cti->class_vtable_addr,
360  prefix, vmi_cti->vtable_addr,
361  prefix, vmi_cti->name_addr,
362  prefix, vmi_cti->name,
363  prefix, vmi_cti->name_unique ? "true" : "false",
364  prefix, vmi_cti->vmi_flags,
365  prefix, vmi_cti->vmi_base_count);
366 
367  int i;
368  for (i = 0; i < vmi_cti->vmi_base_count; i++) {
369  rz_cons_printf("%s Base class type descriptor address: 0x%08" PFMT64x "\n"
370  "%s Base class flags: 0x%" PFMT64x
371  "\n",
372  prefix, vmi_cti->vmi_bases[i].base_class_addr,
373  prefix, vmi_cti->vmi_bases[i].flags);
374  }
375 }

References base_class_type_info_t::base_class_addr, vmi_class_type_info_t::class_vtable_addr, base_class_type_info_t::flags, i, vmi_class_type_info_t::name, vmi_class_type_info_t::name_addr, vmi_class_type_info_t::name_unique, PFMT64x, prefix, rz_cons_printf(), vmi_class_type_info_t::type, type_to_string(), vmi_class_type_info_t::typeinfo_addr, vmi_class_type_info_t::vmi_base_count, vmi_class_type_info_t::vmi_bases, vmi_class_type_info_t::vmi_flags, and vmi_class_type_info_t::vtable_addr.

Referenced by rz_analysis_rtti_itanium_print_at_vtable().

◆ rtti_itanium_print_vmi_class_type_info_json()

static void rtti_itanium_print_vmi_class_type_info_json ( vmi_class_type_info vmi_cti)
static

Definition at line 377 of file rtti_itanium.c.

377  {
378  PJ *pj = pj_new();
379  if (!pj) {
380  return;
381  }
382 
383  pj_o(pj);
384  pj_ks(pj, "type", type_to_string(vmi_cti->type));
385  pj_kn(pj, "found_at", vmi_cti->typeinfo_addr);
386  pj_kn(pj, "class_vtable", vmi_cti->class_vtable_addr);
387  pj_kn(pj, "ref_to_type_class", vmi_cti->vtable_addr);
388  pj_kn(pj, "ref_to_type_name", vmi_cti->name_addr);
389  pj_ks(pj, "name", vmi_cti->name);
390  pj_kb(pj, "name_unique", vmi_cti->name_unique);
391  pj_kn(pj, "flags", vmi_cti->vmi_flags);
392  pj_k(pj, "base_classes");
393  pj_a(pj);
394  int i;
395  for (i = 0; i < vmi_cti->vmi_base_count; i++) {
396  pj_o(pj);
397  pj_kn(pj, "type_desc_addr", vmi_cti->vmi_bases[i].base_class_addr);
398  pj_kN(pj, "flags", vmi_cti->vmi_bases[i].flags);
399  pj_end(pj);
400  }
401  pj_end(pj);
402  pj_end(pj);
403 
404  rz_cons_print(pj_string(pj));
405  pj_free(pj);
406 }
RZ_API PJ * pj_k(PJ *j, const char *k)
Definition: pj.c:104
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
Definition: pj.c:128

References base_class_type_info_t::base_class_addr, vmi_class_type_info_t::class_vtable_addr, base_class_type_info_t::flags, i, vmi_class_type_info_t::name, vmi_class_type_info_t::name_addr, vmi_class_type_info_t::name_unique, pj_a(), pj_end(), pj_free(), pj_k(), pj_kb(), pj_kN(), pj_kn(), pj_ks(), pj_new(), pj_o(), pj_string(), vmi_class_type_info_t::type, type_to_string(), vmi_class_type_info_t::typeinfo_addr, vmi_class_type_info_t::vmi_base_count, vmi_class_type_info_t::vmi_bases, vmi_class_type_info_t::vmi_flags, and vmi_class_type_info_t::vtable_addr.

Referenced by rz_analysis_rtti_itanium_print_at_vtable().

◆ rtti_itanium_read_type_name()

static bool rtti_itanium_read_type_name ( RVTableContext *  context,
ut64  addr,
class_type_info cti 
)
static

Definition at line 75 of file rtti_itanium.c.

75  {
76  ut64 at;
77  if (!context->read_addr(context->analysis, addr, &at)) {
78  return false;
79  }
80  ut64 unique_mask = 1ULL << (VT_WORD_SIZE(context) * 8 - 1);
81  cti->name_unique = (at & unique_mask) == 0;
82  at &= ~unique_mask;
83  cti->name_addr = at;
85  if (!context->analysis->iob.read_at(context->analysis->iob.io, at, buf, sizeof(buf))) {
86  return false;
87  }
88  buf[NAME_BUF_SIZE - 1] = 0;
90  if (!cti->name) {
91  return false;
92  }
93  return true;
94 }
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API char * rz_analysis_rtti_itanium_demangle_class_name(RVTableContext *context, const char *name)
Definition: rtti_itanium.c:743
#define NAME_BUF_SIZE
Definition: rtti_itanium.c:14

References addr, class_type_info_t::name, class_type_info_t::name_addr, NAME_BUF_SIZE, class_type_info_t::name_unique, rz_analysis_rtti_itanium_demangle_class_name(), ut64(), and VT_WORD_SIZE.

Referenced by add_class_bases(), rtti_itanium_class_type_info_init(), rtti_itanium_si_class_type_info_init(), and rtti_itanium_vmi_class_type_info_init().

◆ rtti_itanium_read_type_name_custom()

static char* rtti_itanium_read_type_name_custom ( RVTableContext *  context,
ut64  addr,
ut64 str_addr,
bool unique_name 
)
static

Definition at line 97 of file rtti_itanium.c.

97  {
98  ut64 at;
99  if (!context->read_addr(context->analysis, addr, &at)) {
100  return NULL;
101  }
102  ut64 unique_mask = 1ULL << (VT_WORD_SIZE(context) * 8 - 1);
103  *unique_name = (at & unique_mask) == 0;
104  at &= ~unique_mask;
105  *str_addr = at;
107  if (!context->analysis->iob.read_at(context->analysis->iob.io, at, buf, sizeof(buf))) {
108  return NULL;
109  }
110  buf[NAME_BUF_SIZE - 1] = 0;
112 
113  return name;
114 }
Definition: z80asm.h:102

References addr, name, NAME_BUF_SIZE, NULL, rz_analysis_rtti_itanium_demangle_class_name(), ut64(), and VT_WORD_SIZE.

Referenced by raw_rtti_parse().

◆ rtti_itanium_si_class_type_info_fini()

static void rtti_itanium_si_class_type_info_fini ( si_class_type_info si_cti)
static

Definition at line 245 of file rtti_itanium.c.

245  {
246  if (si_cti) {
247  free(si_cti->name);
248  }
249 }

References free(), and si_class_type_info_t::name.

Referenced by rtti_itanium_si_class_type_info_free().

◆ rtti_itanium_si_class_type_info_free()

static void rtti_itanium_si_class_type_info_free ( si_class_type_info cti)
static

Definition at line 251 of file rtti_itanium.c.

251  {
252  if (cti == NULL) {
253  return;
254  }
255 
257  free(cti);
258 }
static void rtti_itanium_si_class_type_info_fini(si_class_type_info *si_cti)
Definition: rtti_itanium.c:245

References free(), NULL, and rtti_itanium_si_class_type_info_fini().

Referenced by rtti_itanium_si_class_type_info_new(), rtti_itanium_type_info_free(), and rz_analysis_rtti_itanium_print_at_vtable().

◆ rtti_itanium_si_class_type_info_init()

static bool rtti_itanium_si_class_type_info_init ( RVTableContext *  context,
ut64  addr,
si_class_type_info si_cti 
)
static

Definition at line 260 of file rtti_itanium.c.

260  {
262  ut64 at;
263  if (addr == UT64_MAX) {
264  return false;
265  }
266  if (!context->read_addr(context->analysis, addr, &at)) {
267  return false;
268  }
269  si_cti->vtable_addr = at;
271  return false;
272  }
273  if (!context->read_addr(context->analysis, addr + 2 * VT_WORD_SIZE(context), &at)) {
274  return false;
275  }
276  si_cti->base_class_addr = at;
277  return true;
278 }

References addr, si_class_type_info_t::base_class_addr, rtti_itanium_read_type_name(), RZ_TYPEINFO_TYPE_SI_CLASS, si_class_type_info_t::type, ut64(), UT64_MAX, VT_WORD_SIZE, and si_class_type_info_t::vtable_addr.

Referenced by rtti_itanium_si_class_type_info_new().

◆ rtti_itanium_si_class_type_info_new()

static si_class_type_info* rtti_itanium_si_class_type_info_new ( RVTableContext *  context,
ut64  addr,
ut64  source_vtable 
)
static

Definition at line 280 of file rtti_itanium.c.

280  {
282  if (!result) {
283  return NULL;
284  }
285 
288  return NULL;
289  }
290 
291  result->class_vtable_addr = source_vtable;
292  result->typeinfo_addr = addr;
293 
294  return result;
295 }
static void rtti_itanium_si_class_type_info_free(si_class_type_info *cti)
Definition: rtti_itanium.c:251
static bool rtti_itanium_si_class_type_info_init(RVTableContext *context, ut64 addr, si_class_type_info *si_cti)
Definition: rtti_itanium.c:260

References addr, si_class_type_info_t::class_vtable_addr, NULL, rtti_itanium_si_class_type_info_free(), rtti_itanium_si_class_type_info_init(), RZ_NEW0, and si_class_type_info_t::typeinfo_addr.

Referenced by rtti_itanium_type_info_new().

◆ rtti_itanium_type_info_free()

static void rtti_itanium_type_info_free ( void *  info)
static

Definition at line 679 of file rtti_itanium.c.

679  {
680  class_type_info *cti = info;
681  if (!cti) {
682  return;
683  }
684 
685  switch (cti->type) {
688  return;
691  return;
694  return;
695  default:
697  }
698 }
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
static void rtti_itanium_vmi_class_type_info_free(vmi_class_type_info *cti)
Definition: rtti_itanium.c:168
#define rz_return_if_reached()
Definition: rz_assert.h:116

References info(), rtti_itanium_class_type_info_free(), rtti_itanium_si_class_type_info_free(), rtti_itanium_vmi_class_type_info_free(), rz_return_if_reached, RZ_TYPEINFO_TYPE_CLASS, RZ_TYPEINFO_TYPE_SI_CLASS, RZ_TYPEINFO_TYPE_VMI_CLASS, and class_type_info_t::type.

Referenced by rz_analysis_rtti_itanium_recover_all().

◆ rtti_itanium_type_info_new()

static class_type_info* rtti_itanium_type_info_new ( RVTableContext *  context,
ut64  vtable_addr 
)
static

Definition at line 637 of file rtti_itanium.c.

637  {
638  /*
639  vpointer - 2 words | offset to top |
640  |---------------|
641  vpointer - word | RTTI pointer |
642  |---------------|
643  vpointer -----> | virt_func_0 |
644  */
645  ut64 rtti_ptr = vtable_addr - VT_WORD_SIZE(context); // RTTI pointer
646  ut64 rtti_addr; // RTTI address
647 
648  if (!context->read_addr(context->analysis, rtti_ptr, &rtti_addr)) {
649  return NULL;
650  }
651 
653  // If there isn't flag telling us the type of TypeInfo
654  // try to find the flag in it's vtable
656  ut64 follow;
657  if (!context->read_addr(context->analysis, rtti_addr, &follow)) {
658  return NULL;
659  }
660  follow -= 2 * context->word_size;
662  }
663 
665  return raw_rtti_parse(context, vtable_addr, rtti_addr);
666  }
667  switch (type) {
669  return (class_type_info *)rtti_itanium_vmi_class_type_info_new(context, rtti_addr, vtable_addr);
671  return (class_type_info *)rtti_itanium_si_class_type_info_new(context, rtti_addr, vtable_addr);
673  return rtti_itanium_class_type_info_new(context, rtti_addr, vtable_addr);
674  default:
676  }
677 }
int type
Definition: mipsasm.c:17
static vmi_class_type_info * rtti_itanium_vmi_class_type_info_new(RVTableContext *context, ut64 addr, ut64 source_vtable)
Definition: rtti_itanium.c:228
static class_type_info * raw_rtti_parse(RVTableContext *context, ut64 vtable_addr, ut64 rtti_addr)
Try to parse as much valid looking RTTI as you can.
Definition: rtti_itanium.c:544
static RTypeInfoType rtti_itanium_type_info_type_from_flag(RVTableContext *context, ut64 atAddress)
Definition: rtti_itanium.c:448
static si_class_type_info * rtti_itanium_si_class_type_info_new(RVTableContext *context, ut64 addr, ut64 source_vtable)
Definition: rtti_itanium.c:280
static class_type_info * rtti_itanium_class_type_info_new(RVTableContext *context, ut64 addr, ut64 source_vtable)
Definition: rtti_itanium.c:144
#define rz_return_val_if_reached(val)
Definition: rz_assert.h:122

References NULL, raw_rtti_parse(), rtti_itanium_class_type_info_new(), rtti_itanium_si_class_type_info_new(), rtti_itanium_type_info_type_from_flag(), rtti_itanium_vmi_class_type_info_new(), rz_return_val_if_reached, RZ_TYPEINFO_TYPE_CLASS, RZ_TYPEINFO_TYPE_SI_CLASS, RZ_TYPEINFO_TYPE_UNKNOWN, RZ_TYPEINFO_TYPE_VMI_CLASS, type, ut64(), and VT_WORD_SIZE.

Referenced by rz_analysis_rtti_itanium_print_at_vtable(), and rz_analysis_rtti_itanium_recover_all().

◆ rtti_itanium_type_info_type_from_flag()

static RTypeInfoType rtti_itanium_type_info_type_from_flag ( RVTableContext *  context,
ut64  atAddress 
)
static

Definition at line 448 of file rtti_itanium.c.

448  {
449  RzCore *core = context->analysis->coreb.core;
451 
452  // get the reloc flags
453  const RzList *flags = context->analysis->flb.get_list(core->flags, atAddress);
454  if (!flags) {
456  }
457 
458  RzListIter *iter;
459  RzFlagItem *flag;
460  rz_list_foreach (flags, iter, flag) {
461  if (strstr(flag->name, VMI_CLASS_TYPE_INFO_NAME)) {
463  } else if (strstr(flag->name, SI_CLASS_TYPE_INFO_NAME)) {
465  } else if (strstr(flag->name, CLASS_TYPE_INFO_NAME)) {
466  return RZ_TYPEINFO_TYPE_CLASS;
467  }
468  }
469 
471 }
#define VMI_CLASS_TYPE_INFO_NAME
Definition: rtti_itanium.c:11
#define SI_CLASS_TYPE_INFO_NAME
Definition: rtti_itanium.c:12
#define CLASS_TYPE_INFO_NAME
Definition: rtti_itanium.c:13
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RzFlag * flags
Definition: rz_core.h:330
char * name
Definition: rz_flag.h:35

References CLASS_TYPE_INFO_NAME, rz_core_t::flags, flags, rz_flag_item_t::name, rz_return_val_if_fail, RZ_TYPEINFO_TYPE_CLASS, RZ_TYPEINFO_TYPE_SI_CLASS, RZ_TYPEINFO_TYPE_UNKNOWN, RZ_TYPEINFO_TYPE_VMI_CLASS, SI_CLASS_TYPE_INFO_NAME, and VMI_CLASS_TYPE_INFO_NAME.

Referenced by rtti_itanium_type_info_new().

◆ rtti_itanium_vmi_class_type_info_fini()

static void rtti_itanium_vmi_class_type_info_fini ( vmi_class_type_info vmi_cti)
static

Definition at line 161 of file rtti_itanium.c.

161  {
162  if (vmi_cti) {
163  free(vmi_cti->vmi_bases);
164  free(vmi_cti->name);
165  }
166 }

References free(), vmi_class_type_info_t::name, and vmi_class_type_info_t::vmi_bases.

Referenced by rtti_itanium_vmi_class_type_info_free().

◆ rtti_itanium_vmi_class_type_info_free()

static void rtti_itanium_vmi_class_type_info_free ( vmi_class_type_info cti)
static

Definition at line 168 of file rtti_itanium.c.

168  {
169  if (cti == NULL) {
170  return;
171  }
172 
174  free(cti);
175 }
static void rtti_itanium_vmi_class_type_info_fini(vmi_class_type_info *vmi_cti)
Definition: rtti_itanium.c:161

References free(), NULL, and rtti_itanium_vmi_class_type_info_fini().

Referenced by rtti_itanium_type_info_free(), rtti_itanium_vmi_class_type_info_new(), and rz_analysis_rtti_itanium_print_at_vtable().

◆ rtti_itanium_vmi_class_type_info_init()

static bool rtti_itanium_vmi_class_type_info_init ( RVTableContext *  context,
ut64  addr,
vmi_class_type_info vmi_cti 
)
static

Definition at line 177 of file rtti_itanium.c.

177  {
178  vmi_cti->type = RZ_TYPEINFO_TYPE_VMI_CLASS;
179  ut64 at;
180  if (addr == UT64_MAX) {
181  return false;
182  }
183  if (!context->read_addr(context->analysis, addr, &at)) {
184  return false;
185  }
186  vmi_cti->vtable_addr = at;
189  return false;
190  }
192  if (!context->read_addr(context->analysis, addr, &at)) {
193  return false;
194  }
195  vmi_cti->vmi_flags = at & 0xffffffff;
196  addr += 0x4;
197  if (!context->read_addr(context->analysis, addr, &at)) {
198  return false;
199  }
200  at = at & 0xffffffff;
201  if (at < 1 || at > 0xfffff) {
202  RZ_LOG_ERROR("Cannot read vmi_base_count\n");
203  return false;
204  }
205  vmi_cti->vmi_base_count = at;
206  vmi_cti->vmi_bases = calloc(sizeof(base_class_type_info), vmi_cti->vmi_base_count);
207  if (!vmi_cti->vmi_bases) {
208  return false;
209  }
210  ut64 tmp_addr = addr + 0x4;
211 
212  int i;
213  for (i = 0; i < vmi_cti->vmi_base_count; i++) {
214  if (!context->read_addr(context->analysis, tmp_addr, &at)) {
215  return false;
216  }
217  vmi_cti->vmi_bases[i].base_class_addr = at;
218  tmp_addr += VT_WORD_SIZE(context);
219  if (!context->read_addr(context->analysis, tmp_addr, &at)) {
220  return false;
221  }
222  vmi_cti->vmi_bases[i].flags = at;
223  tmp_addr += VT_WORD_SIZE(context);
224  }
225  return true;
226 }
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58

References addr, base_class_type_info_t::base_class_addr, calloc(), base_class_type_info_t::flags, i, rtti_itanium_read_type_name(), RZ_LOG_ERROR, RZ_TYPEINFO_TYPE_VMI_CLASS, vmi_class_type_info_t::type, ut64(), UT64_MAX, vmi_class_type_info_t::vmi_base_count, vmi_class_type_info_t::vmi_bases, vmi_class_type_info_t::vmi_flags, VT_WORD_SIZE, and vmi_class_type_info_t::vtable_addr.

Referenced by rtti_itanium_vmi_class_type_info_new().

◆ rtti_itanium_vmi_class_type_info_new()

static vmi_class_type_info* rtti_itanium_vmi_class_type_info_new ( RVTableContext *  context,
ut64  addr,
ut64  source_vtable 
)
static

Definition at line 228 of file rtti_itanium.c.

228  {
230  if (!result) {
231  return NULL;
232  }
233 
236  return NULL;
237  }
238 
239  result->class_vtable_addr = source_vtable;
240  result->typeinfo_addr = addr;
241 
242  return result;
243 }
static bool rtti_itanium_vmi_class_type_info_init(RVTableContext *context, ut64 addr, vmi_class_type_info *vmi_cti)
Definition: rtti_itanium.c:177

References addr, vmi_class_type_info_t::class_vtable_addr, NULL, rtti_itanium_vmi_class_type_info_free(), rtti_itanium_vmi_class_type_info_init(), RZ_NEW0, and vmi_class_type_info_t::typeinfo_addr.

Referenced by rtti_itanium_type_info_new().

◆ rz_analysis_rtti_itanium_demangle_class_name()

RZ_API char* rz_analysis_rtti_itanium_demangle_class_name ( RVTableContext *  context,
const char *  name 
)

Definition at line 743 of file rtti_itanium.c.

743  {
744  if (!name || !*name) {
745  return NULL;
746  }
747 
748  char *result = NULL;
749 
750  if (name[0] != '_') {
751  char *to_demangle = rz_str_newf("_Z%s", name);
752  result = context->analysis->binb.demangle(NULL, "cxx", to_demangle, 0, false);
753  free(to_demangle);
754  } else {
755  result = context->analysis->binb.demangle(NULL, "cxx", name, 0, false);
756  }
757 
758  return result;
759 }

References free(), NULL, and rz_str_newf().

Referenced by rtti_itanium_read_type_name(), rtti_itanium_read_type_name_custom(), and rz_analysis_rtti_demangle_class_name().

◆ rz_analysis_rtti_itanium_print_at_vtable()

RZ_API bool rz_analysis_rtti_itanium_print_at_vtable ( RVTableContext *  context,
ut64  addr,
RzOutputMode  mode 
)

Definition at line 700 of file rtti_itanium.c.

700  {
701  bool use_json = mode == RZ_OUTPUT_MODE_JSON;
703  if (!cti) {
704  return false;
705  }
706 
707  switch (cti->type) {
709  vmi_class_type_info *vmi_cti = (vmi_class_type_info *)cti;
710  if (use_json) {
712  } else {
714  }
716  }
717  return true;
719  si_class_type_info *si_cti = (si_class_type_info *)cti;
720  if (use_json) {
722  } else {
724  }
726  }
727  return true;
728  case RZ_TYPEINFO_TYPE_CLASS: {
729  if (use_json) {
731  } else {
733  }
735  }
736  return true;
737  default:
740  }
741 }
const char int mode
Definition: ioapi.h:137
static void rtti_itanium_print_si_class_type_info(si_class_type_info *si_cti, const char *prefix)
Definition: rtti_itanium.c:408
static void rtti_itanium_print_si_class_type_info_json(si_class_type_info *si_cti)
Definition: rtti_itanium.c:427
static void rtti_itanium_print_class_type_info(class_type_info *cti, const char *prefix)
Definition: rtti_itanium.c:309
static void rtti_itanium_print_class_type_info_json(class_type_info *cti)
Definition: rtti_itanium.c:326
static void rtti_itanium_print_vmi_class_type_info_json(vmi_class_type_info *vmi_cti)
Definition: rtti_itanium.c:377
static void rtti_itanium_print_vmi_class_type_info(vmi_class_type_info *vmi_cti, const char *prefix)
Definition: rtti_itanium.c:346
static class_type_info * rtti_itanium_type_info_new(RVTableContext *context, ut64 vtable_addr)
Definition: rtti_itanium.c:637
@ RZ_OUTPUT_MODE_JSON
Definition: rz_types.h:40

References addr, rtti_itanium_class_type_info_free(), rtti_itanium_print_class_type_info(), rtti_itanium_print_class_type_info_json(), rtti_itanium_print_si_class_type_info(), rtti_itanium_print_si_class_type_info_json(), rtti_itanium_print_vmi_class_type_info(), rtti_itanium_print_vmi_class_type_info_json(), rtti_itanium_si_class_type_info_free(), rtti_itanium_type_info_new(), rtti_itanium_vmi_class_type_info_free(), RZ_OUTPUT_MODE_JSON, rz_return_val_if_reached, RZ_TYPEINFO_TYPE_CLASS, RZ_TYPEINFO_TYPE_SI_CLASS, RZ_TYPEINFO_TYPE_VMI_CLASS, and class_type_info_t::type.

Referenced by rz_analysis_rtti_print_all(), and rz_analysis_rtti_print_at_vtable().

◆ rz_analysis_rtti_itanium_recover_all()

RZ_API void rz_analysis_rtti_itanium_recover_all ( RVTableContext *  context,
RzList vtables 
)

Definition at line 860 of file rtti_itanium.c.

860  {
861  RzList /*<class_type_info>*/ *rtti_list = rz_list_new();
862  rtti_list->free = rtti_itanium_type_info_free;
863  // to escape multiple same infos from multiple inheritance
864  SetU *unique_rttis = set_u_new();
865 
866  RzListIter *iter;
867  RVTableInfo *vtable;
868  rz_list_foreach (vtables, iter, vtable) {
869  class_type_info *cti = rtti_itanium_type_info_new(context, vtable->saddr);
870  if (!cti) {
871  continue;
872  }
873 
874  rz_analysis_class_create(context->analysis, cti->name);
875  // can't we name virtual functions virtual even without RTTI?
876  recovery_apply_vtable(context, cti->name, vtable);
877  // Temporarily detect by method name
878  detect_constructor_destructor(context->analysis, cti);
879 
880  // we only need one of a kind
881  if (set_u_contains(unique_rttis, cti->typeinfo_addr)) {
883  } else {
884  set_u_add(unique_rttis, cti->typeinfo_addr);
885  rz_list_append(rtti_list, cti);
886  }
887  }
888 
889  class_type_info *cti;
890  rz_list_foreach (rtti_list, iter, cti) {
891  add_class_bases(context, cti);
892  }
893 
894  set_u_free(unique_rttis);
895  rz_list_free(rtti_list);
896 }
RZ_API RzAnalysisClassErr rz_analysis_class_create(RzAnalysis *analysis, const char *name)
Definition: class.c:79
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
static void add_class_bases(RVTableContext *context, const class_type_info *cti)
Add any base class information about the type into analysis/classes.
Definition: rtti_itanium.c:805
static void detect_constructor_destructor(RzAnalysis *analysis, class_type_info *cti)
Definition: rtti_itanium.c:839
static void recovery_apply_vtable(RVTableContext *context, const char *class_name, RVTableInfo *vtable_info)
Definition: rtti_itanium.c:761
static void rtti_itanium_type_info_free(void *info)
Definition: rtti_itanium.c:679
RZ_API SetU * set_u_new(void)
Definition: set.c:30
RZ_API void set_u_free(SetU *s)
Definition: set.c:46
RZ_API void set_u_add(SetU *s, ut64 u)
Definition: set.c:34
RZ_API bool set_u_contains(SetU *s, ut64 u)
Definition: set.c:38
HtUP SetU
Definition: set.h:22
RzListFree free
Definition: rz_list.h:21

References add_class_bases(), detect_constructor_destructor(), rz_list_t::free, class_type_info_t::name, recovery_apply_vtable(), rtti_itanium_type_info_free(), rtti_itanium_type_info_new(), rz_analysis_class_create(), rz_list_append(), rz_list_free(), rz_list_new(), set_u_add(), set_u_contains(), set_u_free(), set_u_new(), and class_type_info_t::typeinfo_addr.

Referenced by rz_analysis_rtti_recover_all().

◆ type_to_string()