28
28
#include "qemu/include/qemu/queue.h"
29
29
#include "qemu-common.h"
30
30
31
+ static void clear_deleted_hooks (uc_engine * uc );
32
+
33
+ static void * hook_insert (struct list * l , struct hook * h )
34
+ {
35
+ void * item = list_insert (l , (void * )h );
36
+ if (item ) {
37
+ h -> refs ++ ;
38
+ }
39
+ return item ;
40
+ }
41
+
42
+ static void * hook_append (struct list * l , struct hook * h )
43
+ {
44
+ void * item = list_append (l , (void * )h );
45
+ if (item ) {
46
+ h -> refs ++ ;
47
+ }
48
+ return item ;
49
+ }
50
+
51
+ static void hook_delete (void * data )
52
+ {
53
+ struct hook * h = (struct hook * )data ;
54
+
55
+ h -> refs -- ;
56
+
57
+ if (h -> refs == 0 ) {
58
+ free (h );
59
+ }
60
+ }
61
+
31
62
UNICORN_EXPORT
32
63
unsigned int uc_version (unsigned int * major , unsigned int * minor )
33
64
{
@@ -172,6 +203,12 @@ static uc_err uc_init(uc_engine *uc)
172
203
return UC_ERR_HANDLE ;
173
204
}
174
205
206
+ uc -> hooks_to_del .delete_fn = hook_delete ;
207
+
208
+ for (int i = 0 ; i < UC_HOOK_MAX ; i ++ ) {
209
+ uc -> hook [i ].delete_fn = hook_delete ;
210
+ }
211
+
175
212
uc -> exits = g_tree_new_full (uc_exits_cmp , NULL , g_free , NULL );
176
213
177
214
if (machine_initialize (uc )) {
@@ -369,8 +406,6 @@ UNICORN_EXPORT
369
406
uc_err uc_close (uc_engine * uc )
370
407
{
371
408
int i ;
372
- struct list_item * cur ;
373
- struct hook * hook ;
374
409
MemoryRegion * mr ;
375
410
376
411
if (!uc -> init_done ) {
@@ -422,17 +457,9 @@ uc_err uc_close(uc_engine *uc)
422
457
}
423
458
424
459
// free hooks and hook lists
460
+ clear_deleted_hooks (uc );
461
+
425
462
for (i = 0 ; i < UC_HOOK_MAX ; i ++ ) {
426
- cur = uc -> hook [i ].head ;
427
- // hook can be in more than one list
428
- // so we refcount to know when to free
429
- while (cur ) {
430
- hook = (struct hook * )cur -> data ;
431
- if (-- hook -> refs == 0 ) {
432
- free (hook );
433
- }
434
- cur = cur -> next ;
435
- }
436
463
list_clear (& uc -> hook [i ]);
437
464
}
438
465
@@ -670,12 +697,6 @@ static void clear_deleted_hooks(uc_engine *uc)
670
697
assert (hook -> to_delete );
671
698
for (i = 0 ; i < UC_HOOK_MAX ; i ++ ) {
672
699
if (list_remove (& uc -> hook [i ], (void * )hook )) {
673
- if (-- hook -> refs == 0 ) {
674
- uc -> del_inline_hook (uc , hook );
675
- free (hook );
676
- }
677
-
678
- // a hook cannot be twice in the same list
679
700
break ;
680
701
}
681
702
}
@@ -1507,19 +1528,18 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
1507
1528
}
1508
1529
1509
1530
if (uc -> hook_insert ) {
1510
- if (list_insert (& uc -> hook [UC_HOOK_INSN_IDX ], hook ) == NULL ) {
1531
+ if (hook_insert (& uc -> hook [UC_HOOK_INSN_IDX ], hook ) == NULL ) {
1511
1532
free (hook );
1512
1533
return UC_ERR_NOMEM ;
1513
1534
}
1514
1535
} else {
1515
- if (list_append (& uc -> hook [UC_HOOK_INSN_IDX ], hook ) == NULL ) {
1536
+ if (hook_append (& uc -> hook [UC_HOOK_INSN_IDX ], hook ) == NULL ) {
1516
1537
free (hook );
1517
1538
return UC_ERR_NOMEM ;
1518
1539
}
1519
1540
}
1520
1541
1521
1542
uc -> hooks_count [UC_HOOK_INSN_IDX ]++ ;
1522
- hook -> refs ++ ;
1523
1543
return UC_ERR_OK ;
1524
1544
}
1525
1545
@@ -1539,19 +1559,18 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
1539
1559
}
1540
1560
1541
1561
if (uc -> hook_insert ) {
1542
- if (list_insert (& uc -> hook [UC_HOOK_TCG_OPCODE_IDX ], hook ) == NULL ) {
1562
+ if (hook_insert (& uc -> hook [UC_HOOK_TCG_OPCODE_IDX ], hook ) == NULL ) {
1543
1563
free (hook );
1544
1564
return UC_ERR_NOMEM ;
1545
1565
}
1546
1566
} else {
1547
- if (list_append (& uc -> hook [UC_HOOK_TCG_OPCODE_IDX ], hook ) == NULL ) {
1567
+ if (hook_append (& uc -> hook [UC_HOOK_TCG_OPCODE_IDX ], hook ) == NULL ) {
1548
1568
free (hook );
1549
1569
return UC_ERR_NOMEM ;
1550
1570
}
1551
1571
}
1552
1572
1553
1573
uc -> hooks_count [UC_HOOK_TCG_OPCODE_IDX ]++ ;
1554
- hook -> refs ++ ;
1555
1574
return UC_ERR_OK ;
1556
1575
}
1557
1576
@@ -1560,22 +1579,17 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
1560
1579
// TODO: invalid hook error?
1561
1580
if (i < UC_HOOK_MAX ) {
1562
1581
if (uc -> hook_insert ) {
1563
- if (list_insert (& uc -> hook [i ], hook ) == NULL ) {
1564
- if (hook -> refs == 0 ) {
1565
- free (hook );
1566
- }
1582
+ if (hook_insert (& uc -> hook [i ], hook ) == NULL ) {
1583
+ free (hook );
1567
1584
return UC_ERR_NOMEM ;
1568
1585
}
1569
1586
} else {
1570
- if (list_append (& uc -> hook [i ], hook ) == NULL ) {
1571
- if (hook -> refs == 0 ) {
1572
- free (hook );
1573
- }
1587
+ if (hook_append (& uc -> hook [i ], hook ) == NULL ) {
1588
+ free (hook );
1574
1589
return UC_ERR_NOMEM ;
1575
1590
}
1576
1591
}
1577
1592
uc -> hooks_count [i ]++ ;
1578
- hook -> refs ++ ;
1579
1593
}
1580
1594
}
1581
1595
i ++ ;
@@ -1607,7 +1621,7 @@ uc_err uc_hook_del(uc_engine *uc, uc_hook hh)
1607
1621
if (list_exists (& uc -> hook [i ], (void * )hook )) {
1608
1622
hook -> to_delete = true;
1609
1623
uc -> hooks_count [i ]-- ;
1610
- list_append (& uc -> hooks_to_del , hook );
1624
+ hook_append (& uc -> hooks_to_del , hook );
1611
1625
}
1612
1626
}
1613
1627
0 commit comments