Rizin
unix-like reverse engineering framework and cli tools
serialize_analysis.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2020-2021 thestr4ng3r <info@florianmaerkl.de>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_util/rz_serialize.h>
5 #include <rz_util/rz_num.h>
6 #include <rz_vector.h>
7 #include <rz_type.h>
8 #include <rz_analysis.h>
9 #include <rz_core.h>
10 
11 #include <errno.h>
12 
13 /*
14  *
15  * SDB Format:
16  *
17  * /
18  * /blocks
19  * 0x<addr>={size:<ut64>, jump?:<ut64>, fail?:<ut64>, traced?:true, colorize?:<ut32>,
20  * fingerprint?:"<base64>", diff?: <RzAnalysisDiff>, switch_op?:<RzAnalysisSwitchOp>,
21  * ninstr:<int>, op_pos?:[<ut16>], stackptr:<int>, parent_stackptr:<int>,
22  * cmpval:<ut64>, cmpreg?:<str>}
23  * /functions
24  * 0x<addr>={name:<str>, bits?:<int>, type:<int>, cc?:<str>, stack:<int>, maxstack:<int>,
25  * ninstr:<int>, pure?:<bool>, bp_frame?:<bool>, bp_off?:<st64>, noreturn?:<bool>,
26  * fingerprint?:"<base64>", diff?:<RzAnalysisDiff>, bbs:[<ut64>], imports?:[<str>], vars?:[<RzAnalysisVar>],
27  * labels?: {<str>:<ut64>}}
28  * /xrefs
29  * 0x<addr>=[{to:<ut64>, type?:"c"|"C"|"d"|"s"}]
30  *
31  * /meta
32  * 0x<addr>=[{size?:<ut64, interpreted as 1 if not present>, type:<str>, subtype?:<int>, str?:<str>, space?:<str>}]
33  * /spaces
34  * see spaces.c
35  *
36  * /hints
37  * 0x<addr>={arch?:<str|null>,bits?:<int|null>,toff?:<string>,nword?:<int>,jump?:<ut64>,fail?:<ut64>,newbits?:<int>,
38  * immbase?:<int>,ptr?:<ut64>,ret?:<ut64>,syntax?:<str>,opcode?:<str>,esil?:<str>,optype?:<int>,
39  * size?:<ut64>,frame?:<ut64>,val?:<ut64>,high?:<bool>}
40  * /classes
41  * <direct dump of RzAnalysis.sdb_classes>
42  * /attrs
43  * <direct dump of RzAnalysis.sdb_classes_attrs>
44  *
45  *
46  * /imports
47  * <str>=i
48  *
49  * RzAnalysisDiff JSON:
50  * {type?:"m"|"u", addr:<ut64>, dist:<double>, name?:<str>, size:<ut32>}
51  *
52  * RzAnalysisSwitchOp JSON:
53  * {addr:<ut64>, min:<ut64>, max:<ut64>, def:<ut64>, cases:[<RzAnalysisCaseOp>]}
54  *
55  * RzAnalysisCaseOp JSON:
56  * {addr:<ut64>, jump:<ut64>, value:<ut64>}
57  *
58  * RzAnalysisVar JSON:
59  * {name:<str>, type:<str>, kind:"s|b|r", arg?:<bool>, delta?:<st64>, reg?:<str>, cmt?:<str>,
60  * accs?: [{off:<st64>, type:"r|w|rw", reg:<str>, sp?:<st64>}], constrs?:[<int>,<ut64>,...]}
61  *
62  */
63 
65  pj_o(j);
66  switch (diff->type) {
68  pj_ks(j, "type", "m");
69  break;
71  pj_ks(j, "type", "u");
72  break;
73  }
74  if (diff->addr != UT64_MAX) {
75  pj_kn(j, "addr", diff->addr);
76  }
77  if (diff->dist != 0.0) {
78  pj_kd(j, "dist", diff->dist);
79  }
80  if (diff->name) {
81  pj_ks(j, "name", diff->name);
82  }
83  if (diff->size) {
84  pj_kn(j, "size", (ut64)diff->size);
85  }
86  pj_end(j);
87 }
88 
89 enum {
95 };
96 
97 RZ_API RzSerializeAnalDiffParser rz_serialize_analysis_diff_parser_new(void) {
98  RzSerializeAnalDiffParser parser = rz_key_parser_new();
99  if (!parser) {
100  return NULL;
101  }
107  return parser;
108 }
109 
110 RZ_API void rz_serialize_analysis_diff_parser_free(RzSerializeAnalDiffParser parser) {
112 }
113 
115  if (json->type != RZ_JSON_OBJECT) {
116  return NULL;
117  }
119  if (!diff) {
120  return NULL;
121  }
122  RZ_KEY_PARSER_JSON(parser, json, child, {
123  case DIFF_FIELD_TYPE:
124  if (child->type != RZ_JSON_STRING) {
125  break;
126  }
127  if (strcmp(child->str_value, "m") == 0) {
128  diff->type = RZ_ANALYSIS_DIFF_TYPE_MATCH;
129  } else if (strcmp(child->str_value, "u") == 0) {
130  diff->type = RZ_ANALYSIS_DIFF_TYPE_UNMATCH;
131  }
132  break;
133  case DIFF_FIELD_ADDR:
134  if (child->type != RZ_JSON_INTEGER) {
135  break;
136  }
137  diff->addr = child->num.u_value;
138  break;
139  case DIFF_FIELD_DIST:
140  if (child->type == RZ_JSON_INTEGER) {
141  diff->dist = child->num.u_value;
142  } else if (child->type == RZ_JSON_DOUBLE) {
143  diff->dist = child->num.dbl_value;
144  }
145  break;
146  case DIFF_FIELD_NAME:
147  if (child->type != RZ_JSON_STRING) {
148  break;
149  }
150  free(diff->name);
151  diff->name = strdup(child->str_value);
152  break;
153  case DIFF_FIELD_SIZE:
154  if (child->type != RZ_JSON_INTEGER) {
155  break;
156  }
157  diff->size = child->num.u_value;
158  break;
159  default:
160  break;
161  })
162  return diff;
163 }
164 
166  pj_o(j);
167  pj_kn(j, "addr", op->addr);
168  pj_kn(j, "jump", op->jump);
169  pj_kn(j, "value", op->value);
170  pj_end(j);
171 }
172 
174  pj_o(j);
175  pj_kn(j, "addr", op->addr);
176  pj_kn(j, "min", op->min_val);
177  pj_kn(j, "max", op->max_val);
178  pj_kn(j, "def", op->def_val);
179  pj_k(j, "cases");
180  pj_a(j);
181  RzListIter *it;
182  RzAnalysisCaseOp *cop;
183  rz_list_foreach (op->cases, it, cop) {
185  }
186  pj_end(j);
187  pj_end(j);
188 }
189 
191  if (json->type != RZ_JSON_OBJECT) {
192  return NULL;
193  }
195  if (!sop) {
196  return NULL;
197  }
198  RzJson *child;
199  for (child = json->children.first; child; child = child->next) {
200  if (child->type == RZ_JSON_INTEGER) {
201  if (strcmp(child->key, "addr") == 0) {
202  sop->addr = child->num.u_value;
203  } else if (strcmp(child->key, "min") == 0) {
204  sop->min_val = child->num.u_value;
205  } else if (strcmp(child->key, "max") == 0) {
206  sop->max_val = child->num.u_value;
207  } else if (strcmp(child->key, "def") == 0) {
208  sop->def_val = child->num.u_value;
209  }
210  } else if (child->type == RZ_JSON_ARRAY && strcmp(child->key, "cases") == 0) {
211  RzJson *obj;
212  for (obj = child->children.first; obj; obj = obj->next) {
213  if (obj->type != RZ_JSON_OBJECT) {
214  continue;
215  }
216  ut64 addr = UT64_MAX;
217  ut64 jump = UT64_MAX;
218  ut64 value = UT64_MAX;
219  RzJson *cases;
220  for (cases = obj->children.first; cases; cases = cases->next) {
221  if (cases->type != RZ_JSON_INTEGER) {
222  continue;
223  }
224  if (strcmp(cases->key, "addr") == 0) {
225  addr = cases->num.u_value;
226  } else if (strcmp(cases->key, "jump") == 0) {
227  jump = cases->num.u_value;
228  } else if (strcmp(cases->key, "value") == 0) {
229  value = cases->num.u_value;
230  }
231  }
233  }
234  }
235  }
236  return sop;
237 }
238 
239 static void block_store(RZ_NONNULL Sdb *db, const char *key, RzAnalysisBlock *block) {
240  PJ *j = pj_new();
241  if (!j) {
242  return;
243  }
244  pj_o(j);
245 
246  pj_kn(j, "size", block->size);
247  if (block->jump != UT64_MAX) {
248  pj_kn(j, "jump", block->jump);
249  }
250  if (block->fail != UT64_MAX) {
251  pj_kn(j, "fail", block->fail);
252  }
253  if (block->traced) {
254  pj_kb(j, "traced", true);
255  }
256  if (block->colorize) {
257  pj_kn(j, "colorize", (ut64)block->colorize);
258  }
259  if (block->fingerprint) {
260  char *b64 = rz_base64_encode_dyn(block->fingerprint, block->size);
261  if (b64) {
262  pj_ks(j, "fingerprint", b64);
263  free(b64);
264  }
265  }
266  if (block->diff) {
267  pj_k(j, "diff");
269  }
270 
271  // TODO: cond? It's used nowhere...
272 
273  if (block->switch_op) {
274  pj_k(j, "switch_op");
276  }
277 
278  if (block->ninstr) {
279  pj_ki(j, "ninstr", block->ninstr);
280  }
281  if (block->op_pos && block->ninstr > 1) {
282  pj_k(j, "op_pos");
283  pj_a(j);
284  size_t i;
285  for (i = 0; i < block->ninstr - 1; i++) {
286  pj_n(j, block->op_pos[i]);
287  }
288  pj_end(j);
289  }
290 
291  // op_bytes is only java, never set
292  // parent_reg_arena is never set
293 
294  if (block->stackptr) {
295  pj_ki(j, "stackptr", block->stackptr);
296  }
297  if (block->parent_stackptr != INT_MAX) {
298  pj_ki(j, "parent_stackptr", block->parent_stackptr);
299  }
300  if (block->cmpval != UT64_MAX) {
301  pj_kn(j, "cmpval", block->cmpval);
302  }
303  if (block->cmpreg) {
304  pj_ks(j, "cmpreg", block->cmpreg);
305  }
306 
307  pj_end(j);
308  sdb_set(db, key, pj_string(j), 0);
309  pj_free(j);
310 }
311 
313  RBIter iter;
314  RzAnalysisBlock *block;
315  RzStrBuf key = { 0 };
316  rz_rbtree_foreach (analysis->bb_tree, iter, block, RzAnalysisBlock, _rb) {
317  rz_strbuf_setf(&key, "0x%" PFMT64x, block->addr);
318  block_store(db, rz_strbuf_get(&key), block);
319  }
321 }
322 
323 enum {
338 };
339 
340 typedef struct {
343  RzSerializeAnalDiffParser diff_parser;
344 } BlockLoadCtx;
345 
346 static bool block_load_cb(void *user, const char *k, const char *v) {
347  BlockLoadCtx *ctx = user;
348 
349  char *json_str = strdup(v);
350  if (!json_str) {
351  return true;
352  }
353  RzJson *json = rz_json_parse(json_str);
354  if (!json || json->type != RZ_JSON_OBJECT) {
355  free(json_str);
356  return false;
357  }
358 
359  RzAnalysisBlock proto = { 0 };
360  proto.jump = UT64_MAX;
361  proto.fail = UT64_MAX;
362  proto.size = UT64_MAX;
363  proto.parent_stackptr = INT_MAX;
364  proto.cmpval = UT64_MAX;
365  size_t fingerprint_size = SIZE_MAX;
366  RZ_KEY_PARSER_JSON(ctx->parser, json, child, {
367  case BLOCK_FIELD_SIZE:
368  if (child->type != RZ_JSON_INTEGER) {
369  break;
370  }
371  proto.size = child->num.u_value;
372  break;
373  case BLOCK_FIELD_JUMP:
374  if (child->type != RZ_JSON_INTEGER) {
375  break;
376  }
377  proto.jump = child->num.u_value;
378  break;
379  case BLOCK_FIELD_FAIL:
380  if (child->type != RZ_JSON_INTEGER) {
381  break;
382  }
383  proto.fail = child->num.u_value;
384  break;
385  case BLOCK_FIELD_TRACED:
386  if (child->type != RZ_JSON_BOOLEAN) {
387  break;
388  }
389  proto.traced = child->num.u_value;
390  break;
392  if (child->type != RZ_JSON_INTEGER) {
393  break;
394  }
395  proto.colorize = (ut32)child->num.u_value;
396  break;
398  if (child->type != RZ_JSON_STRING) {
399  break;
400  }
401  if (proto.fingerprint) {
402  free(proto.fingerprint);
403  proto.fingerprint = NULL;
404  }
405  fingerprint_size = strlen(child->str_value);
406  if (!fingerprint_size) {
407  break;
408  }
409  proto.fingerprint = malloc(fingerprint_size);
410  if (!proto.fingerprint) {
411  break;
412  }
413  int decsz = rz_base64_decode(proto.fingerprint, child->str_value, fingerprint_size);
414  if (decsz <= 0) {
415  free(proto.fingerprint);
416  proto.fingerprint = NULL;
417  fingerprint_size = 0;
418  } else if (decsz < fingerprint_size) {
419  ut8 *n = realloc(proto.fingerprint, (size_t)decsz);
420  if (n) {
421  proto.fingerprint = n;
422  fingerprint_size = decsz;
423  }
424  }
425  break;
426  }
427  case BLOCK_FIELD_DIFF:
428  rz_analysis_diff_free(proto.diff);
429  proto.diff = rz_serialize_analysis_diff_load(ctx->diff_parser, child);
430  break;
432  rz_analysis_switch_op_free(proto.switch_op);
433  proto.switch_op = rz_serialize_analysis_switch_op_load(child);
434  break;
435  case BLOCK_FIELD_NINSTR:
436  if (child->type != RZ_JSON_INTEGER) {
437  break;
438  }
439  proto.ninstr = (int)child->num.s_value;
440  break;
441  case BLOCK_FIELD_OP_POS: {
442  if (child->type != RZ_JSON_ARRAY) {
443  break;
444  }
445  if (proto.op_pos) {
446  free(proto.op_pos);
447  proto.op_pos = NULL;
448  }
449  proto.op_pos = calloc(child->children.count, sizeof(ut16));
450  proto.op_pos_size = 0;
451  RzJson *baby;
452  for (baby = child->children.first; baby; baby = baby->next) {
453  if (baby->type != RZ_JSON_INTEGER) {
454  free(proto.op_pos);
455  proto.op_pos = NULL;
456  proto.op_pos_size = 0;
457  break;
458  }
459  proto.op_pos[proto.op_pos_size++] = (ut16)baby->num.u_value;
460  }
461  break;
462  }
464  if (child->type != RZ_JSON_INTEGER) {
465  break;
466  }
467  proto.stackptr = (int)child->num.s_value;
468  break;
470  if (child->type != RZ_JSON_INTEGER) {
471  break;
472  }
473  proto.parent_stackptr = (int)child->num.s_value;
474  break;
475  case BLOCK_FIELD_CMPVAL:
476  if (child->type != RZ_JSON_INTEGER) {
477  break;
478  }
479  proto.cmpval = child->num.u_value;
480  break;
481  case BLOCK_FIELD_CMPREG:
482  if (child->type != RZ_JSON_STRING) {
483  break;
484  }
485  proto.cmpreg = rz_str_constpool_get(&ctx->analysis->constpool, child->str_value);
486  break;
487  default:
488  break;
489  })
490  rz_json_free(json);
491  free(json_str);
492 
493  errno = 0;
494  ut64 addr = strtoull(k, NULL, 0);
495  if (errno || proto.size == UT64_MAX || (fingerprint_size != SIZE_MAX && fingerprint_size != proto.size) || (proto.op_pos && proto.op_pos_size != proto.ninstr - 1)) { // op_pos_size > ninstr - 1 is legal but we require the format to be like this.
496  goto error;
497  }
498 
499  RzAnalysisBlock *block = rz_analysis_create_block(ctx->analysis, addr, proto.size);
500  if (!block) {
501  goto error;
502  }
503  block->jump = proto.jump;
504  block->fail = proto.fail;
505  block->traced = proto.traced;
506  block->colorize = proto.colorize;
507  block->fingerprint = proto.fingerprint;
508  block->diff = proto.diff;
509  block->switch_op = proto.switch_op;
510  block->ninstr = proto.ninstr;
511  if (proto.op_pos) {
512  free(block->op_pos);
513  block->op_pos = proto.op_pos;
514  block->op_pos_size = proto.op_pos_size;
515  }
516  block->stackptr = proto.stackptr;
517  block->parent_stackptr = proto.parent_stackptr;
518  block->cmpval = proto.cmpval;
519  block->cmpreg = proto.cmpreg;
520 
521  return true;
522 error:
523  free(proto.fingerprint);
524  rz_analysis_diff_free(proto.diff);
525  rz_analysis_switch_op_free(proto.switch_op);
526  free(proto.op_pos);
527  return false;
528 }
529 
530 RZ_API bool rz_serialize_analysis_blocks_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RzSerializeAnalDiffParser diff_parser, RZ_NULLABLE RzSerializeResultInfo *res) {
531  BlockLoadCtx ctx = { analysis, rz_key_parser_new(), diff_parser };
532  if (!ctx.parser) {
533  RZ_SERIALIZE_ERR(res, "parser init failed");
534  return false;
535  }
536  rz_key_parser_add(ctx.parser, "size", BLOCK_FIELD_SIZE);
537  rz_key_parser_add(ctx.parser, "jump", BLOCK_FIELD_JUMP);
538  rz_key_parser_add(ctx.parser, "fail", BLOCK_FIELD_FAIL);
539  rz_key_parser_add(ctx.parser, "traced", BLOCK_FIELD_TRACED);
540  rz_key_parser_add(ctx.parser, "colorize", BLOCK_FIELD_COLORIZE);
541  rz_key_parser_add(ctx.parser, "fingerprint", BLOCK_FIELD_FINGERPRINT);
542  rz_key_parser_add(ctx.parser, "diff", BLOCK_FIELD_DIFF);
543  rz_key_parser_add(ctx.parser, "switch_op", BLOCK_FIELD_SWITCH_OP);
544  rz_key_parser_add(ctx.parser, "ninstr", BLOCK_FIELD_NINSTR);
545  rz_key_parser_add(ctx.parser, "op_pos", BLOCK_FIELD_OP_POS);
546  rz_key_parser_add(ctx.parser, "stackptr", BLOCK_FIELD_STACKPTR);
547  rz_key_parser_add(ctx.parser, "parent_stackptr", BLOCK_FIELD_PARENT_STACKPTR);
548  rz_key_parser_add(ctx.parser, "cmpval", BLOCK_FIELD_CMPVAL);
549  rz_key_parser_add(ctx.parser, "cmpreg", BLOCK_FIELD_CMPREG);
550  bool ret = sdb_foreach(db, block_load_cb, &ctx);
551  rz_key_parser_free(ctx.parser);
552  if (!ret) {
553  RZ_SERIALIZE_ERR(res, "basic blocks parsing failed");
554  }
555  return ret;
556 }
557 
559  rz_return_if_fail(j && var);
560  char *vartype = rz_type_as_string(var->fcn->analysis->typedb, var->type);
561  if (!vartype) {
562  RZ_LOG_ERROR("Variable \"%s\" has undefined type\n", var->name);
563  return;
564  }
565  pj_o(j);
566  pj_ks(j, "name", var->name);
567  // TODO: Save it properly instead of using the C representation
568  pj_ks(j, "type", vartype);
569  free(vartype);
570  switch (var->kind) {
572  pj_ks(j, "kind", "r");
573  break;
575  pj_ks(j, "kind", "s");
576  break;
578  pj_ks(j, "kind", "b");
579  break;
580  }
581  if (var->kind != RZ_ANALYSIS_VAR_KIND_REG) {
582  pj_kN(j, "delta", var->delta);
583  }
584  if (var->regname) {
585  pj_ks(j, "reg", var->regname);
586  }
587  if (var->isarg) {
588  pj_kb(j, "arg", true);
589  }
590  if (var->comment) {
591  pj_ks(j, "cmt", var->comment);
592  }
593  if (!rz_vector_empty(&var->accesses)) {
594  pj_ka(j, "accs");
595  RzAnalysisVarAccess *acc;
596  rz_vector_foreach(&var->accesses, acc) {
597  pj_o(j);
598  pj_kn(j, "off", acc->offset);
599  switch (acc->type) {
601  pj_ks(j, "type", "r");
602  break;
604  pj_ks(j, "type", "w");
605  break;
607  pj_ks(j, "type", "rw");
608  break;
609  }
610  if (acc->stackptr) {
611  pj_kn(j, "sp", acc->stackptr);
612  }
613  if (acc->reg) {
614  pj_ks(j, "reg", acc->reg);
615  } else {
617  }
618  pj_end(j);
619  }
620  pj_end(j);
621  }
622  if (!rz_vector_empty(&var->constraints)) {
623  pj_ka(j, "constrs");
624  RzTypeConstraint *constr;
625  rz_vector_foreach(&var->constraints, constr) {
626  pj_i(j, (int)constr->cond);
627  pj_n(j, constr->val);
628  }
629  pj_end(j);
630  }
631  pj_end(j);
632 }
633 
634 enum {
644 };
645 
646 RZ_API RzSerializeAnalVarParser rz_serialize_analysis_var_parser_new(void) {
647  RzSerializeAnalDiffParser parser = rz_key_parser_new();
648  if (!parser) {
649  return NULL;
650  }
660  return parser;
661 }
662 
663 RZ_API void rz_serialize_analysis_var_parser_free(RzSerializeAnalVarParser parser) {
665 }
666 
668  if (json->type != RZ_JSON_OBJECT) {
669  return NULL;
670  }
671  const char *name = NULL;
672  const char *type = NULL;
673  RzAnalysisVarKind kind = -1;
674  bool arg = false;
675  st64 delta = ST64_MAX;
676  const char *regname = NULL;
677  const char *comment = NULL;
678  RzVector accesses;
679  rz_vector_init(&accesses, sizeof(RzAnalysisVarAccess), NULL, NULL);
680  RzVector constraints;
681  rz_vector_init(&constraints, sizeof(RzTypeConstraint), NULL, NULL);
682 
683  RzAnalysisVar *ret = NULL;
684 
685  RZ_KEY_PARSER_JSON(parser, json, child, {
686  case VAR_FIELD_NAME:
687  if (child->type != RZ_JSON_STRING) {
688  break;
689  }
690  name = child->str_value;
691  break;
692  case VAR_FIELD_TYPE:
693  if (child->type != RZ_JSON_STRING) {
694  break;
695  }
696  type = child->str_value;
697  break;
698  case VAR_FIELD_KIND:
699  if (child->type != RZ_JSON_STRING || !*child->str_value || child->str_value[1]) {
700  // must be a string of exactly 1 char
701  break;
702  }
703  switch (*child->str_value) {
704  case 'r':
705  kind = RZ_ANALYSIS_VAR_KIND_REG;
706  break;
707  case 's':
708  kind = RZ_ANALYSIS_VAR_KIND_SPV;
709  break;
710  case 'b':
711  kind = RZ_ANALYSIS_VAR_KIND_BPV;
712  break;
713  default:
714  break;
715  }
716  break;
717  case VAR_FIELD_ARG:
718  if (child->type != RZ_JSON_BOOLEAN) {
719  break;
720  }
721  arg = child->num.u_value ? true : false;
722  break;
723  case VAR_FIELD_DELTA:
724  if (child->type != RZ_JSON_INTEGER) {
725  break;
726  }
727  delta = child->num.s_value;
728  break;
729  case VAR_FIELD_REG:
730  if (child->type != RZ_JSON_STRING) {
731  break;
732  }
733  regname = child->str_value;
734  break;
735  case VAR_FIELD_COMMENT:
736  if (child->type != RZ_JSON_STRING) {
737  break;
738  }
739  comment = child->str_value;
740  break;
741  case VAR_FIELD_ACCS: {
742  if (child->type != RZ_JSON_ARRAY) {
743  break;
744  }
745  RzJson *baby;
746  for (baby = child->children.first; baby; baby = baby->next) {
747  if (baby->type != RZ_JSON_OBJECT) {
748  continue;
749  }
750  // {off:<st64>, type:"r|w|rw", sp?:<st64>}
751  const RzJson *offv = rz_json_get(baby, "off");
752  if (!offv || offv->type != RZ_JSON_INTEGER) {
753  continue;
754  }
755  const RzJson *typev = rz_json_get(baby, "type");
756  if (!typev || typev->type != RZ_JSON_STRING) {
757  continue;
758  }
759  const char *acctype_str = typev->str_value;
760  const RzJson *spv = rz_json_get(baby, "sp");
761  if (spv && spv->type != RZ_JSON_INTEGER) {
762  continue;
763  }
764  const RzJson *regv = rz_json_get(baby, "reg");
765  if (!regv || regv->type != RZ_JSON_STRING) {
766  continue;
767  }
768 
769  ut64 acctype;
770  // parse "r", "w" or "rw" and reject everything else
771  if (acctype_str[0] == 'r') {
772  if (acctype_str[1] == 'w') {
774  } else if (!acctype_str[1]) {
776  } else {
777  continue;
778  }
779  } else if (acctype_str[0] == 'w' && !acctype_str[1]) {
781  } else {
782  continue;
783  }
784 
785  RzAnalysisVarAccess *acc = rz_vector_push(&accesses, NULL);
786  acc->offset = offv->num.s_value;
787  acc->type = acctype;
788  acc->stackptr = spv ? spv->num.s_value : 0;
789  acc->reg = regv->str_value;
790  }
791  break;
792  }
793  case VAR_FIELD_CONSTRS: {
794  if (child->type != RZ_JSON_ARRAY) {
795  break;
796  }
797  RzJson *baby;
798  for (baby = child->children.first; baby; baby = baby->next) {
799  if (baby->type != RZ_JSON_INTEGER) {
800  break;
801  }
802  RzJson *sibling = baby->next;
803  if (!sibling || sibling->type != RZ_JSON_INTEGER) {
804  break;
805  }
806  RzTypeConstraint constr;
807  constr.cond = (RzTypeCond)baby->num.s_value;
808  constr.val = sibling->num.u_value;
809  if (constr.cond < RZ_TYPE_COND_AL || constr.cond > RZ_TYPE_COND_LS) {
810  baby = sibling;
811  continue;
812  }
813  rz_vector_push(&constraints, &constr);
814  baby = sibling;
815  }
816  break;
817  }
818  default:
819  break;
820  })
821 
822  if (kind == RZ_ANALYSIS_VAR_KIND_REG) {
823  if (!regname) {
824  goto beach;
825  }
826  RzRegItem *reg = rz_reg_get(fcn->analysis->reg, regname, -1);
827  if (!reg) {
828  goto beach;
829  }
830  delta = reg->index;
831  }
832  if (!name || !type || kind == -1 || delta == ST64_MAX) {
833  goto beach;
834  }
835  char *error_msg = NULL;
836  RzType *vartype = rz_type_parse_string_single(fcn->analysis->typedb->parser, type, &error_msg);
837  if (error_msg) {
838  RZ_LOG_ERROR("Fail to parse the function variable (\"%s\") type: %s\n", name, type);
839  RZ_FREE(error_msg);
840  goto beach;
841  }
842  ret = rz_analysis_function_set_var(fcn, delta, kind, vartype, 0, arg, name);
843  rz_type_free(vartype);
844  if (!ret) {
845  goto beach;
846  }
847  if (comment) {
848  free(ret->comment);
849  ret->comment = strdup(comment);
850  }
851  RzAnalysisVarAccess *acc;
852  rz_vector_foreach(&accesses, acc) {
853  rz_analysis_var_set_access(ret, acc->reg, fcn->addr + acc->offset, acc->type, acc->stackptr);
854  }
855  RzTypeConstraint *constr;
856  rz_vector_foreach(&constraints, constr) {
857  rz_analysis_var_add_constraint(ret, constr);
858  }
859 
860 beach:
861  rz_vector_fini(&accesses);
862  rz_vector_fini(&constraints);
863  return ret;
864 }
865 
867  rz_return_if_fail(db && anal);
868 
869  PJ *j = pj_new();
870  if (!j) {
871  return;
872  }
873  RBIter it;
874  RzAnalysisVarGlobal *var;
875  char *vartype;
876  rz_rbtree_foreach (anal->global_var_tree, it, var, RzAnalysisVarGlobal, rb) {
877  vartype = rz_type_as_string(anal->typedb, var->type);
878  if (!vartype) {
879  RZ_LOG_ERROR("Global variable \"%s\" has undefined type\n", var->name);
880  pj_free(j);
881  return;
882  }
883  char addr[32];
884  rz_strf(addr, "0x%" PFMT64x, var->addr);
885  pj_o(j);
886  pj_ks(j, "name", var->name);
887  pj_ks(j, "addr", addr);
888  // TODO: Save it properly instead of using the C representation
889  pj_ks(j, "type", vartype);
890  free(vartype);
891  if (!rz_vector_empty(&var->constraints)) {
892  pj_ka(j, "constrs");
893  RzTypeConstraint *constr;
894  rz_vector_foreach(&var->constraints, constr) {
895  pj_i(j, (int)constr->cond);
896  pj_n(j, constr->val);
897  }
898  pj_end(j);
899  }
900  pj_end(j);
901 
902  sdb_set(db, addr, pj_string(j), 0);
903  pj_reset(j);
904  }
905  pj_free(j);
906 }
907 
908 enum {
913 };
914 
915 RZ_API RzSerializeAnalGlobalVarParser rz_serialize_analysis_global_var_parser_new(void) {
916  RzSerializeAnalDiffParser parser = rz_key_parser_new();
917  if (!parser) {
918  return NULL;
919  }
924  return parser;
925 }
926 
927 RZ_API void rz_serialize_analysis_global_var_parser_free(RzSerializeAnalGlobalVarParser parser) {
929 }
930 
931 typedef struct {
934 } GlobalVarCtx;
935 
936 static bool global_var_load_cb(void *user, const char *k, const char *v) {
937  GlobalVarCtx *ctx = user;
938 
939  char *json_str = strdup(v);
940  if (!json_str) {
941  return true;
942  }
943  RzJson *json = rz_json_parse(json_str);
944  if (!json || json->type != RZ_JSON_OBJECT) {
945  free(json_str);
946  return false;
947  }
948 
949  const char *name = NULL;
950  const char *type = NULL;
951  const char *addr_s = NULL;
952  ut64 addr = 0;
953  RzVector constraints;
954  rz_vector_init(&constraints, sizeof(RzTypeConstraint), NULL, NULL);
955 
956  RzAnalysisVarGlobal *glob = NULL;
957 
958  RZ_KEY_PARSER_JSON(ctx->parser, json, child, {
959  case GLOBAL_VAR_FIELD_NAME:
960  if (child->type != RZ_JSON_STRING) {
961  break;
962  }
963  name = child->str_value;
964  break;
966  if (child->type != RZ_JSON_STRING) {
967  break;
968  }
969  addr_s = child->str_value;
970  break;
972  if (child->type != RZ_JSON_STRING) {
973  break;
974  }
975  type = child->str_value;
976  break;
977  case VAR_FIELD_CONSTRS: {
978  if (child->type != RZ_JSON_ARRAY) {
979  break;
980  }
981  RzJson *baby;
982  for (baby = child->children.first; baby; baby = baby->next) {
983  if (baby->type != RZ_JSON_INTEGER) {
984  break;
985  }
986  RzJson *sibling = baby->next;
987  if (!sibling || sibling->type != RZ_JSON_INTEGER) {
988  break;
989  }
990  RzTypeConstraint constr;
991  constr.cond = (RzTypeCond)baby->num.s_value;
992  constr.val = sibling->num.u_value;
993  if (constr.cond < RZ_TYPE_COND_AL || constr.cond > RZ_TYPE_COND_LS) {
994  baby = sibling;
995  continue;
996  }
997  rz_vector_push(&constraints, &constr);
998  baby = sibling;
999  }
1000  break;
1001  }
1002  default:
1003  break;
1004  })
1005 
1006  if (!name || !type) {
1007  goto beach;
1008  }
1009  char *error_msg = NULL;
1010  RzType *vartype = rz_type_parse_string_single(ctx->analysis->typedb->parser, type, &error_msg);
1011  if (error_msg) {
1012  RZ_LOG_ERROR("Fail to parse the function variable (\"%s\") type: %s\n", name, type);
1013  RZ_FREE(error_msg);
1014  goto beach;
1015  }
1016  RzCore *core = ctx->analysis->core;
1017  addr = rz_num_math(core->num, addr_s);
1019  if (!glob) {
1020  goto beach;
1021  }
1022  rz_analysis_var_global_set_type(glob, vartype);
1023 
1024  RzTypeConstraint *constr;
1025  rz_vector_foreach(&constraints, constr) {
1027  }
1028  return rz_analysis_var_global_add(ctx->analysis, glob);
1029 
1030 beach:
1031  rz_vector_fini(&constraints);
1032  return false;
1033 }
1034 
1036  GlobalVarCtx ctx = {
1037  .analysis = analysis,
1039  };
1040  bool ret;
1041  if (!ctx.parser) {
1042  RZ_SERIALIZE_ERR(res, "parser init failed");
1043  ret = false;
1044  goto beach;
1045  }
1046  ret = sdb_foreach(db, global_var_load_cb, &ctx);
1047  if (!ret) {
1048  RZ_SERIALIZE_ERR(res, "functions parsing failed");
1049  }
1050 beach:
1051  rz_key_parser_free(ctx.parser);
1052  return ret;
1053 }
1054 
1055 static bool store_label_cb(void *j, const ut64 k, const void *v) {
1056  pj_kn(j, v, k);
1057  return true;
1058 }
1059 
1060 static void function_store(RZ_NONNULL Sdb *db, const char *key, RzAnalysisFunction *function) {
1061  PJ *j = pj_new();
1062  if (!j) {
1063  return;
1064  }
1065  pj_o(j);
1066 
1067  pj_ks(j, "name", function->name);
1068  if (function->bits) {
1069  pj_ki(j, "bits", function->bits);
1070  }
1071  pj_ki(j, "type", function->type);
1072  if (function->cc) {
1073  pj_ks(j, "cc", function->cc);
1074  }
1075  pj_ki(j, "stack", function->stack);
1076  pj_ki(j, "maxstack", function->maxstack);
1077  pj_ki(j, "ninstr", function->ninstr);
1078  if (function->bp_frame) {
1079  pj_kb(j, "bp_frame", true);
1080  }
1081  if (function->bp_off) {
1082  pj_kN(j, "bp_off", function->bp_off);
1083  }
1084  if (function->is_pure) {
1085  pj_kb(j, "pure", true);
1086  }
1087  if (function->is_noreturn) {
1088  pj_kb(j, "noreturn", true);
1089  }
1090  if (function->fingerprint) {
1091  char *b64 = rz_base64_encode_dyn(function->fingerprint, function->fingerprint_size);
1092  if (b64) {
1093  pj_ks(j, "fingerprint", b64);
1094  free(b64);
1095  }
1096  }
1097  if (function->diff) {
1098  pj_k(j, "diff");
1099  rz_serialize_analysis_diff_save(j, function->diff);
1100  }
1101 
1102  pj_ka(j, "bbs");
1103  RzListIter *it;
1104  RzAnalysisBlock *block;
1105  rz_list_foreach (function->bbs, it, block) {
1106  pj_n(j, block->addr);
1107  }
1108  pj_end(j);
1109 
1110  if (!rz_list_empty(function->imports)) {
1111  pj_ka(j, "imports");
1112  const char *import;
1113  rz_list_foreach (function->imports, it, import) {
1114  pj_s(j, import);
1115  }
1116  pj_end(j);
1117  }
1118 
1119  if (!rz_pvector_empty(&function->vars)) {
1120  pj_ka(j, "vars");
1121  void **vit;
1122  rz_pvector_foreach (&function->vars, vit) {
1123  RzAnalysisVar *var = *vit;
1125  }
1126  pj_end(j);
1127  }
1128 
1129  if (function->labels->count) {
1130  pj_ko(j, "labels");
1131  ht_up_foreach(function->labels, store_label_cb, j);
1132  pj_end(j);
1133  }
1134 
1135  pj_end(j);
1136  sdb_set(db, key, pj_string(j), 0);
1137  pj_free(j);
1138 }
1139 
1141  RzListIter *it;
1142  RzAnalysisFunction *function;
1143  RzStrBuf key;
1144  rz_strbuf_init(&key);
1145  rz_list_foreach (analysis->fcns, it, function) {
1146  rz_strbuf_setf(&key, "0x%" PFMT64x, function->addr);
1147  function_store(db, rz_strbuf_get(&key), function);
1148  }
1149  rz_strbuf_fini(&key);
1150 }
1151 
1152 enum {
1170 };
1171 
1172 typedef struct {
1175  RzSerializeAnalDiffParser diff_parser;
1176  RzSerializeAnalVarParser var_parser;
1177 } FunctionLoadCtx;
1178 
1179 static bool function_load_cb(void *user, const char *k, const char *v) {
1180  FunctionLoadCtx *ctx = user;
1181 
1182  char *json_str = strdup(v);
1183  if (!json_str) {
1184  return true;
1185  }
1186  RzJson *json = rz_json_parse(json_str);
1187  if (!json || json->type != RZ_JSON_OBJECT) {
1188  free(json_str);
1189  return false;
1190  }
1191 
1192  RzAnalysisFunction *function = rz_analysis_function_new(ctx->analysis);
1193  function->bits = 0; // should be 0 if not specified
1194  function->bp_frame = false; // should be false if not specified
1195  function->bp_off = 0; // 0 if not specified
1196  bool noreturn = false;
1197  RzJson *vars_json = NULL;
1198  RZ_KEY_PARSER_JSON(ctx->parser, json, child, {
1199  case FUNCTION_FIELD_NAME:
1200  if (child->type != RZ_JSON_STRING) {
1201  break;
1202  }
1203  if (function->name) {
1204  free(function->name);
1205  }
1206  function->name = strdup(child->str_value);
1207  break;
1208  case FUNCTION_FIELD_BITS:
1209  if (child->type != RZ_JSON_INTEGER) {
1210  break;
1211  }
1212  function->bits = (int)child->num.s_value;
1213  break;
1214  case FUNCTION_FIELD_TYPE:
1215  if (child->type != RZ_JSON_INTEGER) {
1216  break;
1217  }
1218  function->type = (int)child->num.s_value;
1219  break;
1220  case FUNCTION_FIELD_CC:
1221  if (child->type != RZ_JSON_STRING) {
1222  break;
1223  }
1224  function->cc = rz_str_constpool_get(&ctx->analysis->constpool, child->str_value);
1225  break;
1226  case FUNCTION_FIELD_STACK:
1227  if (child->type != RZ_JSON_INTEGER) {
1228  break;
1229  }
1230  function->stack = (int)child->num.s_value;
1231  break;
1233  if (child->type != RZ_JSON_INTEGER) {
1234  break;
1235  }
1236  function->maxstack = (int)child->num.s_value;
1237  break;
1238  case FUNCTION_FIELD_NINSTR:
1239  if (child->type != RZ_JSON_INTEGER) {
1240  break;
1241  }
1242  function->ninstr = (int)child->num.s_value;
1243  break;
1244  case FUNCTION_FIELD_PURE:
1245  if (child->type != RZ_JSON_BOOLEAN) {
1246  break;
1247  }
1248  function->is_pure = child->num.u_value ? true : false;
1249  break;
1251  if (child->type != RZ_JSON_BOOLEAN) {
1252  break;
1253  }
1254  function->bp_frame = child->num.u_value ? true : false;
1255  break;
1256  case FUNCTION_FIELD_BP_OFF:
1257  if (child->type != RZ_JSON_INTEGER) {
1258  break;
1259  }
1260  function->bp_off = child->num.s_value;
1261  break;
1263  if (child->type != RZ_JSON_BOOLEAN) {
1264  break;
1265  }
1266  noreturn = child->num.u_value ? true : false;
1267  break;
1269  if (child->type != RZ_JSON_STRING) {
1270  break;
1271  }
1272  if (function->fingerprint) {
1273  free(function->fingerprint);
1274  function->fingerprint = NULL;
1275  }
1276  function->fingerprint_size = strlen(child->str_value);
1277  if (!function->fingerprint_size) {
1278  break;
1279  }
1280  function->fingerprint = malloc(function->fingerprint_size);
1281  if (!function->fingerprint) {
1282  function->fingerprint_size = 0;
1283  break;
1284  }
1285  int decsz = rz_base64_decode(function->fingerprint, child->str_value, function->fingerprint_size);
1286  if (decsz <= 0) {
1287  free(function->fingerprint);
1288  function->fingerprint = NULL;
1289  function->fingerprint_size = 0;
1290  } else if (decsz < function->fingerprint_size) {
1291  ut8 *n = realloc(function->fingerprint, (size_t)decsz);
1292  if (!n) {
1293  free(function->fingerprint);
1294  function->fingerprint = NULL;
1295  function->fingerprint_size = 0;
1296  }
1297  function->fingerprint = n;
1298  function->fingerprint_size = (size_t)decsz;
1299  }
1300  break;
1301  case FUNCTION_FIELD_DIFF:
1302  rz_analysis_diff_free(function->diff);
1303  function->diff = rz_serialize_analysis_diff_load(ctx->diff_parser, child);
1304  break;
1305  case FUNCTION_FIELD_BBS: {
1306  if (child->type != RZ_JSON_ARRAY) {
1307  break;
1308  }
1309  RzJson *baby;
1310  for (baby = child->children.first; baby; baby = baby->next) {
1311  if (baby->type != RZ_JSON_INTEGER) {
1312  continue;
1313  }
1314  RzAnalysisBlock *block = rz_analysis_get_block_at(ctx->analysis, baby->num.u_value);
1315  if (!block) {
1316  continue;
1317  }
1318  rz_analysis_function_add_block(function, block);
1319  }
1320  break;
1321  }
1322  case FUNCTION_FIELD_IMPORTS: {
1323  if (child->type != RZ_JSON_ARRAY) {
1324  break;
1325  }
1326  RzJson *baby;
1327  for (baby = child->children.first; baby; baby = baby->next) {
1328  if (baby->type != RZ_JSON_STRING) {
1329  continue;
1330  }
1331  char *import = strdup(baby->str_value);
1332  if (!import) {
1333  break;
1334  }
1335  if (!function->imports) {
1336  function->imports = rz_list_newf((RzListFree)free);
1337  if (!function->imports) {
1338  free(import);
1339  break;
1340  }
1341  }
1342  rz_list_push(function->imports, import);
1343  }
1344  break;
1345  }
1346  case FUNCTION_FIELD_VARS: {
1347  if (child->type != RZ_JSON_ARRAY) {
1348  break;
1349  }
1350  vars_json = child;
1351  break;
1352  }
1353  case FUNCTION_FIELD_LABELS: {
1354  if (child->type != RZ_JSON_OBJECT) {
1355  break;
1356  }
1357  RzJson *baby;
1358  for (baby = child->children.first; baby; baby = baby->next) {
1359  if (baby->type != RZ_JSON_INTEGER) {
1360  continue;
1361  }
1362  rz_analysis_function_set_label(function, baby->key, baby->num.u_value);
1363  }
1364  break;
1365  }
1366  default:
1367  break;
1368  })
1369 
1370  bool ret = true;
1371  errno = 0;
1372  function->addr = strtoull(k, NULL, 0);
1373  if (errno || !function->name || !rz_analysis_add_function(ctx->analysis, function)) {
1374  rz_analysis_function_free(function);
1375  ret = false;
1376  goto beach;
1377  }
1378  function->is_noreturn = noreturn; // Can't set directly, rz_analysis_add_function() overwrites it
1379 
1380  if (vars_json) {
1381  RzJson *baby;
1382  for (baby = vars_json->children.first; baby; baby = baby->next) {
1383  rz_serialize_analysis_var_load(function, ctx->var_parser, baby);
1384  }
1385  }
1386 
1387 beach:
1388  rz_json_free(json);
1389  free(json_str);
1390  return ret;
1391 }
1392 
1393 RZ_API bool rz_serialize_analysis_functions_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RzSerializeAnalDiffParser diff_parser, RZ_NULLABLE RzSerializeResultInfo *res) {
1394  FunctionLoadCtx ctx = {
1395  .analysis = analysis,
1396  .parser = rz_key_parser_new(),
1397  .diff_parser = diff_parser,
1398  .var_parser = rz_serialize_analysis_var_parser_new()
1399  };
1400  bool ret;
1401  if (!ctx.parser || !ctx.var_parser) {
1402  RZ_SERIALIZE_ERR(res, "parser init failed");
1403  ret = false;
1404  goto beach;
1405  }
1406  rz_key_parser_add(ctx.parser, "name", FUNCTION_FIELD_NAME);
1407  rz_key_parser_add(ctx.parser, "bits", FUNCTION_FIELD_BITS);
1408  rz_key_parser_add(ctx.parser, "type", FUNCTION_FIELD_TYPE);
1409  rz_key_parser_add(ctx.parser, "cc", FUNCTION_FIELD_CC);
1410  rz_key_parser_add(ctx.parser, "stack", FUNCTION_FIELD_STACK);
1411  rz_key_parser_add(ctx.parser, "maxstack", FUNCTION_FIELD_MAXSTACK);
1412  rz_key_parser_add(ctx.parser, "ninstr", FUNCTION_FIELD_NINSTR);
1413  rz_key_parser_add(ctx.parser, "pure", FUNCTION_FIELD_PURE);
1414  rz_key_parser_add(ctx.parser, "bp_frame", FUNCTION_FIELD_BP_FRAME);
1415  rz_key_parser_add(ctx.parser, "bp_off", FUNCTION_FIELD_BP_OFF);
1416  rz_key_parser_add(ctx.parser, "noreturn", FUNCTION_FIELD_NORETURN);
1417  rz_key_parser_add(ctx.parser, "fingerprint", FUNCTION_FIELD_FINGERPRINT);
1418  rz_key_parser_add(ctx.parser, "diff", FUNCTION_FIELD_DIFF);
1419  rz_key_parser_add(ctx.parser, "bbs", FUNCTION_FIELD_BBS);
1420  rz_key_parser_add(ctx.parser, "imports", FUNCTION_FIELD_IMPORTS);
1421  rz_key_parser_add(ctx.parser, "vars", FUNCTION_FIELD_VARS);
1422  rz_key_parser_add(ctx.parser, "labels", FUNCTION_FIELD_LABELS);
1423  ret = sdb_foreach(db, function_load_cb, &ctx);
1424  if (!ret) {
1425  RZ_SERIALIZE_ERR(res, "functions parsing failed");
1426  }
1427 beach:
1428  rz_key_parser_free(ctx.parser);
1430  return ret;
1431 }
1432 
1434  sdb_copy(analysis->sdb_noret, db);
1435 }
1436 
1438  sdb_reset(analysis->sdb_noret);
1439  sdb_copy(db, analysis->sdb_noret);
1440  return true;
1441 }
1442 
1443 static bool store_xref_cb(void *j, const ut64 k, const void *v) {
1444  const RzAnalysisXRef *xref = v;
1445  pj_o(j);
1446  pj_kn(j, "to", k);
1447  if (xref->type != RZ_ANALYSIS_XREF_TYPE_NULL) {
1448  char type[2] = { xref->type, '\0' };
1449  pj_ks(j, "type", type);
1450  }
1451  pj_end(j);
1452  return true;
1453 }
1454 
1455 static bool store_xrefs_list_cb(void *db, const ut64 k, const void *v) {
1456  char key[0x20];
1457  if (snprintf(key, sizeof(key), "0x%" PFMT64x, k) < 0) {
1458  return false;
1459  }
1460  PJ *j = pj_new();
1461  if (!j) {
1462  return false;
1463  }
1464  pj_a(j);
1465  HtUP *ht = (HtUP *)v;
1466  ht_up_foreach(ht, store_xref_cb, j);
1467  pj_end(j);
1468  sdb_set(db, key, pj_string(j), 0);
1469  pj_free(j);
1470  return true;
1471 }
1472 
1474  ht_up_foreach(analysis->ht_xrefs_from, store_xrefs_list_cb, db);
1475 }
1476 
1477 static bool xrefs_load_cb(void *user, const char *k, const char *v) {
1478  RzAnalysis *analysis = user;
1479 
1480  errno = 0;
1481  ut64 from = strtoull(k, NULL, 0);
1482  if (errno) {
1483  return false;
1484  }
1485 
1486  char *json_str = strdup(v);
1487  if (!json_str) {
1488  return true;
1489  }
1490  RzJson *json = rz_json_parse(json_str);
1491  if (!json || json->type != RZ_JSON_ARRAY) {
1492  free(json_str);
1493  return false;
1494  }
1495 
1496  const RzJson *child;
1497  for (child = json->children.first; child; child = child->next) {
1498  if (child->type != RZ_JSON_OBJECT) {
1499  goto error;
1500  }
1501  const RzJson *baby = rz_json_get(child, "to");
1502  if (!baby || baby->type != RZ_JSON_INTEGER) {
1503  goto error;
1504  }
1505  ut64 to = baby->num.u_value;
1506 
1508  baby = rz_json_get(child, "type");
1509  if (baby) {
1510  // must be a 1-char string
1511  if (baby->type != RZ_JSON_STRING || !baby->str_value[0] || baby->str_value[1]) {
1512  goto error;
1513  }
1514  switch (baby->str_value[0]) {
1519  type = baby->str_value[0];
1520  break;
1521  default:
1522  goto error;
1523  }
1524  }
1525 
1526  rz_analysis_xrefs_set(analysis, from, to, type);
1527  }
1528 
1529  rz_json_free(json);
1530  free(json_str);
1531 
1532  return true;
1533 error:
1534  rz_json_free(json);
1535  free(json_str);
1536  return false;
1537 }
1538 
1540  bool ret = sdb_foreach(db, xrefs_load_cb, analysis);
1541  if (!ret) {
1542  RZ_SERIALIZE_ERR(res, "xrefs parsing failed");
1543  }
1544  return ret;
1545 }
1546 
1548  rz_serialize_spaces_save(sdb_ns(db, "spaces", true), &analysis->meta_spaces);
1549 
1550  if (rz_interval_tree_empty(&analysis->meta)) {
1551  return;
1552  }
1553 
1554  PJ *j = pj_new();
1555  if (!j) {
1556  return;
1557  }
1558  char key[0x20];
1559  RzIntervalTreeIter it;
1560  RzAnalysisMetaItem *meta;
1561  ut64 addr = 0;
1562  size_t count = 0;
1563 
1564 #define FLUSH \
1565  pj_end(j); \
1566  if (snprintf(key, sizeof(key), "0x%" PFMT64x, addr) >= 0) { \
1567  sdb_set(db, key, pj_string(j), 0); \
1568  }
1569 
1570  rz_interval_tree_foreach (&analysis->meta, it, meta) {
1572  if (count && node->start != addr) {
1573  // new address
1574  FLUSH
1575  pj_reset(j);
1576  pj_a(j);
1577  count = 0;
1578  } else if (!count) {
1579  // first address
1580  pj_a(j);
1581  }
1582  count++;
1583  addr = node->start;
1584  pj_o(j);
1585  ut64 size = rz_meta_node_size(node);
1586  if (size != 1) {
1587  pj_kn(j, "size", size);
1588  }
1589  char type_str[2] = { 0 };
1590  switch (meta->type) {
1591  case RZ_META_TYPE_DATA:
1592  type_str[0] = 'd';
1593  break;
1594  case RZ_META_TYPE_CODE:
1595  type_str[0] = 'c';
1596  break;
1597  case RZ_META_TYPE_STRING:
1598  type_str[0] = 's';
1599  break;
1600  case RZ_META_TYPE_FORMAT:
1601  type_str[0] = 'f';
1602  break;
1603  case RZ_META_TYPE_MAGIC:
1604  type_str[0] = 'm';
1605  break;
1606  case RZ_META_TYPE_HIDE:
1607  type_str[0] = 'h';
1608  break;
1609  case RZ_META_TYPE_COMMENT:
1610  type_str[0] = 'C';
1611  break;
1613  type_str[0] = 'H';
1614  break;
1615  case RZ_META_TYPE_VARTYPE:
1616  type_str[0] = 't';
1617  break;
1618  default:
1619  break;
1620  }
1621  pj_ks(j, "type", type_str);
1622  if (meta->subtype) {
1623  pj_ki(j, "subtype", meta->subtype);
1624  }
1625  if (meta->str) {
1626  pj_ks(j, "str", meta->str);
1627  }
1628  if (meta->space) {
1629  pj_ks(j, "space", meta->space->name);
1630  }
1631  pj_end(j);
1632  }
1633  if (count) {
1634  FLUSH
1635  }
1636 #undef FLUSH
1637  pj_free(j);
1638 }
1639 
1640 static bool meta_load_cb(void *user, const char *k, const char *v) {
1641  RzAnalysis *analysis = user;
1642 
1643  errno = 0;
1644  ut64 addr = strtoull(k, NULL, 0);
1645  if (errno) {
1646  return false;
1647  }
1648 
1649  char *json_str = strdup(v);
1650  if (!json_str) {
1651  return true;
1652  }
1653  RzJson *json = rz_json_parse(json_str);
1654  if (!json || json->type != RZ_JSON_ARRAY) {
1655  free(json_str);
1656  return false;
1657  }
1658 
1659  const RzJson *child;
1660  for (child = json->children.first; child; child = child->next) {
1661  if (child->type != RZ_JSON_OBJECT) {
1662  goto error;
1663  }
1664 
1665  ut64 size = 1;
1667  const char *str = NULL;
1668  int subtype = 0;
1669  const char *space_name = NULL;
1670 
1671  const RzJson *baby;
1672  for (baby = child->children.first; baby; baby = baby->next) {
1673  if (!strcmp(baby->key, "size")) {
1674  if (baby->type == RZ_JSON_INTEGER) {
1675  size = baby->num.u_value;
1676  }
1677  continue;
1678  }
1679  if (!strcmp(baby->key, "type")) {
1680  // only single-char strings accepted
1681  if (baby->type == RZ_JSON_STRING && baby->str_value[0] && !baby->str_value[1]) {
1682  switch (baby->str_value[0]) {
1683  case 'd':
1685  break;
1686  case 'c':
1688  break;
1689  case 's':
1691  break;
1692  case 'f':
1694  break;
1695  case 'm':
1697  break;
1698  case 'h':
1700  break;
1701  case 'C':
1703  break;
1704  case 'H':
1706  break;
1707  case 't':
1709  break;
1710  default:
1711  break;
1712  }
1713  }
1714  continue;
1715  }
1716  if (!strcmp(baby->key, "str")) {
1717  if (baby->type == RZ_JSON_STRING) {
1718  str = baby->str_value;
1719  }
1720  continue;
1721  }
1722  if (!strcmp(baby->key, "subtype")) {
1723  if (baby->type == RZ_JSON_INTEGER) {
1724  subtype = (int)baby->num.s_value;
1725  }
1726  continue;
1727  }
1728  if (!strcmp(baby->key, "space")) {
1729  if (baby->type == RZ_JSON_STRING) {
1730  space_name = baby->str_value;
1731  }
1732  continue;
1733  }
1734  }
1735 
1736  if (type == RZ_META_TYPE_ANY || (type == RZ_META_TYPE_COMMENT && !str)) {
1737  continue;
1738  }
1739 
1741  if (!item) {
1742  break;
1743  }
1744  item->type = type;
1745  item->subtype = subtype;
1746  item->space = space_name ? rz_spaces_get(&analysis->meta_spaces, space_name) : NULL;
1747  item->str = str ? strdup(str) : NULL;
1748  if (str && !item->str) {
1749  free(item);
1750  continue;
1751  }
1752  ut64 end = addr + size - 1;
1753  if (end < addr) {
1754  end = UT64_MAX;
1755  }
1756  rz_interval_tree_insert(&analysis->meta, addr, end, item);
1757  }
1758 
1759  rz_json_free(json);
1760  free(json_str);
1761 
1762  return true;
1763 error:
1764  rz_json_free(json);
1765  free(json_str);
1766  return false;
1767 }
1768 
1770  Sdb *spaces_db = sdb_ns(db, "spaces", false);
1771  if (!spaces_db) {
1772  RZ_SERIALIZE_ERR(res, "missing meta spaces namespace");
1773  return false;
1774  }
1775  if (!rz_serialize_spaces_load(spaces_db, &analysis->meta_spaces, false, res)) {
1776  return false;
1777  }
1778  bool ret = sdb_foreach(db, meta_load_cb, analysis);
1779  if (!ret) {
1780  RZ_SERIALIZE_ERR(res, "meta parsing failed");
1781  }
1782  return ret;
1783 }
1784 
1785 typedef struct {
1786  const RzVector /*<const RzAnalysisAddrHintRecord>*/ *addr_hints;
1787  const char *arch;
1788  int bits;
1789  bool arch_set;
1790  bool bits_set;
1791 } HintsAtAddr;
1792 
1793 static void hints_at_addr_kv_free(HtUPKv *kv) {
1794  free(kv->value);
1795 }
1796 
1797 static HintsAtAddr *hints_at_addr(HtUP *acc, ut64 addr) {
1798  HintsAtAddr *h = ht_up_find(acc, addr, NULL);
1799  if (h) {
1800  return h;
1801  }
1802  h = RZ_NEW0(HintsAtAddr);
1803  if (!h) {
1804  return NULL;
1805  }
1806  ht_up_insert(acc, addr, h);
1807  return h;
1808 }
1809 
1810 static bool addr_hint_acc_cb(ut64 addr, const RzVector /*<const RzAnalysisAddrHintRecord>*/ *records, void *user) {
1811  HintsAtAddr *h = hints_at_addr(user, addr);
1812  if (!h) {
1813  return false;
1814  }
1815  h->addr_hints = records;
1816  return true;
1817 }
1818 
1819 static bool arch_hint_acc_cb(ut64 addr, RZ_NULLABLE const char *arch, void *user) {
1820  HintsAtAddr *h = hints_at_addr(user, addr);
1821  if (!h) {
1822  return false;
1823  }
1824  h->arch = arch;
1825  h->arch_set = true;
1826  return true;
1827 }
1828 
1829 static bool bits_hint_acc_cb(ut64 addr, int bits, void *user) {
1830  HintsAtAddr *h = hints_at_addr(user, addr);
1831  if (!h) {
1832  return false;
1833  }
1834  h->bits = bits;
1835  h->bits_set = true;
1836  return true;
1837 }
1838 
1839 static bool hints_acc_store_cb(void *user, const ut64 addr, const void *v) {
1840  const HintsAtAddr *h = v;
1841  char key[0x20];
1842  if (snprintf(key, sizeof(key), "0x%" PFMT64x, addr) < 0) {
1843  return false;
1844  }
1845  Sdb *db = user;
1846  PJ *j = pj_new();
1847  if (!j) {
1848  return false;
1849  }
1850  pj_o(j);
1851  if (h->arch_set) {
1852  pj_k(j, "arch");
1853  if (h->arch) {
1854  pj_s(j, h->arch);
1855  } else {
1856  pj_null(j);
1857  }
1858  }
1859  if (h->bits_set) {
1860  pj_ki(j, "bits", h->bits);
1861  }
1862  if (h->addr_hints) {
1864  rz_vector_foreach(h->addr_hints, record) {
1865  switch (record->type) {
1867  pj_ki(j, "immbase", record->immbase);
1868  break;
1870  pj_kn(j, "jump", record->jump);
1871  break;
1873  pj_kn(j, "fail", record->fail);
1874  break;
1876  pj_kn(j, "frame", record->stackframe);
1877  break;
1879  pj_kn(j, "ptr", record->ptr);
1880  break;
1882  pj_ki(j, "nword", record->nword);
1883  break;
1885  pj_kn(j, "ret", record->retval);
1886  break;
1888  pj_ki(j, "newbits", record->newbits);
1889  break;
1891  pj_kn(j, "size", record->size);
1892  break;
1894  pj_ks(j, "syntax", record->syntax);
1895  break;
1897  pj_ki(j, "optype", record->optype);
1898  break;
1900  pj_ks(j, "opcode", record->opcode);
1901  break;
1903  pj_ks(j, "toff", record->type_offset);
1904  break;
1906  pj_ks(j, "esil", record->esil);
1907  break;
1909  pj_kb(j, "high", true);
1910  break;
1912  pj_kn(j, "val", record->val);
1913  break;
1914  }
1915  }
1916  }
1917  pj_end(j);
1918  sdb_set(db, key, pj_string(j), 0);
1919  pj_free(j);
1920  return true;
1921 }
1922 
1924  HtUP /*<HintsAtAddr *>*/ *acc = ht_up_new(NULL, hints_at_addr_kv_free, NULL);
1928  ht_up_foreach(acc, hints_acc_store_cb, db);
1929  ht_up_free(acc);
1930 }
1931 
1932 enum {
1951 };
1952 
1953 typedef struct {
1956 } HintsLoadCtx;
1957 
1958 static bool hints_load_cb(void *user, const char *k, const char *v) {
1959  HintsLoadCtx *ctx = user;
1960  RzAnalysis *analysis = ctx->analysis;
1961 
1962  errno = 0;
1963  ut64 addr = strtoull(k, NULL, 0);
1964  if (errno) {
1965  return false;
1966  }
1967 
1968  char *json_str = strdup(v);
1969  if (!json_str) {
1970  return true;
1971  }
1972  RzJson *json = rz_json_parse(json_str);
1973  if (!json || json->type != RZ_JSON_OBJECT) {
1974  free(json_str);
1975  return false;
1976  }
1977 
1978  RZ_KEY_PARSER_JSON(ctx->parser, json, child, {
1979  case HINTS_FIELD_ARCH:
1980  rz_analysis_hint_set_arch(analysis, addr, child->type == RZ_JSON_STRING ? child->str_value : NULL);
1981  break;
1982  case HINTS_FIELD_BITS:
1983  rz_analysis_hint_set_bits(analysis, addr, child->type == RZ_JSON_INTEGER ? (int)child->num.s_value : 0);
1984  break;
1985  case HINTS_FIELD_IMMBASE:
1986  if (child->type != RZ_JSON_INTEGER) {
1987  break;
1988  }
1989  rz_analysis_hint_set_immbase(analysis, addr, (int)child->num.s_value);
1990  break;
1991  case HINTS_FIELD_JUMP:
1992  if (child->type != RZ_JSON_INTEGER) {
1993  break;
1994  }
1995  rz_analysis_hint_set_jump(analysis, addr, child->num.u_value);
1996  break;
1997  case HINTS_FIELD_FAIL:
1998  if (child->type != RZ_JSON_INTEGER) {
1999  break;
2000  }
2001  rz_analysis_hint_set_fail(analysis, addr, child->num.u_value);
2002  break;
2004  if (child->type != RZ_JSON_INTEGER) {
2005  break;
2006  }
2007  rz_analysis_hint_set_stackframe(analysis, addr, child->num.u_value);
2008  break;
2009  case HINTS_FIELD_PTR:
2010  if (child->type != RZ_JSON_INTEGER) {
2011  break;
2012  }
2013  rz_analysis_hint_set_pointer(analysis, addr, child->num.u_value);
2014  break;
2015  case HINTS_FIELD_NWORD:
2016  if (child->type != RZ_JSON_INTEGER) {
2017  break;
2018  }
2019  rz_analysis_hint_set_nword(analysis, addr, (int)child->num.s_value);
2020  break;
2021  case HINTS_FIELD_RET:
2022  if (child->type != RZ_JSON_INTEGER) {
2023  break;
2024  }
2025  rz_analysis_hint_set_ret(analysis, addr, child->num.u_value);
2026  break;
2027  case HINTS_FIELD_NEW_BITS:
2028  if (child->type != RZ_JSON_INTEGER) {
2029  break;
2030  }
2031  rz_analysis_hint_set_newbits(analysis, addr, (int)child->num.s_value);
2032  break;
2033  case HINTS_FIELD_SIZE:
2034  if (child->type != RZ_JSON_INTEGER) {
2035  break;
2036  }
2037  rz_analysis_hint_set_size(analysis, addr, child->num.u_value);
2038  break;
2039  case HINTS_FIELD_SYNTAX:
2040  if (child->type != RZ_JSON_STRING) {
2041  break;
2042  }
2043  rz_analysis_hint_set_syntax(analysis, addr, child->str_value);
2044  break;
2045  case HINTS_FIELD_OPTYPE:
2046  if (child->type != RZ_JSON_INTEGER) {
2047  break;
2048  }
2049  rz_analysis_hint_set_type(analysis, addr, (int)child->num.s_value);
2050  break;
2051  case HINTS_FIELD_OPCODE:
2052  if (child->type != RZ_JSON_STRING) {
2053  break;
2054  }
2055  rz_analysis_hint_set_opcode(analysis, addr, child->str_value);
2056  break;
2058  if (child->type != RZ_JSON_STRING) {
2059  break;
2060  }
2061  rz_analysis_hint_set_offset(analysis, addr, child->str_value);
2062  break;
2063  case HINTS_FIELD_ESIL:
2064  if (child->type != RZ_JSON_STRING) {
2065  break;
2066  }
2067  rz_analysis_hint_set_esil(analysis, addr, child->str_value);
2068  break;
2069  case HINTS_FIELD_HIGH:
2070  if (child->type != RZ_JSON_BOOLEAN || !child->num.u_value) {
2071  break;
2072  }
2073  rz_analysis_hint_set_high(analysis, addr);
2074  break;
2075  case HINTS_FIELD_VAL:
2076  if (child->type != RZ_JSON_INTEGER) {
2077  break;
2078  }
2079  rz_analysis_hint_set_val(analysis, addr, child->num.u_value);
2080  break;
2081  default:
2082  break;
2083  })
2084 
2085  rz_json_free(json);
2086  free(json_str);
2087 
2088  return true;
2089 }
2090 
2092  HintsLoadCtx ctx = {
2093  .analysis = analysis,
2094  .parser = rz_key_parser_new(),
2095  };
2096  bool ret;
2097  if (!ctx.parser) {
2098  RZ_SERIALIZE_ERR(res, "parser init failed");
2099  ret = false;
2100  goto beach;
2101  }
2102  rz_key_parser_add(ctx.parser, "arch", HINTS_FIELD_ARCH);
2103  rz_key_parser_add(ctx.parser, "bits", HINTS_FIELD_BITS);
2104  rz_key_parser_add(ctx.parser, "immbase", HINTS_FIELD_IMMBASE);
2105  rz_key_parser_add(ctx.parser, "jump", HINTS_FIELD_JUMP);
2106  rz_key_parser_add(ctx.parser, "fail", HINTS_FIELD_FAIL);
2107  rz_key_parser_add(ctx.parser, "frame", HINTS_FIELD_STACKFRAME);
2108  rz_key_parser_add(ctx.parser, "ptr", HINTS_FIELD_PTR);
2109  rz_key_parser_add(ctx.parser, "nword", HINTS_FIELD_NWORD);
2110  rz_key_parser_add(ctx.parser, "ret", HINTS_FIELD_RET);
2111  rz_key_parser_add(ctx.parser, "newbits", HINTS_FIELD_NEW_BITS);
2112  rz_key_parser_add(ctx.parser, "size", HINTS_FIELD_SIZE);
2113  rz_key_parser_add(ctx.parser, "syntax", HINTS_FIELD_SYNTAX);
2114  rz_key_parser_add(ctx.parser, "optype", HINTS_FIELD_OPTYPE);
2115  rz_key_parser_add(ctx.parser, "opcode", HINTS_FIELD_OPCODE);
2117  rz_key_parser_add(ctx.parser, "esil", HINTS_FIELD_ESIL);
2118  rz_key_parser_add(ctx.parser, "high", HINTS_FIELD_HIGH);
2119  rz_key_parser_add(ctx.parser, "val", HINTS_FIELD_VAL);
2120  ret = sdb_foreach(db, hints_load_cb, &ctx);
2121  if (!ret) {
2122  RZ_SERIALIZE_ERR(res, "hints parsing failed");
2123  }
2124 beach:
2125  rz_key_parser_free(ctx.parser);
2126  return ret;
2127 }
2128 
2130  sdb_copy(analysis->sdb_classes, db);
2131 }
2132 
2134  if (!sdb_ns(db, "attrs", false)) {
2135  RZ_SERIALIZE_ERR(res, "missing attrs namespace");
2136  return false;
2137  }
2138  sdb_reset(analysis->sdb_classes);
2139  sdb_reset(analysis->sdb_classes_attrs);
2140  sdb_copy(db, analysis->sdb_classes);
2141  return true;
2142 }
2143 
2145  rz_serialize_types_save(db, analysis->typedb);
2146 }
2147 
2149  return rz_serialize_types_load(db, analysis->typedb, res);
2150 }
2151 
2153  rz_serialize_callables_save(db, analysis->typedb);
2154 }
2155 
2157  return rz_serialize_callables_load(db, analysis->typedb, res);
2158 }
2159 
2161  rz_serialize_typelinks_save(db, analysis);
2162 }
2163 
2165  return rz_serialize_typelinks_load(db, analysis, res);
2166 }
2167 
2169  RzListIter *it;
2170  const char *imp;
2171  rz_list_foreach (analysis->imports, it, imp) {
2172  sdb_set(db, imp, "i", 0);
2173  }
2174 }
2175 
2176 static bool import_load_cb(void *user, const char *k, const char *v) {
2177  rz_analysis_add_import(user, k);
2178  return true;
2179 }
2180 
2182  return sdb_foreach(db, import_load_cb, analysis);
2183 }
2184 
2186  sdb_copy(analysis->sdb_cc, db);
2187 }
2188 
2190  sdb_copy(db, analysis->sdb_cc);
2191  return true;
2192 }
2193 
2195  rz_serialize_analysis_xrefs_save(sdb_ns(db, "xrefs", true), analysis);
2196  rz_serialize_analysis_blocks_save(sdb_ns(db, "blocks", true), analysis);
2197  rz_serialize_analysis_functions_save(sdb_ns(db, "functions", true), analysis);
2198  rz_serialize_analysis_function_noreturn_save(sdb_ns(db, "noreturn", true), analysis);
2199  rz_serialize_analysis_meta_save(sdb_ns(db, "meta", true), analysis);
2200  rz_serialize_analysis_hints_save(sdb_ns(db, "hints", true), analysis);
2201  rz_serialize_analysis_classes_save(sdb_ns(db, "classes", true), analysis);
2202  rz_serialize_analysis_types_save(sdb_ns(db, "types", true), analysis);
2203  rz_serialize_analysis_callables_save(sdb_ns(db, "callables", true), analysis);
2204  rz_serialize_analysis_typelinks_save(sdb_ns(db, "typelinks", true), analysis);
2205  rz_serialize_analysis_imports_save(sdb_ns(db, "imports", true), analysis);
2206  rz_serialize_analysis_cc_save(sdb_ns(db, "cc", true), analysis);
2207  rz_serialize_analysis_global_var_save(sdb_ns(db, "vars", true), analysis);
2208 }
2209 
2211  bool ret = false;
2212  RzSerializeAnalDiffParser diff_parser = rz_serialize_analysis_diff_parser_new();
2213  if (!diff_parser) {
2214  goto beach;
2215  }
2216 
2217  rz_analysis_purge(analysis);
2218 
2219  Sdb *subdb;
2220 #define SUB(ns, call) RZ_SERIALIZE_SUB_DO(db, subdb, res, ns, call, goto beach;)
2221  SUB("xrefs", rz_serialize_analysis_xrefs_load(subdb, analysis, res));
2222 
2223  SUB("blocks", rz_serialize_analysis_blocks_load(subdb, analysis, diff_parser, res));
2224 
2225  SUB("classes", rz_serialize_analysis_classes_load(subdb, analysis, res));
2226  SUB("types", rz_serialize_analysis_types_load(subdb, analysis, res));
2227  SUB("callables", rz_serialize_analysis_callables_load(subdb, analysis, res));
2228  SUB("typelinks", rz_serialize_analysis_typelinks_load(subdb, analysis, res));
2229 
2230  // All bbs have ref=1 now
2231  SUB("functions", rz_serialize_analysis_functions_load(subdb, analysis, diff_parser, res));
2232  SUB("noreturn", rz_serialize_analysis_function_noreturn_load(subdb, analysis, res));
2233  // BB's refs have increased if they are part of a function.
2234  // We must subtract from each to hold our invariant again.
2235  // If any block has ref=0 then, it should be deleted. But we can't do this while
2236  // iterating the RBTree, otherwise this will become a segfault cacophony, so we cache them.
2237  RzPVector orphaned_bbs;
2239  RBIter iter;
2240  RzAnalysisBlock *block;
2241  rz_rbtree_foreach (analysis->bb_tree, iter, block, RzAnalysisBlock, _rb) {
2242  if (block->ref <= 1) {
2243  rz_pvector_push(&orphaned_bbs, block);
2244  continue;
2245  }
2246  rz_analysis_block_unref(block);
2247  }
2248  rz_pvector_clear(&orphaned_bbs); // unrefs all
2249 
2250  SUB("meta", rz_serialize_analysis_meta_load(subdb, analysis, res));
2251  SUB("hints", rz_serialize_analysis_hints_load(subdb, analysis, res));
2252  SUB("imports", rz_serialize_analysis_imports_load(subdb, analysis, res));
2253  SUB("cc", rz_serialize_analysis_cc_load(subdb, analysis, res));
2254  SUB("vars", rz_serialize_analysis_global_var_load(subdb, analysis, res));
2255 
2256  ret = true;
2257 beach:
2259  return ret;
2260 }
RZ_API void rz_analysis_diff_free(RzAnalysisDiff *diff)
Definition: diff.c:22
RZ_API RZ_OWN RzAnalysisDiff * rz_analysis_diff_new(void)
Definition: diff.c:9
RZ_API void rz_analysis_function_add_block(RzAnalysisFunction *fcn, RzAnalysisBlock *bb)
Definition: function.c:264
RZ_API bool rz_analysis_add_function(RzAnalysis *analysis, RzAnalysisFunction *fcn)
Definition: function.c:129
RZ_API RzAnalysisFunction * rz_analysis_function_new(RzAnalysis *analysis)
Definition: function.c:70
RZ_API void rz_analysis_function_free(void *_fcn)
Definition: function.c:92
RZ_API void rz_analysis_add_import(RzAnalysis *analysis, const char *imp)
Definition: analysis.c:693
RZ_API void rz_analysis_purge(RzAnalysis *analysis)
Definition: analysis.c:433
lzma_index ** i
Definition: index.h:629
int jump(int a, int b)
Definition: bcj_test.c:35
int bits(struct state *s, int need)
Definition: blast.c:72
RZ_API RzAnalysisBlock * rz_analysis_get_block_at(RzAnalysis *analysis, ut64 addr)
Definition: block.c:90
RZ_API void rz_analysis_block_unref(RzAnalysisBlock *bb)
Definition: block.c:370
RZ_API RzAnalysisBlock * rz_analysis_create_block(RzAnalysis *analysis, ut64 addr, ut64 size)
Definition: block.c:174
RZ_API RZ_OWN RzType * rz_type_parse_string_single(RzTypeParser *parser, const char *code, char **error_msg)
Parses the single C type definition.
Definition: c_cpp_parser.c:309
static int value
Definition: cmd_api.c:93
#define RZ_API
#define INT_MAX
Definition: cp-demangle.c:131
#define NULL
Definition: cris-opc.c:27
cs_arch arch
Definition: cstool.c:13
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
uint16_t ut16
uint32_t ut32
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
RZ_API void rz_analysis_hint_set_val(RzAnalysis *a, ut64 addr, ut64 v)
Definition: hint.c:275
RZ_API void rz_analysis_hint_set_nword(RzAnalysis *a, ut64 addr, int nword)
Definition: hint.c:209
RZ_API void rz_analysis_hint_set_newbits(RzAnalysis *a, ut64 addr, int bits)
Definition: hint.c:221
RZ_API void rz_analysis_hint_set_high(RzAnalysis *a, ut64 addr)
Definition: hint.c:225
RZ_API void rz_analysis_addr_hints_foreach(RzAnalysis *analysis, RzAnalysisAddrHintRecordsCb cb, void *user)
Definition: hint.c:426
RZ_API void rz_analysis_hint_set_stackframe(RzAnalysis *a, ut64 addr, ut64 size)
Definition: hint.c:271
RZ_API void rz_analysis_hint_set_ret(RzAnalysis *a, ut64 addr, ut64 val)
Definition: hint.c:241
RZ_API void rz_analysis_hint_set_jump(RzAnalysis *a, ut64 addr, ut64 jump)
Definition: hint.c:213
RZ_API void rz_analysis_hint_set_opcode(RzAnalysis *a, ut64 addr, const char *opcode)
Definition: hint.c:251
RZ_API void rz_analysis_arch_hints_foreach(RzAnalysis *analysis, RzAnalysisArchHintCb cb, void *user)
Definition: hint.c:431
RZ_API void rz_analysis_hint_set_syntax(RzAnalysis *a, ut64 addr, const char *syn)
Definition: hint.c:245
RZ_API void rz_analysis_bits_hints_foreach(RzAnalysis *analysis, RzAnalysisBitsHintCb cb, void *user)
Definition: hint.c:442
RZ_API void rz_analysis_hint_set_fail(RzAnalysis *a, ut64 addr, ut64 fail)
Definition: hint.c:217
RZ_API void rz_analysis_hint_set_esil(RzAnalysis *a, ut64 addr, const char *esil)
Definition: hint.c:257
RZ_API void rz_analysis_hint_set_offset(RzAnalysis *a, ut64 addr, const char *typeoff)
Definition: hint.c:203
RZ_API void rz_analysis_hint_set_immbase(RzAnalysis *a, ut64 addr, int base)
Definition: hint.c:229
RZ_API void rz_analysis_hint_set_type(RzAnalysis *a, ut64 addr, int type)
Definition: hint.c:263
RZ_API void rz_analysis_hint_set_pointer(RzAnalysis *a, ut64 addr, ut64 ptr)
Definition: hint.c:237
RZ_API void rz_analysis_hint_set_size(RzAnalysis *a, ut64 addr, ut64 size)
Definition: hint.c:267
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
RZ_API bool rz_analysis_function_set_label(RzAnalysisFunction *fcn, const char *name, ut64 addr)
Definition: labels.c:20
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
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_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
RZ_API Sdb * sdb_ns(Sdb *s, const char *name, int create)
Definition: ns.c:186
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
unsigned long sop
Definition: regex2.h:62
@ RZ_ANALYSIS_DIFF_TYPE_MATCH
Definition: rz_analysis.h:206
@ RZ_ANALYSIS_DIFF_TYPE_UNMATCH
Definition: rz_analysis.h:207
RzAnalysisXRefType
Definition: rz_analysis.h:898
@ RZ_ANALYSIS_XREF_TYPE_CODE
Definition: rz_analysis.h:900
@ RZ_ANALYSIS_XREF_TYPE_NULL
Definition: rz_analysis.h:899
@ RZ_ANALYSIS_XREF_TYPE_STRING
Definition: rz_analysis.h:903
@ RZ_ANALYSIS_XREF_TYPE_CALL
Definition: rz_analysis.h:901
@ RZ_ANALYSIS_XREF_TYPE_DATA
Definition: rz_analysis.h:902
@ RZ_ANALYSIS_ADDR_HINT_TYPE_SYNTAX
Definition: rz_analysis.h:639
@ RZ_ANALYSIS_ADDR_HINT_TYPE_PTR
Definition: rz_analysis.h:634
@ RZ_ANALYSIS_ADDR_HINT_TYPE_SIZE
Definition: rz_analysis.h:638
@ RZ_ANALYSIS_ADDR_HINT_TYPE_STACKFRAME
Definition: rz_analysis.h:633
@ RZ_ANALYSIS_ADDR_HINT_TYPE_HIGH
Definition: rz_analysis.h:644
@ RZ_ANALYSIS_ADDR_HINT_TYPE_ESIL
Definition: rz_analysis.h:643
@ RZ_ANALYSIS_ADDR_HINT_TYPE_NEW_BITS
Definition: rz_analysis.h:637
@ RZ_ANALYSIS_ADDR_HINT_TYPE_TYPE_OFFSET
Definition: rz_analysis.h:642
@ RZ_ANALYSIS_ADDR_HINT_TYPE_JUMP
Definition: rz_analysis.h:631
@ RZ_ANALYSIS_ADDR_HINT_TYPE_OPTYPE
Definition: rz_analysis.h:640
@ RZ_ANALYSIS_ADDR_HINT_TYPE_RET
Definition: rz_analysis.h:636
@ RZ_ANALYSIS_ADDR_HINT_TYPE_IMMBASE
Definition: rz_analysis.h:630
@ RZ_ANALYSIS_ADDR_HINT_TYPE_NWORD
Definition: rz_analysis.h:635
@ RZ_ANALYSIS_ADDR_HINT_TYPE_FAIL
Definition: rz_analysis.h:632
@ RZ_ANALYSIS_ADDR_HINT_TYPE_OPCODE
Definition: rz_analysis.h:641
@ RZ_ANALYSIS_ADDR_HINT_TYPE_VAL
Definition: rz_analysis.h:645
RzAnalysisMetaType
Definition: rz_analysis.h:287
@ RZ_META_TYPE_VARTYPE
Definition: rz_analysis.h:297
@ RZ_META_TYPE_ANY
Definition: rz_analysis.h:288
@ RZ_META_TYPE_DATA
Definition: rz_analysis.h:289
@ RZ_META_TYPE_CODE
Definition: rz_analysis.h:290
@ RZ_META_TYPE_HIGHLIGHT
Definition: rz_analysis.h:296
@ RZ_META_TYPE_HIDE
Definition: rz_analysis.h:294
@ RZ_META_TYPE_MAGIC
Definition: rz_analysis.h:293
@ RZ_META_TYPE_STRING
Definition: rz_analysis.h:291
@ RZ_META_TYPE_COMMENT
Definition: rz_analysis.h:295
@ RZ_META_TYPE_FORMAT
Definition: rz_analysis.h:292
@ RZ_ANALYSIS_VAR_ACCESS_TYPE_READ
Definition: rz_analysis.h:713
@ RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE
Definition: rz_analysis.h:714
RzAnalysisVarKind
Definition: rz_analysis.h:702
@ RZ_ANALYSIS_VAR_KIND_REG
Definition: rz_analysis.h:703
@ RZ_ANALYSIS_VAR_KIND_SPV
Definition: rz_analysis.h:705
@ RZ_ANALYSIS_VAR_KIND_BPV
Definition: rz_analysis.h:704
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
RZ_API char * rz_base64_encode_dyn(const ut8 *bin, size_t sz)
Definition: ubase64.c:92
RZ_API int rz_base64_decode(ut8 *bout, const char *bin, int len)
Definition: ubase64.c:48
static bool rz_interval_tree_empty(RzIntervalTree *tree)
static RzIntervalNode * rz_interval_tree_iter_get(RzIntervalTreeIter *it)
RZ_API bool rz_interval_tree_insert(RzIntervalTree *tree, ut64 start, ut64 end, void *data)
Definition: intervaltree.c:121
#define rz_interval_tree_foreach(tree, it, dat)
RZ_API const RzJson * rz_json_get(const RzJson *json, const char *key)
Definition: json_parser.c:405
@ RZ_JSON_INTEGER
Definition: rz_json.h:33
@ RZ_JSON_ARRAY
Definition: rz_json.h:31
@ RZ_JSON_DOUBLE
Definition: rz_json.h:34
@ RZ_JSON_OBJECT
Definition: rz_json.h:30
@ RZ_JSON_BOOLEAN
Definition: rz_json.h:35
@ RZ_JSON_STRING
Definition: rz_json.h:32
RZ_API RzJson * rz_json_parse(char *text)
Definition: json_parser.c:382
RZ_API void rz_json_free(RzJson *js)
Definition: json_parser.c:45
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API PJ * pj_ko(PJ *j, const char *k)
Definition: pj.c:156
RZ_API PJ * pj_ka(PJ *j, const char *k)
Definition: pj.c:163
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_ki(PJ *j, const char *k, int d)
Definition: pj.c:149
RZ_API PJ * pj_k(PJ *j, const char *k)
Definition: pj.c:104
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 PJ * pj_i(PJ *j, int d)
Definition: pj.c:284
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_null(PJ *j)
Definition: pj.c:184
RZ_API PJ * pj_s(PJ *j, const char *k)
Definition: pj.c:197
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_n(PJ *j, ut64 n)
Definition: pj.c:252
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
RZ_API PJ * pj_kd(PJ *j, const char *k, double d)
Definition: pj.c:136
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
RZ_API void pj_reset(PJ *j)
Definition: pj.c:42
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
Definition: pj.c:128
#define rz_rbtree_foreach(root, it, data, struc, rb)
Definition: rz_rbtree.h:101
static void rz_key_parser_add(RzKeyParser *parser, const char *key, int val)
Definition: rz_serialize.h:56
HtPP RzKeyParser
Hashtable-based key parser to prevent strcmp chains.
Definition: rz_serialize.h:46
static RzKeyParser * rz_key_parser_new(void)
Definition: rz_serialize.h:48
#define RZ_SERIALIZE_ERR(res,...)
Push an error to the local RzSerializeResultInfo \res RzSerializeInfoResult *.
Definition: rz_serialize.h:33
#define RZ_KEY_PARSER_JSON(parser, json, child, body)
Iterate over all keys in a json object and call RZ_KEY_PARSER_SWITCH on each.
Definition: rz_serialize.h:82
static void rz_key_parser_free(RzKeyParser *parser)
Definition: rz_serialize.h:52
RZ_API RzSpace * rz_spaces_get(RzSpaces *sp, const char *name)
Definition: spaces.c:82
RZ_API bool rz_serialize_spaces_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzSpaces *spaces, bool load_name, RZ_NULLABLE RzSerializeResultInfo *res)
RZ_API void rz_serialize_spaces_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzSpaces *spaces)
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
RZ_API const char * rz_str_constpool_get(RzStrConstPool *pool, const char *str)
Definition: str_constpool.c:19
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
RzTypeCond
Type Conditions.
Definition: rz_type.h:182
@ RZ_TYPE_COND_LS
Unsigned lower or same Less than or equal.
Definition: rz_type.h:198
@ RZ_TYPE_COND_AL
Always executed (no condition)
Definition: rz_type.h:183
#define RZ_NULLABLE
Definition: rz_types.h:65
#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 PFMT64x
Definition: rz_types.h:393
#define st64
Definition: rz_types_base.h:10
#define UT64_MAX
Definition: rz_types_base.h:86
#define ST64_MAX
Definition: rz_types_base.h:84
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
void(* RzPVectorFree)(void *e)
Definition: rz_vector.h:43
static bool rz_pvector_empty(RzPVector *vec)
Definition: rz_vector.h:246
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void rz_vector_fini(RzVector *vec)
Definition: vector.c:61
RZ_API void rz_vector_init(RzVector *vec, size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:33
static bool rz_vector_empty(const RzVector *vec)
Definition: rz_vector.h:74
RZ_API void rz_pvector_clear(RzPVector *vec)
Definition: vector.c:326
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611
RZ_API void sdb_reset(Sdb *s)
Definition: sdb.c:433
RZ_API void sdb_copy(Sdb *src, Sdb *dst)
Definition: sdb.c:1084
RZ_API bool sdb_foreach(Sdb *s, SdbForeachCallback cb, void *user)
Definition: sdb.c:758
RZ_API bool rz_serialize_analysis_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
RZ_API RZ_NULLABLE RzAnalysisVar * rz_serialize_analysis_var_load(RZ_NONNULL RzAnalysisFunction *fcn, RZ_NONNULL RzSerializeAnalVarParser parser, RZ_NONNULL const RzJson *json)
RZ_API void rz_serialize_analysis_case_op_save(RZ_NONNULL PJ *j, RZ_NONNULL RzAnalysisCaseOp *op)
#define FLUSH
static void function_store(RZ_NONNULL Sdb *db, const char *key, RzAnalysisFunction *function)
RZ_API bool rz_serialize_analysis_hints_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
static void block_store(RZ_NONNULL Sdb *db, const char *key, RzAnalysisBlock *block)
RZ_API bool rz_serialize_analysis_cc_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
static bool hints_load_cb(void *user, const char *k, const char *v)
RZ_API void rz_serialize_analysis_imports_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
RZ_API RzAnalysisSwitchOp * rz_serialize_analysis_switch_op_load(RZ_NONNULL const RzJson *json)
RZ_API bool rz_serialize_analysis_blocks_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RzSerializeAnalDiffParser diff_parser, RZ_NULLABLE RzSerializeResultInfo *res)
RZ_API bool rz_serialize_analysis_imports_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
RZ_API void rz_serialize_analysis_diff_save(RZ_NONNULL PJ *j, RZ_NONNULL RzAnalysisDiff *diff)
RZ_API void rz_serialize_analysis_hints_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
static bool store_xrefs_list_cb(void *db, const ut64 k, const void *v)
static bool global_var_load_cb(void *user, const char *k, const char *v)
RZ_API bool rz_serialize_analysis_global_var_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
RZ_API void rz_serialize_analysis_global_var_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *anal)
@ HINTS_FIELD_VAL
@ HINTS_FIELD_SYNTAX
@ HINTS_FIELD_IMMBASE
@ HINTS_FIELD_ESIL
@ HINTS_FIELD_OPCODE
@ HINTS_FIELD_BITS
@ HINTS_FIELD_HIGH
@ HINTS_FIELD_STACKFRAME
@ HINTS_FIELD_NEW_BITS
@ HINTS_FIELD_FAIL
@ HINTS_FIELD_PTR
@ HINTS_FIELD_NWORD
@ HINTS_FIELD_SIZE
@ HINTS_FIELD_TYPE_OFFSET
@ HINTS_FIELD_OPTYPE
@ HINTS_FIELD_RET
@ HINTS_FIELD_JUMP
@ HINTS_FIELD_ARCH
static bool function_load_cb(void *user, const char *k, const char *v)
static bool bits_hint_acc_cb(ut64 addr, int bits, void *user)
RZ_API void rz_serialize_analysis_typelinks_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
RZ_API void rz_serialize_analysis_switch_op_save(RZ_NONNULL PJ *j, RZ_NONNULL RzAnalysisSwitchOp *op)
RZ_API void rz_serialize_analysis_classes_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
RZ_API void rz_serialize_analysis_function_noreturn_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
RZ_API RzSerializeAnalDiffParser rz_serialize_analysis_diff_parser_new(void)
RZ_API RZ_NULLABLE RzAnalysisDiff * rz_serialize_analysis_diff_load(RZ_NONNULL RzSerializeAnalDiffParser parser, RZ_NONNULL const RzJson *json)
static HintsAtAddr * hints_at_addr(HtUP *acc, ut64 addr)
RZ_API RzSerializeAnalVarParser rz_serialize_analysis_var_parser_new(void)
static bool block_load_cb(void *user, const char *k, const char *v)
RZ_API void rz_serialize_analysis_functions_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
RZ_API void rz_serialize_analysis_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
RZ_API void rz_serialize_analysis_var_parser_free(RzSerializeAnalVarParser parser)
@ GLOBAL_VAR_FIELD_CONSTRS
@ GLOBAL_VAR_FIELD_ADDR
@ GLOBAL_VAR_FIELD_NAME
@ GLOBAL_VAR_FIELD_TYPE
RZ_API RzSerializeAnalGlobalVarParser rz_serialize_analysis_global_var_parser_new(void)
RZ_API void rz_serialize_analysis_var_save(RZ_NONNULL PJ *j, RZ_NONNULL RzAnalysisVar *var)
RZ_API void rz_serialize_analysis_callables_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
static bool addr_hint_acc_cb(ut64 addr, const RzVector *records, void *user)
RZ_API bool rz_serialize_analysis_classes_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
static bool arch_hint_acc_cb(ut64 addr, RZ_NULLABLE const char *arch, void *user)
@ BLOCK_FIELD_JUMP
@ BLOCK_FIELD_NINSTR
@ BLOCK_FIELD_TRACED
@ BLOCK_FIELD_SIZE
@ BLOCK_FIELD_SWITCH_OP
@ BLOCK_FIELD_COLORIZE
@ BLOCK_FIELD_PARENT_STACKPTR
@ BLOCK_FIELD_DIFF
@ BLOCK_FIELD_CMPVAL
@ BLOCK_FIELD_FAIL
@ BLOCK_FIELD_FINGERPRINT
@ BLOCK_FIELD_STACKPTR
@ BLOCK_FIELD_CMPREG
@ BLOCK_FIELD_OP_POS
RZ_API bool rz_serialize_analysis_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
RZ_API void rz_serialize_analysis_diff_parser_free(RzSerializeAnalDiffParser parser)
RZ_API bool rz_serialize_analysis_callables_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
RZ_API void rz_serialize_analysis_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
RZ_API bool rz_serialize_analysis_typelinks_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
RZ_API bool rz_serialize_analysis_xrefs_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
static bool store_label_cb(void *j, const ut64 k, const void *v)
RZ_API void rz_serialize_analysis_global_var_parser_free(RzSerializeAnalGlobalVarParser parser)
@ FUNCTION_FIELD_DIFF
@ FUNCTION_FIELD_MAXSTACK
@ FUNCTION_FIELD_NORETURN
@ FUNCTION_FIELD_TYPE
@ FUNCTION_FIELD_LABELS
@ FUNCTION_FIELD_BP_FRAME
@ FUNCTION_FIELD_FINGERPRINT
@ FUNCTION_FIELD_NAME
@ FUNCTION_FIELD_VARS
@ FUNCTION_FIELD_STACK
@ FUNCTION_FIELD_BITS
@ FUNCTION_FIELD_BBS
@ FUNCTION_FIELD_PURE
@ FUNCTION_FIELD_CC
@ FUNCTION_FIELD_NINSTR
@ FUNCTION_FIELD_BP_OFF
@ FUNCTION_FIELD_IMPORTS
static bool import_load_cb(void *user, const char *k, const char *v)
@ DIFF_FIELD_TYPE
@ DIFF_FIELD_NAME
@ DIFF_FIELD_DIST
@ DIFF_FIELD_SIZE
@ DIFF_FIELD_ADDR
RZ_API bool rz_serialize_analysis_functions_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RzSerializeAnalDiffParser diff_parser, RZ_NULLABLE RzSerializeResultInfo *res)
static void hints_at_addr_kv_free(HtUPKv *kv)
static bool xrefs_load_cb(void *user, const char *k, const char *v)
RZ_API void rz_serialize_analysis_cc_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
static bool hints_acc_store_cb(void *user, const ut64 addr, const void *v)
RZ_API bool rz_serialize_analysis_meta_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
static bool meta_load_cb(void *user, const char *k, const char *v)
@ VAR_FIELD_REG
@ VAR_FIELD_CONSTRS
@ VAR_FIELD_DELTA
@ VAR_FIELD_TYPE
@ VAR_FIELD_NAME
@ VAR_FIELD_KIND
@ VAR_FIELD_ARG
@ VAR_FIELD_COMMENT
@ VAR_FIELD_ACCS
RZ_API bool rz_serialize_analysis_function_noreturn_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res)
static bool store_xref_cb(void *j, const ut64 k, const void *v)
RZ_API void rz_serialize_analysis_xrefs_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
RZ_API void rz_serialize_analysis_blocks_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
RZ_API void rz_serialize_analysis_meta_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis)
#define SUB(ns, call)
RZ_API bool rz_serialize_callables_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzTypeDB *typedb, RZ_NULLABLE RzSerializeResultInfo *res)
Loads the callable types from SDB.
RZ_API void rz_serialize_callables_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzTypeDB *typedb)
Saves the callable types into SDB.
RZ_API void rz_serialize_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL const RzTypeDB *typedb)
Saves the types into SDB.
RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzTypeDB *typedb, RZ_NULLABLE RzSerializeResultInfo *res)
Loads the types from SDB.
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
Definition: sfsocketcall.h:123
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
static int
Definition: sfsocketcall.h:114
int size_t
Definition: sftypes.h:40
#define h(i)
Definition: sha256.c:48
#define SIZE_MAX
RzKeyParser * parser
RzAnalysis * analysis
RzSerializeAnalDiffParser diff_parser
RzKeyParser * parser
RzSerializeAnalDiffParser diff_parser
RzSerializeAnalVarParser var_parser
RzKeyParser * parser
RzAnalysis * analysis
const char * arch
const RzVector * addr_hints
RzAnalysis * analysis
RzKeyParser * parser
Definition: z80asm.h:102
Definition: rz_pj.h:12
const char * cmpreg
Definition: rz_analysis.h:883
RzAnalysisSwitchOp * switch_op
Definition: rz_analysis.h:874
RzAnalysisDiff * diff
Definition: rz_analysis.h:872
const RzSpace * space
Definition: rz_analysis.h:306
RzAnalysisMetaType type
Definition: rz_analysis.h:302
RzAnalysisXRefType type
Definition: rz_analysis.h:909
RzIntervalTree meta
Definition: rz_analysis.h:600
RzSpaces meta_spaces
Definition: rz_analysis.h:601
Global variables.
Definition: rz_analysis.h:744
RzType * type
type of the variable
Definition: rz_analysis.h:748
ut64 addr
address of the global variable
Definition: rz_analysis.h:747
char * name
name of the variable
Definition: rz_analysis.h:746
RzNum * num
Definition: rz_core.h:316
struct rz_json_t::@304::@307 children
const char * str_value
Definition: rz_json.h:42
const char * key
Definition: rz_json.h:40
struct rz_json_t * next
Definition: rz_json.h:56
RzJsonType type
Definition: rz_json.h:39
struct rz_json_t::@304::@306 num
char * name
Definition: rz_spaces.h:29
type constrained by the type conditions
Definition: rz_type.h:209
RzTypeCond cond
Definition: rz_type.h:210
Definition: sdb.h:63
RZ_API void rz_analysis_switch_op_free(RzAnalysisSwitchOp *swop)
Definition: switch.c:42
RZ_API RzAnalysisSwitchOp * rz_analysis_switch_op_new(ut64 addr, ut64 min_val, ut64 max_val, ut64 def_val)
Definition: switch.c:21
RZ_API RzAnalysisCaseOp * rz_analysis_switch_op_add_case(RzAnalysisSwitchOp *swop, ut64 addr, ut64 value, ut64 jump)
Definition: switch.c:49
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
Definition: type.c:1273
RZ_API RZ_OWN char * rz_type_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the type C representation.
Definition: type.c:817
Definition: dis.c:32
Definition: tar.h:52
void error(const char *msg)
Definition: untgz.c:593
RZ_API void rz_analysis_var_set_access(RzAnalysisVar *var, const char *reg, ut64 access_addr, int access_type, st64 stackptr)
Definition: var.c:441
RZ_API RZ_BORROW RzAnalysisVar * rz_analysis_function_set_var(RzAnalysisFunction *fcn, int delta, char kind, RZ_BORROW RZ_NULLABLE const RzType *type, int size, bool isarg, RZ_NONNULL const char *name)
Definition: var.c:111
RZ_API void rz_analysis_var_add_constraint(RzAnalysisVar *var, RZ_BORROW RzTypeConstraint *constraint)
Definition: var.c:524
RZ_API void rz_analysis_var_global_set_type(RzAnalysisVarGlobal *glob, RZ_NONNULL RZ_BORROW RzType *type)
Set the type of the global variable.
Definition: var_global.c:302
RZ_API RZ_OWN RzAnalysisVarGlobal * rz_analysis_var_global_new(RZ_NONNULL const char *name, ut64 addr)
Create a new instance of global variable.
Definition: var_global.c:15
RZ_API RZ_OWN bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *global_var)
Add the global variable into hashtable.
Definition: var_global.c:46
RZ_API void rz_analysis_var_global_add_constraint(RzAnalysisVarGlobal *glob, RzTypeConstraint *constraint)
Add a constaint to global variable.
Definition: var_global.c:320
static st64 delta
Definition: vmenus.c:2425
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static char * regname(int reg)
Definition: dis.c:71
RZ_API bool rz_analysis_xrefs_set(RzAnalysis *analysis, ut64 from, ut64 to, RzAnalysisXRefType type)
Definition: xrefs.c:117
static int addr
Definition: z80asm.c:58