Rizin
unix-like reverse engineering framework and cli tools
typelink.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 Anton Kochkov <anton.kochkov@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_util.h>
5 #include <rz_type.h>
6 #include <rz_analysis.h>
7 #include <string.h>
8 #include <sdb.h>
9 
17  rz_return_val_if_fail(analysis, false);
18  if (addr == UT64_MAX) {
19  return false;
20  }
21  bool found = false;
22  return ht_up_find(analysis->type_links, addr, &found) && found;
23 }
24 
32  rz_return_val_if_fail(analysis, NULL);
33  if (addr == UT64_MAX) {
34  return NULL;
35  }
36  bool found = false;
37  RzType *result = ht_up_find(analysis->type_links, addr, &found);
38  if (!found || !result) {
39  return NULL;
40  }
41  return result;
42 }
43 
52  rz_return_val_if_fail(analysis && type, false);
53  ht_up_insert(analysis->type_links, addr, type);
54  return true;
55 }
56 
64  rz_return_val_if_fail(analysis, false);
65  ht_up_delete(analysis->type_links, addr);
66  return true;
67 }
68 
75  rz_return_val_if_fail(analysis, false);
76  ht_up_free(analysis->type_links);
77  analysis->type_links = ht_up_new0();
78  if (!analysis->type_links) {
79  return false;
80  }
81  return true;
82 }
83 
84 static bool type_collect_cb(void *user, ut64 k, const void *v) {
85  rz_return_val_if_fail(user && v, false);
86  RzList *l = user;
87  rz_list_append(l, (RzType *)v);
88  return true;
89 }
90 
97  rz_return_val_if_fail(analysis, NULL);
99  ht_up_foreach(analysis->type_links, type_collect_cb, types);
100  return types;
101 }
102 
103 struct TListMeta {
104  const RzTypeDB *typedb;
108 };
109 
110 // TODO: Also resolve pointers and arrays
111 static bool type_paths_collect_by_offset_cb(void *user, ut64 k, const void *v) {
112  rz_return_val_if_fail(user && v, false);
113  struct TListMeta *tl = (struct TListMeta *)user;
114  RzType *t = (RzType *)v;
115  // Handle only identifiers here
116  if (t->kind != RZ_TYPE_KIND_IDENTIFIER) {
117  return true;
118  }
119  if (!t->identifier.name) {
120  return true;
121  }
122  // Get the base type
123  RzBaseType *btype = rz_type_db_get_base_type(tl->typedb, t->identifier.name);
124  if (!btype) {
125  return true;
126  }
127  if (btype->kind == RZ_BASE_TYPE_KIND_STRUCT || btype->kind == RZ_BASE_TYPE_KIND_UNION) {
128  RzList *list = rz_type_path_by_offset(tl->typedb, btype, tl->offset);
129  if (list) {
130  rz_list_join(tl->l, list);
131  }
132  }
133  return true;
134 }
135 
143  rz_return_val_if_fail(analysis, NULL);
144  if (offset == UT64_MAX) {
145  return NULL;
146  }
147  RzList *typepaths = rz_list_new();
148  struct TListMeta tl = {
149  .typedb = analysis->typedb,
150  .l = typepaths,
151  .addr = 0,
152  .offset = offset
153  };
154  ht_up_foreach(analysis->type_links, type_paths_collect_by_offset_cb, &tl);
155  return typepaths;
156 }
157 
158 // TODO: Also resolve pointers and arrays
159 static bool type_paths_collect_by_address_cb(void *user, ut64 k, const void *v) {
160  rz_return_val_if_fail(user && v, false);
161  struct TListMeta *tl = (struct TListMeta *)user;
162  // If the possible offset doesn't make sense - we skip it
163  if (tl->addr < k) {
164  return true;
165  }
166 
167  RzType *t = (RzType *)v;
168  // Handle only identifiers here
169  if (t->kind != RZ_TYPE_KIND_IDENTIFIER) {
170  return true;
171  }
172  if (!t->identifier.name) {
173  return true;
174  }
175  // Get the base type
176  RzBaseType *btype = rz_type_db_get_base_type(tl->typedb, t->identifier.name);
177  if (!btype) {
178  return true;
179  }
180  // Calculate the possible offset as a difference between base address of the type link
181  // and the given address to check against
182  st64 offset = (st64)(tl->addr - k);
183  if (offset < 0) {
184  return true;
185  }
186  if (btype->kind == RZ_BASE_TYPE_KIND_STRUCT || btype->kind == RZ_BASE_TYPE_KIND_UNION) {
188  if (list) {
189  rz_list_join(tl->l, list);
190  }
191  }
192  return true;
193 }
194 
202  rz_return_val_if_fail(analysis, NULL);
203  if (addr == UT64_MAX) {
204  return NULL;
205  }
206  RzList *typepaths = rz_list_new();
207  struct TListMeta tl = {
208  .typedb = analysis->typedb,
209  .l = typepaths,
210  .addr = addr,
211  .offset = 0
212  };
213  ht_up_foreach(analysis->type_links, type_paths_collect_by_address_cb, &tl);
214  return typepaths;
215 }
RZ_API RZ_BORROW RzBaseType * rz_type_db_get_base_type(const RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the RzBaseType in the types database given the name.
Definition: base.c:57
#define RZ_API
#define NULL
Definition: cris-opc.c:27
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
voidpf uLong offset
Definition: ioapi.h:144
static void list(RzEgg *egg)
Definition: rz-gg.c:52
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 bool rz_list_join(RZ_NONNULL RzList *list1, RZ_NONNULL RzList *list2)
Joins 2 list into one (list2 pointer needs to be freed by the user)
Definition: list.c:209
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
int type
Definition: mipsasm.c:17
insn_type_descr_t types[]
Definition: or1k_disas.c:7
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
@ RZ_BASE_TYPE_KIND_UNION
Definition: rz_type.h:74
@ RZ_BASE_TYPE_KIND_STRUCT
Definition: rz_type.h:73
@ RZ_TYPE_KIND_IDENTIFIER
Definition: rz_type.h:128
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_BORROW
Definition: rz_types.h:63
#define st64
Definition: rz_types_base.h:10
#define UT64_MAX
Definition: rz_types_base.h:86
const RzTypeDB * typedb
Definition: typelink.c:104
ut64 offset
Definition: typelink.c:107
ut64 addr
Definition: typelink.c:106
RzList * l
Definition: typelink.c:105
HtUP * type_links
Definition: rz_analysis.h:603
RzTypeDB * typedb
Definition: rz_analysis.h:602
RzBaseTypeKind kind
Definition: rz_type.h:115
RzTypeKind kind
Definition: rz_type.h:155
struct rz_type_t::@292::@294 identifier
RZ_API RZ_OWN RzList * rz_type_path_by_offset(const RzTypeDB *typedb, RzBaseType *btype, ut64 offset)
Returns the list of all type paths matching the offset.
Definition: path.c:176
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58