OpenOCD
breakpoints.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2005 by Dominic Rath *
5  * Dominic.Rath@gmx.de *
6  * *
7  * Copyright (C) ST-Ericsson SA 2011 *
8  * michel.jaouen@stericsson.com : smp minimum support *
9  ***************************************************************************/
10 
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14 
15 #include "target.h"
16 #include <helper/log.h>
17 #include "breakpoints.h"
18 #include "smp.h"
19 #include "helper/util.h"
20 
24 };
25 
26 static const char * const breakpoint_type_strings[] = {
27  "hardware",
28  "software"
29 };
30 
31 static const char * const watchpoint_rw_strings[] = {
32  "read",
33  "write",
34  "access"
35 };
36 
37 /* monotonic counter/id-number for breakpoints and watch points */
38 static int bpwp_unique_id;
39 
42  unsigned int length,
43  enum breakpoint_type type)
44 {
46  struct breakpoint **breakpoint_p = &target->breakpoints;
47  const char *reason;
48  int retval;
49 
50  while (breakpoint) {
51  if (breakpoint->address == address) {
52  /* FIXME don't assume "same address" means "same
53  * breakpoint" ... check all the parameters before
54  * succeeding.
55  */
56  LOG_TARGET_ERROR(target, "Duplicate Breakpoint address: " TARGET_ADDR_FMT " (BP %" PRIu32 ")",
59  }
60  if (type == BKPT_SOFT &&
62  LOG_TARGET_ERROR(target, "Breakpoint intersects with another one at " TARGET_ADDR_FMT
63  " of length %u (BP %" PRIu32 ")", breakpoint->address,
66  }
67  breakpoint_p = &breakpoint->next;
69  }
70 
71  (*breakpoint_p) = malloc(sizeof(struct breakpoint));
72  (*breakpoint_p)->address = address;
73  (*breakpoint_p)->asid = 0;
74  (*breakpoint_p)->length = length;
75  (*breakpoint_p)->type = type;
76  (*breakpoint_p)->is_set = false;
77  (*breakpoint_p)->orig_instr = malloc(length);
78  (*breakpoint_p)->next = NULL;
79  (*breakpoint_p)->unique_id = bpwp_unique_id++;
80 
81  retval = target_add_breakpoint(target, *breakpoint_p);
82  switch (retval) {
83  case ERROR_OK:
84  break;
86  reason = "resource not available";
87  goto fail;
89  reason = "target not halted";
90  goto fail;
91  default:
92  reason = "unknown reason";
93 fail:
94  LOG_TARGET_ERROR(target, "can't add breakpoint: %s", reason);
95  free((*breakpoint_p)->orig_instr);
96  free(*breakpoint_p);
97  *breakpoint_p = NULL;
98  return retval;
99  }
100 
101  LOG_TARGET_DEBUG(target, "added %s breakpoint at " TARGET_ADDR_FMT
102  " of length 0x%8.8x, (BPID: %" PRIu32 ")",
103  breakpoint_type_strings[(*breakpoint_p)->type],
104  (*breakpoint_p)->address, (*breakpoint_p)->length,
105  (*breakpoint_p)->unique_id);
106 
107  return ERROR_OK;
108 }
109 
111  uint32_t asid,
112  unsigned int length,
113  enum breakpoint_type type)
114 {
116  struct breakpoint **breakpoint_p = &target->breakpoints;
117  int retval;
118 
119  while (breakpoint) {
120  if (breakpoint->asid == asid) {
121  /* FIXME don't assume "same address" means "same
122  * breakpoint" ... check all the parameters before
123  * succeeding.
124  */
125  LOG_TARGET_ERROR(target, "Duplicate Breakpoint asid: 0x%08" PRIx32 " (BP %" PRIu32 ")",
128  }
129  breakpoint_p = &breakpoint->next;
131  }
132 
133  (*breakpoint_p) = malloc(sizeof(struct breakpoint));
134  (*breakpoint_p)->address = 0;
135  (*breakpoint_p)->asid = asid;
136  (*breakpoint_p)->length = length;
137  (*breakpoint_p)->type = type;
138  (*breakpoint_p)->is_set = false;
139  (*breakpoint_p)->orig_instr = malloc(length);
140  (*breakpoint_p)->next = NULL;
141  (*breakpoint_p)->unique_id = bpwp_unique_id++;
142  retval = target_add_context_breakpoint(target, *breakpoint_p);
143  if (retval != ERROR_OK) {
144  LOG_TARGET_ERROR(target, "could not add breakpoint");
145  free((*breakpoint_p)->orig_instr);
146  free(*breakpoint_p);
147  *breakpoint_p = NULL;
148  return retval;
149  }
150 
151  LOG_TARGET_DEBUG(target, "added %s Context breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %" PRIu32 ")",
152  breakpoint_type_strings[(*breakpoint_p)->type],
153  (*breakpoint_p)->asid, (*breakpoint_p)->length,
154  (*breakpoint_p)->unique_id);
155 
156  return ERROR_OK;
157 }
158 
161  uint32_t asid,
162  unsigned int length,
163  enum breakpoint_type type)
164 {
166  struct breakpoint **breakpoint_p = &target->breakpoints;
167  int retval;
168 
169  while (breakpoint) {
170  if ((breakpoint->asid == asid) && (breakpoint->address == address)) {
171  /* FIXME don't assume "same address" means "same
172  * breakpoint" ... check all the parameters before
173  * succeeding.
174  */
175  LOG_TARGET_ERROR(target, "Duplicate Hybrid Breakpoint asid: 0x%08" PRIx32 " (BP %" PRIu32 ")",
178  } else if ((breakpoint->address == address) && (breakpoint->asid == 0)) {
179  LOG_TARGET_ERROR(target, "Duplicate Breakpoint IVA: " TARGET_ADDR_FMT " (BP %" PRIu32 ")",
182 
183  }
184  breakpoint_p = &breakpoint->next;
186  }
187  (*breakpoint_p) = malloc(sizeof(struct breakpoint));
188  (*breakpoint_p)->address = address;
189  (*breakpoint_p)->asid = asid;
190  (*breakpoint_p)->length = length;
191  (*breakpoint_p)->type = type;
192  (*breakpoint_p)->is_set = false;
193  (*breakpoint_p)->orig_instr = malloc(length);
194  (*breakpoint_p)->next = NULL;
195  (*breakpoint_p)->unique_id = bpwp_unique_id++;
196 
197 
198  retval = target_add_hybrid_breakpoint(target, *breakpoint_p);
199  if (retval != ERROR_OK) {
200  LOG_TARGET_ERROR(target, "could not add breakpoint");
201  free((*breakpoint_p)->orig_instr);
202  free(*breakpoint_p);
203  *breakpoint_p = NULL;
204  return retval;
205  }
207  "added %s Hybrid breakpoint at address " TARGET_ADDR_FMT " of length 0x%8.8x, (BPID: %" PRIu32 ")",
208  breakpoint_type_strings[(*breakpoint_p)->type],
209  (*breakpoint_p)->address,
210  (*breakpoint_p)->length,
211  (*breakpoint_p)->unique_id);
212 
213  return ERROR_OK;
214 }
215 
218  unsigned int length,
219  enum breakpoint_type type)
220 {
221  if (target->smp && type == BKPT_HARD) {
222  struct target_list *list_node;
223  foreach_smp_target(list_node, target->smp_targets) {
224  struct target *curr = list_node->target;
225  int retval = breakpoint_add_internal(curr, address, length, type);
226  if (retval != ERROR_OK)
227  return retval;
228  }
229 
230  return ERROR_OK;
231  } else {
233  }
234 }
235 
237  uint32_t asid,
238  unsigned int length,
239  enum breakpoint_type type)
240 {
241  if (target->smp) {
242  struct target_list *head;
243 
245  struct target *curr = head->target;
246  int retval = context_breakpoint_add_internal(curr, asid, length, type);
247  if (retval != ERROR_OK)
248  return retval;
249  }
250 
251  return ERROR_OK;
252  } else {
254  }
255 }
256 
259  uint32_t asid,
260  unsigned int length,
261  enum breakpoint_type type)
262 {
263  if (target->smp) {
264  struct target_list *head;
265 
267  struct target *curr = head->target;
268  int retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type);
269  if (retval != ERROR_OK)
270  return retval;
271  }
272 
273  return ERROR_OK;
274  } else
276 }
277 
278 /* free up a breakpoint */
279 static int breakpoint_free(struct target *target, struct breakpoint *breakpoint_to_remove)
280 {
282  struct breakpoint **breakpoint_p = &target->breakpoints;
283  int retval;
284 
285  while (breakpoint) {
286  if (breakpoint == breakpoint_to_remove)
287  break;
288  breakpoint_p = &breakpoint->next;
290  }
291 
292  if (!breakpoint)
293  return ERROR_OK;
294 
296  if (retval != ERROR_OK) {
297  LOG_TARGET_ERROR(target, "could not remove breakpoint #%d on this target",
298  breakpoint->number);
299  return retval;
300  }
301 
302  LOG_TARGET_DEBUG(target, "free BPID: %" PRIu32 " --> %d", breakpoint->unique_id, retval);
303  (*breakpoint_p) = breakpoint->next;
304  free(breakpoint->orig_instr);
305  free(breakpoint);
306 
307  return ERROR_OK;
308 }
309 
311 {
313 
314  while (breakpoint) {
315  if ((breakpoint->address == address) ||
316  (breakpoint->address == 0 && breakpoint->asid == address))
317  break;
319  }
320 
321  if (breakpoint) {
323  } else {
325  }
326 }
327 
329 {
330  LOG_TARGET_DEBUG(target, "Delete all breakpoints");
331 
333  int retval = ERROR_OK;
334 
335  while (breakpoint) {
336  struct breakpoint *tmp = breakpoint;
338  int status = breakpoint_free(target, tmp);
339  if (status != ERROR_OK)
340  retval = status;
341  }
342 
343  return retval;
344 }
345 
347 {
348  int retval = ERROR_OK;
349  unsigned int num_found_breakpoints = 0;
350  if (target->smp) {
351  struct target_list *head;
352 
354  struct target *curr = head->target;
356 
358  num_found_breakpoints++;
359 
360  if (status != ERROR_OK) {
361  LOG_TARGET_ERROR(curr, "failed to remove breakpoint at address " TARGET_ADDR_FMT, address);
362  retval = status;
363  }
364  }
365  }
366 
367  } else {
369 
370  if (retval != ERROR_BREAKPOINT_NOT_FOUND) {
371  num_found_breakpoints++;
372 
373  if (retval != ERROR_OK)
374  LOG_TARGET_ERROR(target, "failed to remove breakpoint at address " TARGET_ADDR_FMT, address);
375  }
376  }
377 
378  if (num_found_breakpoints == 0) {
379  LOG_TARGET_ERROR(target, "no breakpoint at address " TARGET_ADDR_FMT " found", address);
381  }
382 
383  return retval;
384 }
385 
386 static int watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)
387 {
389  struct watchpoint **watchpoint_p = &target->watchpoints;
390  int retval;
391 
392  while (watchpoint) {
393  if (watchpoint == watchpoint_to_remove)
394  break;
395  watchpoint_p = &watchpoint->next;
397  }
398 
399  if (!watchpoint)
400  return ERROR_OK;
402  if (retval != ERROR_OK) {
403  LOG_TARGET_ERROR(target, "could not remove watchpoint #%d on this target",
404  watchpoint->number);
405  return retval;
406  }
407 
408  LOG_TARGET_DEBUG(target, "free WPID: %d --> %d", watchpoint->unique_id, retval);
409  (*watchpoint_p) = watchpoint->next;
410  free(watchpoint);
411 
412  return ERROR_OK;
413 }
414 
416 {
417  LOG_TARGET_DEBUG(target, "Delete all watchpoints");
418 
420  int retval = ERROR_OK;
421 
422  while (watchpoint) {
423  struct watchpoint *tmp = watchpoint;
425  int status = watchpoint_free(target, tmp);
426  if (status != ERROR_OK)
427  retval = status;
428  }
429 
430  return retval;
431 }
432 
434 {
435  assert(bp_wp == BREAKPOINT || bp_wp == WATCHPOINT);
436  int retval = ERROR_OK;
437  if (target->smp) {
438  struct target_list *head;
439 
441  struct target *curr = head->target;
442 
443  int status = ERROR_OK;
444  if (bp_wp == BREAKPOINT)
446  else
448 
449  if (status != ERROR_OK)
450  retval = status;
451  }
452  } else {
453  if (bp_wp == BREAKPOINT)
455  else
457  }
458 
459  return retval;
460 }
461 
463 {
465 }
466 
468 {
470 }
471 
473 {
475 
476  while (breakpoint) {
477  if (breakpoint->address == address)
478  return breakpoint;
480  }
481 
482  return NULL;
483 }
484 
486  unsigned int length, enum watchpoint_rw rw, uint64_t value, uint64_t mask)
487 {
489  struct watchpoint **watchpoint_p = &target->watchpoints;
490  int retval;
491  const char *reason;
492 
493  while (watchpoint) {
494  if (watchpoint->address == address) {
495  if (watchpoint->length != length
496  || watchpoint->value != value
497  || watchpoint->mask != mask
498  || watchpoint->rw != rw) {
500  " already has watchpoint %d",
502  return ERROR_FAIL;
503  }
504 
505  /* ignore duplicate watchpoint */
506  return ERROR_OK;
507  }
508  watchpoint_p = &watchpoint->next;
510  }
511 
512  (*watchpoint_p) = calloc(1, sizeof(struct watchpoint));
513  (*watchpoint_p)->address = address;
514  (*watchpoint_p)->length = length;
515  (*watchpoint_p)->value = value;
516  (*watchpoint_p)->mask = mask;
517  (*watchpoint_p)->rw = rw;
518  (*watchpoint_p)->unique_id = bpwp_unique_id++;
519 
520  retval = target_add_watchpoint(target, *watchpoint_p);
521  switch (retval) {
522  case ERROR_OK:
523  break;
525  reason = "resource not available";
526  goto bye;
528  reason = "target not halted";
529  goto bye;
530  default:
531  reason = "unrecognized error";
532 bye:
533  LOG_TARGET_ERROR(target, "can't add %s watchpoint at " TARGET_ADDR_FMT ", %s",
534  watchpoint_rw_strings[(*watchpoint_p)->rw],
535  address, reason);
536  free(*watchpoint_p);
537  *watchpoint_p = NULL;
538  return retval;
539  }
540 
541  LOG_TARGET_DEBUG(target, "added %s watchpoint at " TARGET_ADDR_FMT
542  " of length 0x%8.8x (WPID: %d)",
543  watchpoint_rw_strings[(*watchpoint_p)->rw],
544  (*watchpoint_p)->address,
545  (*watchpoint_p)->length,
546  (*watchpoint_p)->unique_id);
547 
548  return ERROR_OK;
549 }
550 
552  unsigned int length, enum watchpoint_rw rw, uint64_t value, uint64_t mask)
553 {
554  if (target->smp) {
555  struct target_list *head;
556 
558  struct target *curr = head->target;
559  int retval = watchpoint_add_internal(curr, address, length, rw, value, mask);
560  if (retval != ERROR_OK)
561  return retval;
562  }
563 
564  return ERROR_OK;
565  } else {
566  return watchpoint_add_internal(target, address, length, rw, value,
567  mask);
568  }
569 }
570 
572 {
574 
575  while (watchpoint) {
576  if (watchpoint->address == address)
577  break;
579  }
580 
581  if (watchpoint) {
583  } else {
585  }
586 }
587 
589 {
590  int retval = ERROR_OK;
591  unsigned int num_found_watchpoints = 0;
592  if (target->smp) {
593  struct target_list *head;
594 
596  struct target *curr = head->target;
598 
600  num_found_watchpoints++;
601 
602  if (status != ERROR_OK) {
603  LOG_TARGET_ERROR(curr, "failed to remove watchpoint at address " TARGET_ADDR_FMT, address);
604  retval = status;
605  }
606  }
607  }
608  } else {
610 
611  if (retval != ERROR_WATCHPOINT_NOT_FOUND) {
612  num_found_watchpoints++;
613 
614  if (retval != ERROR_OK)
615  LOG_TARGET_ERROR(target, "failed to remove watchpoint at address " TARGET_ADDR_FMT, address);
616  }
617  }
618 
619  if (num_found_watchpoints == 0) {
620  LOG_TARGET_ERROR(target, "no watchpoint at address " TARGET_ADDR_FMT " found", address);
622  }
623 
624  return retval;
625 }
626 
629 {
630  int retval;
631  struct watchpoint *hit_watchpoint;
632 
633  retval = target_hit_watchpoint(target, &hit_watchpoint);
634  if (retval == ERROR_NOT_IMPLEMENTED
636  // Handle the trivial case: only one watchpoint is set
637  unsigned int cnt = 0;
638  struct watchpoint *wp = target->watchpoints;
639  while (wp) {
640  cnt++;
641  wp = wp->next;
642  }
643  if (cnt == 1) {
644  retval = ERROR_OK;
645  hit_watchpoint = target->watchpoints;
646  }
647  }
648  if (retval != ERROR_OK)
649  return ERROR_FAIL;
650 
651  *rw = hit_watchpoint->rw;
652  *address = hit_watchpoint->address;
653 
654  LOG_TARGET_DEBUG(target, "Found hit watchpoint at " TARGET_ADDR_FMT " (WPID: %d)",
655  hit_watchpoint->address,
656  hit_watchpoint->unique_id);
657 
658  return ERROR_OK;
659 }
static const char *const watchpoint_rw_strings[]
Definition: breakpoints.c:31
int watchpoint_add(struct target *target, target_addr_t address, unsigned int length, enum watchpoint_rw rw, uint64_t value, uint64_t mask)
Definition: breakpoints.c:551
static int breakpoint_watchpoint_remove_all(struct target *target, enum breakpoint_watchpoint bp_wp)
Definition: breakpoints.c:433
static int watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)
Definition: breakpoints.c:386
static int breakpoint_add_internal(struct target *target, target_addr_t address, unsigned int length, enum breakpoint_type type)
Definition: breakpoints.c:40
int breakpoint_remove(struct target *target, target_addr_t address)
Definition: breakpoints.c:346
static int watchpoint_add_internal(struct target *target, target_addr_t address, unsigned int length, enum watchpoint_rw rw, uint64_t value, uint64_t mask)
Definition: breakpoints.c:485
int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, target_addr_t *address)
Definition: breakpoints.c:627
static int breakpoint_remove_internal(struct target *target, target_addr_t address)
Definition: breakpoints.c:310
static int context_breakpoint_add_internal(struct target *target, uint32_t asid, unsigned int length, enum breakpoint_type type)
Definition: breakpoints.c:110
int watchpoint_remove(struct target *target, target_addr_t address)
Definition: breakpoints.c:588
int breakpoint_add(struct target *target, target_addr_t address, unsigned int length, enum breakpoint_type type)
Definition: breakpoints.c:216
static int bpwp_unique_id
Definition: breakpoints.c:38
breakpoint_watchpoint
Definition: breakpoints.c:21
@ WATCHPOINT
Definition: breakpoints.c:23
@ BREAKPOINT
Definition: breakpoints.c:22
static const char *const breakpoint_type_strings[]
Definition: breakpoints.c:26
int context_breakpoint_add(struct target *target, uint32_t asid, unsigned int length, enum breakpoint_type type)
Definition: breakpoints.c:236
static int watchpoint_remove_internal(struct target *target, target_addr_t address)
Definition: breakpoints.c:571
static int breakpoint_free(struct target *target, struct breakpoint *breakpoint_to_remove)
Definition: breakpoints.c:279
int watchpoint_remove_all(struct target *target)
Definition: breakpoints.c:467
int breakpoint_remove_all(struct target *target)
Definition: breakpoints.c:462
static int hybrid_breakpoint_add_internal(struct target *target, target_addr_t address, uint32_t asid, unsigned int length, enum breakpoint_type type)
Definition: breakpoints.c:159
static int breakpoint_remove_all_internal(struct target *target)
Definition: breakpoints.c:328
int hybrid_breakpoint_add(struct target *target, target_addr_t address, uint32_t asid, unsigned int length, enum breakpoint_type type)
Definition: breakpoints.c:257
static int watchpoint_remove_all_internal(struct target *target)
Definition: breakpoints.c:415
struct breakpoint * breakpoint_find(struct target *target, target_addr_t address)
Definition: breakpoints.c:472
breakpoint_type
Definition: breakpoints.h:17
@ BKPT_HARD
Definition: breakpoints.h:18
@ BKPT_SOFT
Definition: breakpoints.h:19
#define ERROR_WATCHPOINT_NOT_FOUND
Definition: breakpoints.h:88
#define ERROR_BREAKPOINT_NOT_FOUND
Definition: breakpoints.h:87
watchpoint_rw
Definition: breakpoints.h:22
uint32_t address
Starting address. Sector aligned.
Definition: dw-spi-helper.h:0
uint8_t type
Definition: esp_usb_jtag.c:0
uint8_t length
Definition: esp_usb_jtag.c:1
#define ERROR_NOT_IMPLEMENTED
Definition: log.h:179
#define ERROR_FAIL
Definition: log.h:175
#define LOG_TARGET_ERROR(target, fmt_str,...)
Definition: log.h:163
#define LOG_TARGET_DEBUG(target, fmt_str,...)
Definition: log.h:151
#define ERROR_OK
Definition: log.h:169
uint8_t mask
Definition: parport.c:70
#define foreach_smp_target(pos, head)
Definition: smp.h:15
struct breakpoint * next
Definition: breakpoints.h:34
unsigned int length
Definition: breakpoints.h:29
uint8_t * orig_instr
Definition: breakpoints.h:33
uint32_t unique_id
Definition: breakpoints.h:35
unsigned int number
Definition: breakpoints.h:32
uint32_t asid
Definition: breakpoints.h:28
target_addr_t address
Definition: breakpoints.h:27
struct target * target
Definition: target.h:217
Definition: target.h:119
enum target_debug_reason debug_reason
Definition: target.h:157
struct list_head * smp_targets
Definition: target.h:191
struct breakpoint * breakpoints
Definition: target.h:162
unsigned int smp
Definition: target.h:190
struct watchpoint * watchpoints
Definition: target.h:163
uint64_t mask
Definition: breakpoints.h:44
enum watchpoint_rw rw
Definition: breakpoints.h:46
struct watchpoint * next
Definition: breakpoints.h:49
unsigned int length
Definition: breakpoints.h:43
uint64_t value
Definition: breakpoints.h:45
int unique_id
Definition: breakpoints.h:50
unsigned int number
Definition: breakpoints.h:48
target_addr_t address
Definition: breakpoints.h:42
int target_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
Add the watchpoint for target.
Definition: target.c:1339
int target_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
Remove the breakpoint for target.
Definition: target.c:1333
int target_add_hybrid_breakpoint(struct target *target, struct breakpoint *breakpoint)
Add the ContextID & IVA breakpoint for target.
Definition: target.c:1323
int target_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
Add the breakpoint for target.
Definition: target.c:1303
int target_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
Find out the just hit watchpoint for target.
Definition: target.c:1353
int target_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
Remove the watchpoint for target.
Definition: target.c:1348
int target_add_context_breakpoint(struct target *target, struct breakpoint *breakpoint)
Add the ContextID breakpoint for target.
Definition: target.c:1313
@ DBG_REASON_WATCHPOINT
Definition: target.h:74
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:786
#define ERROR_TARGET_DUPLICATE_BREAKPOINT
Definition: target.h:794
#define ERROR_TARGET_INTERSECT_BREAKPOINT
Definition: target.h:799
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:790
#define TARGET_ADDR_FMT
Definition: types.h:286
uint64_t target_addr_t
Definition: types.h:279
#define NULL
Definition: usb.h:16
bool is_memory_regions_overlap(target_addr_t start1, unsigned int size1, target_addr_t start2, unsigned int size2)
Definition: util.c:44
uint8_t status[4]
Definition: vdebug.c:17