Rizin
unix-like reverse engineering framework and cli tools
dsession.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017 rkx1209 <rkx1209dev@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_debug.h>
5 #include <rz_util/rz_json.h>
6 
7 #define CMP_CNUM_REG(x, y) ((x) >= ((RzDebugChangeReg *)y)->cnum ? 1 : -1)
8 #define CMP_CNUM_MEM(x, y) ((x) >= ((RzDebugChangeMem *)y)->cnum ? 1 : -1)
9 #define CMP_CNUM_CHKPT(x, y) ((x) >= ((RzDebugCheckpoint *)y)->cnum ? 1 : -1)
10 
12  if (session) {
13  rz_vector_free(session->checkpoints);
14  ht_up_free(session->registers);
15  ht_up_free(session->memory);
16  RZ_FREE(session);
17  }
18 }
19 
20 static void rz_debug_checkpoint_fini(void *element, void *user) {
21  RzDebugCheckpoint *checkpoint = element;
22  size_t i;
23  for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
24  rz_reg_arena_free(checkpoint->arena[i]);
25  }
26  rz_list_free(checkpoint->snaps);
27 }
28 
29 static void htup_vector_free(HtUPKv *kv) {
30  rz_vector_free(kv->value);
31 }
32 
35  if (!session) {
36  return NULL;
37  }
38 
40  if (!session->checkpoints) {
41  rz_debug_session_free(session);
42  return NULL;
43  }
44  session->registers = ht_up_new(NULL, htup_vector_free, NULL);
45  if (!session->registers) {
46  rz_debug_session_free(session);
47  return NULL;
48  }
49  session->memory = ht_up_new(NULL, htup_vector_free, NULL);
50  if (!session->memory) {
51  rz_debug_session_free(session);
52  return NULL;
53  }
54 
55  return session;
56 }
57 
60  size_t i;
61  RzDebugCheckpoint checkpoint = { 0 };
62 
63  // Save current registers arena iter
65  for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
67  RzRegArena *b = rz_reg_arena_new(a->size);
68  rz_mem_copy(b->bytes, b->size, a->bytes, a->size);
69  checkpoint.arena[i] = b;
70  }
71 
72  // Save current memory maps
74  if (!checkpoint.snaps) {
75  return false;
76  }
78  RzDebugMap *map;
80  rz_list_foreach (dbg->maps, iter, map) {
81  if ((map->perm & RZ_PERM_RW) == RZ_PERM_RW) {
83  if (snap) {
84  rz_list_append(checkpoint.snaps, snap);
85  }
86  }
87  }
88 
89  checkpoint.cnum = dbg->session->cnum;
90  rz_vector_push(dbg->session->checkpoints, &checkpoint);
91 
92  // Add PC register change so we can check for breakpoints when continue [back]
94  ut64 data = rz_reg_get_value(dbg->reg, ripc);
96 
97  return true;
98 }
99 
101  size_t i;
102  for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
104  RzRegArena *b = dbg->reg->regset[i].arena;
105  if (a && b && a->bytes && b->bytes) {
106  memcpy(b->bytes, a->bytes, a->size);
107  }
108  }
109 }
110 
111 static void _set_register(RzDebug *dbg, RzRegItem *ri, ut32 cnum) {
112  RzVector *vreg = ht_up_find(dbg->session->registers, ri->offset | (ri->arena << 16), NULL);
113  if (!vreg) {
114  return;
115  }
116  size_t index;
117  rz_vector_upper_bound(vreg, cnum, index, CMP_CNUM_REG);
118  if (index > 0 && index <= vreg->len) {
119  RzDebugChangeReg *reg = rz_vector_index_ptr(vreg, index - 1);
120  if (reg->cnum > dbg->session->cur_chkpt->cnum) {
121  rz_reg_set_value(dbg->reg, ri, reg->data);
122  }
123  }
124 }
125 
127  RzListIter *iter;
128  RzRegItem *ri;
130  rz_list_foreach (dbg->reg->allregs, iter, ri) {
131  _set_register(dbg, ri, cnum);
132  }
133 }
134 
136  RzListIter *iter;
137  RzDebugSnap *snap;
138  rz_list_foreach (dbg->session->cur_chkpt->snaps, iter, snap) {
139  dbg->iob.write_at(dbg->iob.io, snap->addr, snap->data, snap->size);
140  }
141 }
142 
143 static bool _restore_memory_cb(void *user, const ut64 key, const void *value) {
144  size_t index;
145  RzDebug *dbg = user;
146  RzVector *vmem = (RzVector *)value;
147 
149  if (index > 0 && index <= vmem->len) {
150  RzDebugChangeMem *mem = rz_vector_index_ptr(vmem, index - 1);
151  if (mem->cnum > dbg->session->cur_chkpt->cnum) {
152  dbg->iob.write_at(dbg->iob.io, key, &mem->data, 1);
153  }
154  }
155  return true;
156 }
157 
158 static void _restore_memory(RzDebug *dbg, ut32 cnum) {
160  ht_up_foreach(dbg->session->memory, _restore_memory_cb, dbg);
161 }
162 
164  RzDebugCheckpoint *checkpoint = NULL;
165  size_t index;
166  rz_vector_upper_bound(session->checkpoints, cnum, index, CMP_CNUM_CHKPT);
167  if (index > 0 && index <= session->checkpoints->len) {
168  checkpoint = rz_vector_index_ptr(session->checkpoints, index - 1);
169  }
170  return checkpoint;
171 }
172 
174  // Set checkpoint for initial registers and memory
176 
177  // Restore registers
178  _restore_registers(dbg, cnum);
180 
181  // Restore memory
182  _restore_memory(dbg, cnum);
183 }
184 
186  RzHashSize dsize;
187  RzListIter *iter;
188  RzDebugMap *map;
190  rz_list_foreach (dbg->maps, iter, map) {
191  if ((map->perm & RZ_PERM_RW) == RZ_PERM_RW) {
193  if (!snap) {
194  return;
195  }
196 
197  ut8 *hash = rz_debug_snap_get_hash(dbg, snap, &dsize);
198  if (!hash) {
199  rz_debug_snap_free(snap);
200  return;
201  }
202 
203  char *hexstr = rz_hex_bin2strdup(hash, dsize);
204  if (!hexstr) {
205  free(hash);
206  rz_debug_snap_free(snap);
207  return;
208  }
209  dbg->cb_printf("%s: %s\n", snap->name, hexstr);
210 
211  free(hexstr);
212  free(hash);
213  rz_debug_snap_free(snap);
214  }
215  }
216 }
217 
219  RzVector *vreg = ht_up_find(session->registers, offset | (arena << 16), NULL);
220  if (!vreg) {
221  vreg = rz_vector_new(sizeof(RzDebugChangeReg), NULL, NULL);
222  if (!vreg) {
223  eprintf("Error: creating a register vector.\n");
224  return false;
225  }
226  ht_up_insert(session->registers, offset | (arena << 16), vreg);
227  }
228  RzDebugChangeReg reg = { session->cnum, data };
229  rz_vector_push(vreg, &reg);
230  return true;
231 }
232 
234  RzVector *vmem = ht_up_find(session->memory, addr, NULL);
235  if (!vmem) {
236  vmem = rz_vector_new(sizeof(RzDebugChangeMem), NULL, NULL);
237  if (!vmem) {
238  eprintf("Error: creating a memory vector.\n");
239  return false;
240  }
241  ht_up_insert(session->memory, addr, vmem);
242  }
243  RzDebugChangeMem mem = { session->cnum, data };
244  rz_vector_push(vmem, &mem);
245  return true;
246 }
247 
248 /* Save and Load Session */
249 
250 // 0x<addr>=[<RzDebugChangeReg>]
251 static bool serialize_register_cb(void *db, const ut64 k, const void *v) {
253  RzVector *vreg = (RzVector *)v;
254  PJ *j = pj_new();
255  if (!j) {
256  return false;
257  }
258  pj_a(j);
259 
260  rz_vector_foreach(vreg, reg) {
261  pj_o(j);
262  pj_kN(j, "cnum", reg->cnum);
263  pj_kn(j, "data", reg->data);
264  pj_end(j);
265  }
266 
267  pj_end(j);
268  sdb_set(db, sdb_fmt("0x%" PFMT64x, k), pj_string(j), 0);
269  pj_free(j);
270  return true;
271 }
272 
273 static void serialize_registers(Sdb *db, HtUP *registers) {
274  ht_up_foreach(registers, serialize_register_cb, db);
275 }
276 
277 // 0x<addr>={"size":<size_t>, "a":[<RzDebugChangeMem>]}},
278 static bool serialize_memory_cb(void *db, const ut64 k, const void *v) {
280  RzVector *vmem = (RzVector *)v;
281  PJ *j = pj_new();
282  if (!j) {
283  return false;
284  }
285  pj_a(j);
286 
287  rz_vector_foreach(vmem, mem) {
288  pj_o(j);
289  pj_kN(j, "cnum", mem->cnum);
290  pj_kn(j, "data", mem->data);
291  pj_end(j);
292  }
293 
294  pj_end(j);
295  sdb_set(db, sdb_fmt("0x%" PFMT64x, k), pj_string(j), 0);
296  pj_free(j);
297  return true;
298 }
299 
300 static void serialize_memory(Sdb *db, HtUP *memory) {
301  ht_up_foreach(memory, serialize_memory_cb, db);
302 }
303 
304 static void serialize_checkpoints(Sdb *db, RzVector *checkpoints) {
305  size_t i;
306  RzDebugCheckpoint *chkpt;
307  RzDebugSnap *snap;
308  RzListIter *iter;
309 
310  rz_vector_foreach(checkpoints, chkpt) {
311  // 0x<cnum>={
312  // registers:{"<RzRegisterType>":<RzRegArena>, ...},
313  // snaps:{"size":<size_t>, "a":[<RzDebugSnap>]}
314  // }
315  PJ *j = pj_new();
316  if (!j) {
317  return;
318  }
319  pj_o(j);
320 
321  // Serialize RzRegArena to "registers"
322  // {"size":<int>, "bytes":"<base64>"}
323  pj_ka(j, "registers");
324  for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
325  RzRegArena *arena = chkpt->arena[i];
326  if (arena->bytes) {
327  pj_o(j);
328  pj_kn(j, "arena", i);
329  char *ebytes = sdb_encode((const void *)arena->bytes, arena->size);
330  pj_ks(j, "bytes", ebytes);
331  free(ebytes);
332  pj_kn(j, "size", arena->size);
333  pj_end(j);
334  }
335  }
336  pj_end(j);
337 
338  // Serialize RzDebugSnap to "snaps"
339  // {"name":<str>, "addr":<ut64>, "addr_end":<ut64>, "size":<ut64>,
340  // "data":"<base64>", "perm":<int>, "user":<int>, "shared":<bool>}
341  pj_ka(j, "snaps");
342  rz_list_foreach (chkpt->snaps, iter, snap) {
343  pj_o(j);
344  pj_ks(j, "name", snap->name);
345  pj_kn(j, "addr", snap->addr);
346  pj_kn(j, "addr_end", snap->addr_end);
347  pj_kn(j, "size", snap->size);
348  char *edata = sdb_encode((const void *)snap->data, snap->size);
349  if (!edata) {
350  pj_free(j);
351  return;
352  }
353  pj_ks(j, "data", edata);
354  free(edata);
355  pj_kn(j, "perm", snap->perm);
356  pj_kn(j, "user", snap->user);
357  pj_kb(j, "shared", snap->shared);
358  pj_end(j);
359  }
360  pj_end(j);
361 
362  pj_end(j);
363  sdb_set(db, sdb_fmt("0x%x", chkpt->cnum), pj_string(j), 0);
364  pj_free(j);
365  }
366 }
367 
368 /*
369  * SDB Format:
370  *
371  * /
372  * maxcnum=<maxcnum>
373  *
374  * /registers
375  * 0x<addr>={"size":<size_t>, "a":[<RzDebugChangeReg>]}
376  *
377  * /memory
378  * 0x<addr>={"size":<size_t>, "a":[<RzDebugChangeMem>]}
379  *
380  * /checkpoints
381  * 0x<cnum>={
382  * registers:{"<RzRegisterType>":<RzRegArena>, ...},
383  * snaps:{"size":<size_t>, "a":[<RzDebugSnap>]}
384  * }
385  *
386  * RzDebugChangeReg JSON:
387  * {"cnum":<int>, "data":<ut64>}
388  *
389  * RzDebugChangeMem JSON:
390  * {"cnum":<int>, "data":<ut8>}
391  *
392  * RzRegArena JSON:
393  * {"size":<int>, "bytes":"<base64>"}
394  *
395  * RzDebugSnap JSON:
396  * {"name":<str>, "addr":<ut64>, "addr_end":<ut64>, "size":<ut64>,
397  * "data":"<base64>", "perm":<int>, "user":<int>, "shared":<bool>}
398  *
399  * Notes:
400  * - This mostly follows rz-db-style serialization
401  */
403  sdb_num_set(db, "maxcnum", session->maxcnum, 0);
404  serialize_registers(sdb_ns(db, "registers", true), session->registers);
405  serialize_memory(sdb_ns(db, "memory", true), session->memory);
406  serialize_checkpoints(sdb_ns(db, "checkpoints", true), session->checkpoints);
407 }
408 
409 static bool session_sdb_save(Sdb *db, const char *path) {
410  char *filename;
411  if (!rz_file_is_directory(path)) {
412  eprintf("Error: %s is not a directory\n", path);
413  return false;
414  }
415 
416  filename = rz_str_newf("%s%ssession.sdb", path, RZ_SYS_DIR);
417  sdb_file(db, filename);
418  if (!sdb_sync(db)) {
419  eprintf("Failed to sync session to %s\n", filename);
420  free(filename);
421  sdb_close(db);
422  return false;
423  }
424  free(filename);
425  sdb_close(db);
426 
427  SdbListIter *it;
428  SdbNs *ns;
429  ls_foreach (db->ns, it, ns) {
430  char *filename = rz_str_newf("%s%s%s.sdb", path, RZ_SYS_DIR, ns->name);
431  sdb_file(ns->sdb, filename);
432  if (!sdb_sync(ns->sdb)) {
433  eprintf("Failed to sync %s to %s\n", ns->name, filename);
434  free(filename);
435  sdb_close(ns->sdb);
436  return false;
437  }
438  free(filename);
439  sdb_close(ns->sdb);
440  }
441 
442  return true;
443 }
444 
445 RZ_API bool rz_debug_session_save(RzDebugSession *session, const char *path) {
446  Sdb *db = sdb_new0();
447  if (!db) {
448  return false;
449  }
450  rz_debug_session_serialize(session, db);
451 
452  if (!session_sdb_save(db, path)) {
453  sdb_free(db);
454  return false;
455  }
456  sdb_free(db);
457  return true;
458 }
459 
460 #define CHECK_TYPE(v, t) \
461  if (!v || v->type != t) \
462  continue
463 
464 static bool deserialize_memory_cb(void *user, const char *addr, const char *v) {
465  RzJson *child;
466  char *json_str = strdup(v);
467  if (!json_str) {
468  return true;
469  }
470  RzJson *reg_json = rz_json_parse(json_str);
471  if (!reg_json || reg_json->type != RZ_JSON_ARRAY) {
472  free(json_str);
473  return true;
474  }
475 
476  HtUP *memory = user;
477  // Insert a new vector into `memory` HtUP at `addr`
478  RzVector *vmem = rz_vector_new(sizeof(RzDebugChangeMem), NULL, NULL);
479  if (!vmem) {
480  eprintf("Error: failed to allocate RzVector vmem.\n");
481  free(json_str);
482  rz_json_free(reg_json);
483  return false;
484  }
485  ht_up_insert(memory, sdb_atoi(addr), vmem);
486 
487  // Extract <RzDebugChangeMem>'s into the new vector
488  for (child = reg_json->children.first; child; child = child->next) {
489  if (child->type != RZ_JSON_OBJECT) {
490  continue;
491  }
492  const RzJson *baby = rz_json_get(child, "cnum");
494  int cnum = baby->num.s_value;
495 
496  baby = rz_json_get(child, "data");
498  ut64 data = baby->num.u_value;
499 
500  RzDebugChangeMem mem = { cnum, data };
501  rz_vector_push(vmem, &mem);
502  }
503 
504  free(json_str);
505  rz_json_free(reg_json);
506  return true;
507 }
508 
509 static void deserialize_memory(Sdb *db, HtUP *memory) {
510  sdb_foreach(db, deserialize_memory_cb, memory);
511 }
512 
513 static bool deserialize_registers_cb(void *user, const char *addr, const char *v) {
514  RzJson *child;
515  char *json_str = strdup(v);
516  if (!json_str) {
517  return true;
518  }
519  RzJson *reg_json = rz_json_parse(json_str);
520  if (!reg_json || reg_json->type != RZ_JSON_ARRAY) {
521  free(json_str);
522  return true;
523  }
524 
525  // Insert a new vector into `registers` HtUP at `addr`
526  HtUP *registers = user;
527  RzVector *vreg = rz_vector_new(sizeof(RzDebugChangeReg), NULL, NULL);
528  if (!vreg) {
529  eprintf("Error: failed to allocate RzVector vreg.\n");
530  rz_json_free(reg_json);
531  free(json_str);
532  return true;
533  }
534  ht_up_insert(registers, sdb_atoi(addr), vreg);
535 
536  // Extract <RzDebugChangeReg>'s into the new vector
537  for (child = reg_json->children.first; child; child = child->next) {
538  if (child->type != RZ_JSON_OBJECT) {
539  continue;
540  }
541  const RzJson *baby = rz_json_get(child, "cnum");
543  int cnum = baby->num.s_value;
544 
545  baby = rz_json_get(child, "data");
547  ut64 data = baby->num.u_value;
548 
549  RzDebugChangeReg reg = { cnum, data };
550  rz_vector_push(vreg, &reg);
551  }
552 
553  rz_json_free(reg_json);
554  free(json_str);
555  return true;
556 }
557 
558 static void deserialize_registers(Sdb *db, HtUP *registers) {
559  sdb_foreach(db, deserialize_registers_cb, registers);
560 }
561 
562 #define SNAPATTR(ATTR) sdb_fmt("snaps.a[%u]." ATTR, i)
563 #define REGATTR(ATTR) sdb_fmt("registers.%d." ATTR, i)
564 
565 static bool deserialize_checkpoints_cb(void *user, const char *cnum, const char *v) {
566  const RzJson *child;
567  char *json_str = strdup(v);
568  if (!json_str) {
569  return true;
570  }
571  RzJson *chkpt_json = rz_json_parse(json_str);
572  if (!chkpt_json || chkpt_json->type != RZ_JSON_OBJECT) {
573  free(json_str);
574  return true;
575  }
576 
577  RzVector *checkpoints = user;
578  RzDebugCheckpoint checkpoint = { 0 };
579  checkpoint.cnum = (int)sdb_atoi(cnum);
580 
581  // Extract RzRegArena's from "registers"
582  const RzJson *regs_json = rz_json_get(chkpt_json, "registers");
583  if (!regs_json || regs_json->type != RZ_JSON_ARRAY) {
584  free(json_str);
585  rz_json_free(chkpt_json);
586  return true;
587  }
588  for (child = regs_json->children.first; child; child = child->next) {
589  const RzJson *baby;
590  baby = rz_json_get(child, "arena");
592  int arena = baby->num.s_value;
593  if (arena < RZ_REG_TYPE_GPR || arena >= RZ_REG_TYPE_LAST) {
594  continue;
595  }
596  baby = rz_json_get(child, "size");
598  int size = baby->num.s_value;
599  if (size < 0) {
600  continue;
601  }
602  baby = rz_json_get(child, "bytes");
603  CHECK_TYPE(baby, RZ_JSON_STRING);
604  ut8 *bytes = sdb_decode(baby->str_value, NULL);
605 
607  if (!a) {
608  free(bytes);
609  continue;
610  }
611  memcpy(a->bytes, bytes, a->size);
612  checkpoint.arena[arena] = a;
613  free(bytes);
614  }
615 
616  // Extract RzDebugSnap's from "snaps"
618  const RzJson *snaps_json = rz_json_get(chkpt_json, "snaps");
619  if (!snaps_json || snaps_json->type != RZ_JSON_ARRAY) {
620  goto end;
621  }
622  for (child = snaps_json->children.first; child; child = child->next) {
623  const RzJson *namej = rz_json_get(child, "name");
624  CHECK_TYPE(namej, RZ_JSON_STRING);
625  const RzJson *dataj = rz_json_get(child, "data");
626  CHECK_TYPE(dataj, RZ_JSON_STRING);
627  const RzJson *sizej = rz_json_get(child, "size");
628  CHECK_TYPE(sizej, RZ_JSON_INTEGER);
629  const RzJson *addrj = rz_json_get(child, "addr");
630  CHECK_TYPE(addrj, RZ_JSON_INTEGER);
631  const RzJson *addr_endj = rz_json_get(child, "addr_end");
632  CHECK_TYPE(addr_endj, RZ_JSON_INTEGER);
633  const RzJson *permj = rz_json_get(child, "perm");
634  CHECK_TYPE(permj, RZ_JSON_INTEGER);
635  const RzJson *userj = rz_json_get(child, "user");
636  CHECK_TYPE(userj, RZ_JSON_INTEGER);
637  const RzJson *sharedj = rz_json_get(child, "shared");
638  CHECK_TYPE(sharedj, RZ_JSON_BOOLEAN);
639 
641  if (!snap) {
642  eprintf("Error: failed to allocate RzDebugSnap snap");
643  continue;
644  }
645  snap->name = strdup(namej->str_value);
646  snap->addr = addrj->num.u_value;
647  snap->addr_end = addr_endj->num.u_value;
648  snap->size = sizej->num.u_value;
649  snap->data = sdb_decode(dataj->str_value, NULL);
650  snap->perm = permj->num.s_value;
651  snap->user = userj->num.s_value;
652  snap->shared = sharedj->num.u_value;
653 
654  rz_list_append(checkpoint.snaps, snap);
655  }
656 end:
657  free(json_str);
658  rz_json_free(chkpt_json);
659  rz_vector_push(checkpoints, &checkpoint);
660  return true;
661 }
662 
663 static void deserialize_checkpoints(Sdb *db, RzVector *checkpoints) {
664  sdb_foreach(db, deserialize_checkpoints_cb, checkpoints);
665 }
666 
667 static bool session_sdb_load_ns(Sdb *db, const char *nspath, const char *filename) {
668  Sdb *tmpdb = sdb_new0();
669  if (sdb_open(tmpdb, filename) == -1) {
670  eprintf("Error: failed to load %s into sdb\n", filename);
671  sdb_free(tmpdb);
672  return false;
673  }
674  Sdb *ns = sdb_ns_path(db, nspath, true);
675  sdb_copy(tmpdb, ns);
676  sdb_free(tmpdb);
677  return true;
678 }
679 
680 static Sdb *session_sdb_load(const char *path) {
681  char *filename;
682  Sdb *db = sdb_new0();
683  if (!db) {
684  return NULL;
685  }
686 
687 #define SDB_LOAD(fn, ns) \
688  do { \
689  filename = rz_str_newf("%s%s" fn ".sdb", path, RZ_SYS_DIR); \
690  if (!session_sdb_load_ns(db, ns, filename)) { \
691  free(filename); \
692  goto error; \
693  } \
694  free(filename); \
695  } while (0)
696 
697  SDB_LOAD("session", "");
698  SDB_LOAD("registers", "registers");
699  SDB_LOAD("memory", "memory");
700  SDB_LOAD("checkpoints", "checkpoints");
701  return db;
702 error:
703  sdb_free(db);
704  return NULL;
705 }
706 
708  Sdb *subdb;
709 
710  session->maxcnum = sdb_num_get(db, "maxcnum", 0);
711 
712 #define DESERIALIZE(ns, func) \
713  do { \
714  subdb = sdb_ns(db, ns, false); \
715  if (!subdb) { \
716  eprintf("Error: missing " ns " namespace\n"); \
717  return; \
718  } \
719  func; \
720  } while (0)
721 
722  DESERIALIZE("memory", deserialize_memory(subdb, session->memory));
723  DESERIALIZE("registers", deserialize_registers(subdb, session->registers));
724  DESERIALIZE("checkpoints", deserialize_checkpoints(subdb, session->checkpoints));
725 }
726 
728  Sdb *db = session_sdb_load(path);
729  if (!db) {
730  return false;
731  }
733  // Restore debugger to the beginning of the session
735  sdb_free(db);
736  return true;
737 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
RZ_API RzRegArena * rz_reg_arena_new(size_t size)
Definition: arena.c:170
RZ_API void rz_reg_arena_free(RzRegArena *ra)
Definition: arena.c:189
static ut8 bytes[32]
Definition: asm_arc.c:23
RZ_API ut8 * sdb_decode(const char *in, int *len)
Definition: base64.c:37
RZ_API char * sdb_encode(const ut8 *bin, int len)
Definition: base64.c:18
static int value
Definition: cmd_api.c:93
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
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
uint32_t ut32
RzDebug * dbg
Definition: desil.c:30
RZ_API bool rz_debug_map_sync(RzDebug *dbg)
Definition: dmap.c:33
RZ_API int rz_debug_reg_sync(RzDebug *dbg, int type, int write)
Definition: dreg.c:9
static bool session_sdb_load_ns(Sdb *db, const char *nspath, const char *filename)
Definition: dsession.c:667
static void deserialize_registers(Sdb *db, HtUP *registers)
Definition: dsession.c:558
RZ_API void _restore_registers(RzDebug *dbg, ut32 cnum)
Definition: dsession.c:126
RZ_API void rz_debug_session_free(RzDebugSession *session)
Definition: dsession.c:11
RZ_API bool rz_debug_add_checkpoint(RzDebug *dbg)
Definition: dsession.c:58
static void htup_vector_free(HtUPKv *kv)
Definition: dsession.c:29
static void _set_initial_memory(RzDebug *dbg)
Definition: dsession.c:135
RZ_API RzDebugSession * rz_debug_session_new(void)
Definition: dsession.c:33
RZ_API void rz_debug_session_deserialize(RzDebugSession *session, Sdb *db)
Definition: dsession.c:707
static void _restore_memory(RzDebug *dbg, ut32 cnum)
Definition: dsession.c:158
static bool deserialize_memory_cb(void *user, const char *addr, const char *v)
Definition: dsession.c:464
RZ_API bool rz_debug_session_add_reg_change(RzDebugSession *session, int arena, ut64 offset, ut64 data)
Definition: dsession.c:218
static bool session_sdb_save(Sdb *db, const char *path)
Definition: dsession.c:409
static bool serialize_memory_cb(void *db, const ut64 k, const void *v)
Definition: dsession.c:278
static void serialize_checkpoints(Sdb *db, RzVector *checkpoints)
Definition: dsession.c:304
#define DESERIALIZE(ns, func)
RZ_API void rz_debug_session_restore_reg_mem(RzDebug *dbg, ut32 cnum)
Definition: dsession.c:173
static bool deserialize_checkpoints_cb(void *user, const char *cnum, const char *v)
Definition: dsession.c:565
static void rz_debug_checkpoint_fini(void *element, void *user)
Definition: dsession.c:20
#define SDB_LOAD(fn, ns)
#define CMP_CNUM_MEM(x, y)
Definition: dsession.c:8
#define CHECK_TYPE(v, t)
Definition: dsession.c:460
RZ_API bool rz_debug_session_save(RzDebugSession *session, const char *path)
Definition: dsession.c:445
static void _set_register(RzDebug *dbg, RzRegItem *ri, ut32 cnum)
Definition: dsession.c:111
static bool serialize_register_cb(void *db, const ut64 k, const void *v)
Definition: dsession.c:251
static void serialize_registers(Sdb *db, HtUP *registers)
Definition: dsession.c:273
#define CMP_CNUM_REG(x, y)
Definition: dsession.c:7
static void deserialize_checkpoints(Sdb *db, RzVector *checkpoints)
Definition: dsession.c:663
RZ_API void rz_debug_session_serialize(RzDebugSession *session, Sdb *db)
Definition: dsession.c:402
static void _set_initial_registers(RzDebug *dbg)
Definition: dsession.c:100
static void serialize_memory(Sdb *db, HtUP *memory)
Definition: dsession.c:300
RZ_API void rz_debug_session_list_memory(RzDebug *dbg)
Definition: dsession.c:185
static void deserialize_memory(Sdb *db, HtUP *memory)
Definition: dsession.c:509
static bool _restore_memory_cb(void *user, const ut64 key, const void *value)
Definition: dsession.c:143
static Sdb * session_sdb_load(const char *path)
Definition: dsession.c:680
#define CMP_CNUM_CHKPT(x, y)
Definition: dsession.c:9
RZ_API bool rz_debug_session_add_mem_change(RzDebugSession *session, ut64 addr, ut8 data)
Definition: dsession.c:233
static bool deserialize_registers_cb(void *user, const char *addr, const char *v)
Definition: dsession.c:513
RZ_API bool rz_debug_session_load(RzDebug *dbg, const char *path)
Definition: dsession.c:727
static RzDebugCheckpoint * _get_checkpoint_before(RzDebugSession *session, ut32 cnum)
Definition: dsession.c:163
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
const char * filename
Definition: ioapi.h:137
voidpf uLong offset
Definition: ioapi.h:144
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
void * mem
Definition: libc.cpp:91
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define ls_foreach(list, it, pos)
Definition: ls.h:31
RZ_API Sdb * sdb_ns_path(Sdb *s, const char *path, int create)
Definition: ns.c:213
RZ_API Sdb * sdb_ns(Sdb *s, const char *name, int create)
Definition: ns.c:186
RZ_API int sdb_num_set(Sdb *s, const char *key, ut64 v, ut32 cas)
Definition: num.c:25
RZ_API ut64 sdb_num_get(Sdb *s, const char *key, ut32 *cas)
Definition: num.c:13
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API bool rz_reg_set_value(RzReg *reg, RzRegItem *item, ut64 value)
Definition: rvalue.c:186
RZ_API ut64 rz_reg_get_value(RzReg *reg, RzRegItem *item)
Definition: rvalue.c:114
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API bool rz_file_is_directory(const char *str)
Definition: file.c:167
ut32 RzHashSize
Definition: rz_hash.h:24
RZ_API char * rz_hex_bin2strdup(const ut8 *in, int len)
Definition: hex.c:415
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_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
RZ_API void * rz_mem_copy(void *dest, size_t dmax, const void *src, size_t smax)
Definition: mem.c:50
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_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
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
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
@ RZ_REG_TYPE_LAST
Definition: rz_reg.h:34
@ RZ_REG_TYPE_ANY
Definition: rz_reg.h:35
@ RZ_REG_NAME_PC
Definition: rz_reg.h:43
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_SYS_DIR
Definition: rz_types.h:218
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RW
Definition: rz_types.h:96
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
static void * rz_vector_index_ptr(RzVector *vec, size_t index)
Definition: rz_vector.h:88
#define rz_vector_upper_bound(vec, x, i, cmp)
Definition: rz_vector.h:203
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
RZ_API void rz_vector_free(RzVector *vec)
Definition: vector.c:75
RZ_API RzVector * rz_vector_new(size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:42
RZ_API void sdb_file(Sdb *s, const char *dir)
Definition: sdb.c:128
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611
RZ_API void sdb_close(Sdb *s)
Definition: sdb.c:416
RZ_API Sdb * sdb_new0(void)
Definition: sdb.c:43
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206
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 int sdb_open(Sdb *s, const char *file)
Definition: sdb.c:383
RZ_API bool sdb_sync(Sdb *s)
Definition: sdb.c:803
RZ_API ut64 sdb_atoi(const char *s)
Definition: util.c:88
static int
Definition: sfsocketcall.h:114
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
RZ_API RzDebugSnap * rz_debug_snap_map(RzDebug *dbg, RzDebugMap *map)
Definition: snap.c:15
RZ_API ut8 * rz_debug_snap_get_hash(RzDebug *dbg, RzDebugSnap *snap, RzHashSize *size)
Definition: snap.c:50
RZ_API void rz_debug_snap_free(RzDebugSnap *snap)
Definition: snap.c:7
Definition: ls.h:17
Definition: rz_pj.h:12
RzRegArena * arena[RZ_REG_TYPE_LAST]
Definition: rz_debug.h:185
RzDebugCheckpoint * cur_chkpt
Definition: rz_debug.h:192
RzVector * checkpoints
Definition: rz_debug.h:193
PrintfCallback cb_printf
Definition: rz_debug.h:292
RzDebugSession * session
Definition: rz_debug.h:311
RzList * maps
Definition: rz_debug.h:306
RzReg * reg
Definition: rz_debug.h:286
RzIOBind iob
Definition: rz_debug.h:293
RzIOWriteAt write_at
Definition: rz_io.h:241
RzIO * io
Definition: rz_io.h:232
struct rz_json_t::@304::@307 children
const char * str_value
Definition: rz_json.h:42
struct rz_json_t * next
Definition: rz_json.h:56
RzJsonType type
Definition: rz_json.h:39
struct rz_json_t::@304::@306 num
ut8 * bytes
Definition: rz_reg.h:131
int arena
In which arena is this reg living. Usually equals type.
Definition: rz_reg.h:127
int offset
Offset into register profile in bits.
Definition: rz_reg.h:121
RzRegArena * arena
Definition: rz_reg.h:136
RzRegSet regset[RZ_REG_TYPE_LAST]
Definition: rz_reg.h:150
RzList * allregs
Definition: rz_reg.h:151
char * name[RZ_REG_NAME_LAST]
Definition: rz_reg.h:149
Definition: sdb.h:88
char * name
Definition: sdb.h:89
Sdb * sdb
Definition: sdb.h:91
Definition: sdb.h:63
SdbList * ns
Definition: sdb.h:82
void error(const char *msg)
Definition: untgz.c:593
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58