Rizin
unix-like reverse engineering framework and cli tools
serialize_bp.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 Dhruv Maroo <dhruvmaru007@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_util/rz_serialize.h>
5 #include <rz_bp.h>
6 
14  rz_return_if_fail(db && bp);
15 
17  RzBreakpointItem *bp_item;
18  rz_list_foreach (bp->bps, iter, bp_item) {
19  PJ *j = pj_new();
20  if (!j) {
21  return;
22  }
23  pj_o(j);
24  if (bp_item->cond) {
25  pj_ks(j, "cond", bp_item->cond);
26  }
27  if (bp_item->data) {
28  pj_ks(j, "data", bp_item->data);
29  }
30  pj_kn(j, "delta", bp_item->delta);
31  pj_ki(j, "enabled", bp_item->enabled);
32  if (bp_item->expr) {
33  pj_ks(j, "expr", bp_item->expr);
34  }
35  pj_ki(j, "hits", bp_item->hits);
36  pj_ki(j, "hw", bp_item->hw);
37  pj_ki(j, "internal", bp_item->internal);
38  pj_kN(j, "module_delta", bp_item->module_delta);
39  if (bp_item->module_name) {
40  pj_ks(j, "module_name", bp_item->module_name);
41  }
42  if (bp_item->name) {
43  pj_ks(j, "name", bp_item->name);
44  }
45  pj_ki(j, "perm", bp_item->perm);
46 
47  pj_ka(j, "pids");
48  for (int i = 0; i < RZ_BP_MAXPIDS; i++) {
49  pj_i(j, bp_item->pids[i]);
50  }
51  pj_end(j);
52 
53  pj_ki(j, "size", bp_item->size);
54  pj_kb(j, "swstep", bp_item->swstep);
55  pj_ki(j, "togglehits", bp_item->togglehits);
56  pj_ki(j, "trace", bp_item->trace);
57  pj_end(j);
58 
59  char key[19];
60  sdb_set(db, rz_strf(key, "0x%" PFMT64x, bp_item->addr), pj_string(j), 0);
61  pj_free(j);
62  }
63 }
64 
65 enum {
83 };
84 
90 RZ_API RzSerializeBpParser rz_serialize_bp_parser_new(void) {
91  RzSerializeBpParser parser = rz_key_parser_new();
92  if (!parser) {
93  return NULL;
94  }
95 
113 
114  return parser;
115 }
116 
117 typedef struct {
119  RzSerializeBpParser parser;
120 } BpLoadCtx;
121 
122 static bool bp_load_cb(void *user, const char *k, const char *v) {
123  bool ret = false;
124  BpLoadCtx *ctx = user;
125  char *json_str = strdup(v);
126  if (!json_str) {
127  return true;
128  }
129  RzJson *json = rz_json_parse(json_str);
130  if (!json || json->type != RZ_JSON_OBJECT) {
131  goto heaven;
132  }
133  RzBreakpointItem bp_item_temp = { 0 };
134  bp_item_temp.addr = strtoull(k, NULL, 0);
135 
136  RZ_KEY_PARSER_JSON(ctx->parser, json, child, {
137  case BP_FIELD_NAME:
138  if (child->type != RZ_JSON_STRING) {
139  break;
140  }
141  bp_item_temp.name = (char *)child->str_value;
142  break;
144  if (child->type != RZ_JSON_STRING) {
145  break;
146  }
147  bp_item_temp.module_name = (char *)child->str_value;
148  break;
150  if (child->type != RZ_JSON_INTEGER) {
151  break;
152  }
153  bp_item_temp.module_delta = child->num.s_value;
154  break;
155  case BP_FIELD_DELTA:
156  if (child->type != RZ_JSON_INTEGER) {
157  break;
158  }
159  bp_item_temp.delta = child->num.u_value;
160  break;
161  case BP_FIELD_SIZE:
162  if (child->type != RZ_JSON_INTEGER) {
163  break;
164  }
165  bp_item_temp.size = (int)child->num.s_value;
166  break;
167  case BP_FIELD_SWSTEP:
168  if (child->type != RZ_JSON_BOOLEAN) {
169  break;
170  }
171  bp_item_temp.swstep = child->num.u_value ? true : false;
172  break;
173  case BP_FIELD_PERM:
174  if (child->type != RZ_JSON_INTEGER) {
175  break;
176  }
177  bp_item_temp.perm = (int)child->num.s_value;
178  break;
179  case BP_FIELD_HW:
180  if (child->type != RZ_JSON_INTEGER) {
181  break;
182  }
183  bp_item_temp.hw = (int)child->num.s_value;
184  break;
185  case BP_FIELD_TRACE:
186  if (child->type != RZ_JSON_INTEGER) {
187  break;
188  }
189  bp_item_temp.trace = (int)child->num.s_value;
190  break;
191  case BP_FIELD_INTERNAL:
192  if (child->type != RZ_JSON_INTEGER) {
193  break;
194  }
195  bp_item_temp.internal = (int)child->num.s_value;
196  break;
197  case BP_FIELD_ENABLED:
198  if (child->type != RZ_JSON_INTEGER) {
199  break;
200  }
201  bp_item_temp.enabled = (int)child->num.s_value;
202  break;
203  case BP_FIELD_TOGGLEHITS:
204  if (child->type != RZ_JSON_INTEGER) {
205  break;
206  }
207  bp_item_temp.togglehits = (int)child->num.s_value;
208  break;
209  case BP_FIELD_HITS:
210  if (child->type != RZ_JSON_INTEGER) {
211  break;
212  }
213  bp_item_temp.hits = (int)child->num.s_value;
214  break;
215  case BP_FIELD_PIDS:
216  if (child->type != RZ_JSON_ARRAY) {
217  break;
218  }
219  int index = 0;
220  for (const RzJson *pid_child = child->children.first; pid_child; pid_child = pid_child->next) {
221  if (index >= RZ_BP_MAXPIDS) {
222  break;
223  }
224  bp_item_temp.pids[index] = (int)pid_child->num.s_value;
225  ++index;
226  }
227  break;
228  case BP_FIELD_DATA:
229  if (child->type != RZ_JSON_STRING) {
230  break;
231  }
232  bp_item_temp.data = (char *)child->str_value;
233  break;
234  case BP_FIELD_COND:
235  if (child->type != RZ_JSON_STRING) {
236  break;
237  }
238  bp_item_temp.cond = (char *)child->str_value;
239  break;
240  case BP_FIELD_EXPR:
241  if (child->type != RZ_JSON_STRING) {
242  break;
243  }
244  bp_item_temp.expr = (char *)child->str_value;
245  break;
246  })
247 
248  RzBreakpointItem *bp_item = NULL;
249  if (bp_item_temp.hw) {
250  bp_item = rz_bp_add_hw(ctx->bp, bp_item_temp.addr, bp_item_temp.size, bp_item_temp.perm);
251  } else {
252  bp_item = rz_bp_add_sw(ctx->bp, bp_item_temp.addr, bp_item_temp.size, bp_item_temp.perm);
253  }
254  if (!bp_item) {
255  goto beach;
256  }
257 
258  if (bp_item_temp.name) {
259  bp_item->name = strdup(bp_item_temp.name);
260  }
261  if (bp_item_temp.module_name) {
262  bp_item->module_name = strdup(bp_item_temp.module_name);
263  }
264  bp_item->module_delta = bp_item_temp.module_delta;
265  bp_item->delta = bp_item_temp.delta;
266  bp_item->swstep = bp_item_temp.swstep;
267  bp_item->hw = bp_item_temp.hw;
268  bp_item->trace = bp_item_temp.trace;
269  bp_item->internal = bp_item_temp.internal;
270  bp_item->enabled = bp_item_temp.enabled;
271  bp_item->togglehits = bp_item_temp.togglehits;
272  bp_item->hits = bp_item_temp.hits;
273  for (int i = 0; i < RZ_BP_MAXPIDS; i++) {
274  bp_item->pids[i] = bp_item_temp.pids[i];
275  }
276  if (bp_item_temp.data) {
277  bp_item->data = strdup(bp_item_temp.data);
278  }
279  if (bp_item_temp.cond) {
280  bp_item->cond = strdup(bp_item_temp.cond);
281  }
282  if (bp_item_temp.expr) {
283  bp_item->expr = strdup(bp_item_temp.expr);
284  }
285  ret = true;
286 
287 beach:
288  rz_json_free(json);
289 heaven:
290  free(json_str);
291  return ret;
292 }
293 
303  rz_return_val_if_fail(db && bp, false);
304 
305  bool ret = false;
306  RzSerializeBpParser bp_parser = rz_serialize_bp_parser_new();
307  if (!bp_parser) {
308  goto heaven;
309  }
310  if (!rz_list_empty(bp->bps) && !rz_bp_del_all(bp)) {
311  goto heaven;
312  }
313 
314  BpLoadCtx ctx = {
315  .bp = bp,
316  .parser = bp_parser
317  };
318  ret = sdb_foreach(db, bp_load_cb, &ctx);
319  if (!ret) {
320  RZ_SERIALIZE_ERR(res, "failed to parse a breakpoint json");
321  }
322 
323 heaven:
324  rz_key_parser_free(bp_parser);
325  return ret;
326 }
lzma_index ** i
Definition: index.h:629
RZ_API bool rz_bp_del_all(RzBreakpoint *bp)
Definition: bp.c:303
RZ_API RzBreakpointItem * rz_bp_add_hw(RzBreakpoint *bp, ut64 addr, int size, int perm)
Definition: bp.c:299
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_add_sw(RZ_NONNULL RzBreakpoint *bp, ut64 addr, int size, int perm)
Add a software breakpoint size preferred size of the breakpoint, or 0 to determine automatically.
Definition: bp.c:280
#define RZ_API
#define NULL
Definition: cris-opc.c:27
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
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
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 rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_BP_MAXPIDS
Definition: rz_bp.h:15
@ 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
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_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_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_kN(PJ *j, const char *k, st64 n)
Definition: pj.c:128
static void rz_key_parser_add(RzKeyParser *parser, const char *key, int val)
Definition: rz_serialize.h:56
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
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_NONNULL
Definition: rz_types.h:64
#define PFMT64x
Definition: rz_types.h:393
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611
RZ_API bool sdb_foreach(Sdb *s, SdbForeachCallback cb, void *user)
Definition: sdb.c:758
static bool bp_load_cb(void *user, const char *k, const char *v)
Definition: serialize_bp.c:122
RZ_API bool rz_serialize_bp_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzBreakpoint *bp, RZ_NULLABLE RzSerializeResultInfo *res)
Load a serialized breakpoints to a RzBreakpoint instance.
Definition: serialize_bp.c:302
@ BP_FIELD_TRACE
Definition: serialize_bp.c:74
@ BP_FIELD_COND
Definition: serialize_bp.c:81
@ BP_FIELD_MODULE_NAME
Definition: serialize_bp.c:67
@ BP_FIELD_DELTA
Definition: serialize_bp.c:69
@ BP_FIELD_TOGGLEHITS
Definition: serialize_bp.c:77
@ BP_FIELD_HW
Definition: serialize_bp.c:73
@ BP_FIELD_SWSTEP
Definition: serialize_bp.c:71
@ BP_FIELD_DATA
Definition: serialize_bp.c:80
@ BP_FIELD_EXPR
Definition: serialize_bp.c:82
@ BP_FIELD_PIDS
Definition: serialize_bp.c:79
@ BP_FIELD_HITS
Definition: serialize_bp.c:78
@ BP_FIELD_PERM
Definition: serialize_bp.c:72
@ BP_FIELD_MODULE_DELTA
Definition: serialize_bp.c:68
@ BP_FIELD_ENABLED
Definition: serialize_bp.c:76
@ BP_FIELD_NAME
Definition: serialize_bp.c:66
@ BP_FIELD_INTERNAL
Definition: serialize_bp.c:75
@ BP_FIELD_SIZE
Definition: serialize_bp.c:70
RZ_API void rz_serialize_bp_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzBreakpoint *bp)
serialize and save the breakpoints in a sdb
Definition: serialize_bp.c:13
RZ_API RzSerializeBpParser rz_serialize_bp_parser_new(void)
Create a new RzSerializeBpParser instance.
Definition: serialize_bp.c:90
RzSerializeBpParser parser
Definition: serialize_bp.c:119
RzBreakpoint * bp
Definition: serialize_bp.c:118
Definition: rz_pj.h:12
char * expr
Definition: rz_bp.h:61
int hw
Definition: rz_bp.h:50
st64 module_delta
Definition: rz_bp.h:44
char * data
Definition: rz_bp.h:59
char * module_name
Definition: rz_bp.h:43
int size
Definition: rz_bp.h:47
int perm
Definition: rz_bp.h:49
int internal
Definition: rz_bp.h:52
char * name
Definition: rz_bp.h:42
bool swstep
Definition: rz_bp.h:48
int pids[RZ_BP_MAXPIDS]
Definition: rz_bp.h:58
ut64 addr
Definition: rz_bp.h:45
int togglehits
Definition: rz_bp.h:54
int hits
Definition: rz_bp.h:55
int enabled
Definition: rz_bp.h:53
int trace
Definition: rz_bp.h:51
char * cond
Definition: rz_bp.h:60
ut64 delta
Definition: rz_bp.h:46
Definition: rz_bp.h:78
struct rz_json_t::@304::@307 children
RzJsonType type
Definition: rz_json.h:39
Definition: sdb.h:63
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4