1 #include <r_anal.h>
2 #include <r_util.h>
3 #include <sdb.h>
4
_set_interrupt(RAnalEsil * esil,RAnalEsilHandler * intr,ut32 intr_num)5 static bool _set_interrupt(RAnalEsil *esil, RAnalEsilHandler *intr, ut32 intr_num) {
6 return intr_num ? dict_set (esil->interrupts, intr_num, intr_num, intr) : (esil->intr0 = intr, true);
7 }
8
_set_syscall(RAnalEsil * esil,RAnalEsilHandler * sysc,ut32 sysc_num)9 static bool _set_syscall(RAnalEsil *esil, RAnalEsilHandler *sysc, ut32 sysc_num) {
10 return sysc_num ? dict_set (esil->syscalls, sysc_num, sysc_num, sysc) : (esil->sysc0 = sysc, true);
11 }
12
_get_interrupt(RAnalEsil * esil,ut32 intr_num)13 static RAnalEsilHandler *_get_interrupt(RAnalEsil *esil, ut32 intr_num) {
14 return intr_num ? (RAnalEsilHandler *)dict_getu (esil->interrupts, intr_num) : esil->intr0;
15 }
16
_get_syscall(RAnalEsil * esil,ut32 sysc_num)17 static RAnalEsilHandler *_get_syscall(RAnalEsil *esil, ut32 sysc_num) {
18 return sysc_num ? (RAnalEsilHandler *)dict_getu (esil->syscalls, sysc_num) : esil->sysc0;
19 }
20
r_anal_esil_handlers_init(RAnalEsil * esil)21 R_API void r_anal_esil_handlers_init(RAnalEsil *esil) {
22 r_return_if_fail (esil);
23 esil->interrupts = dict_new (sizeof (ut32), free);
24 if (!esil->interrupts) {
25 return;
26 }
27 esil->syscalls = dict_new (sizeof (ut32), free);
28 if (!esil->syscalls) {
29 dict_free (esil->interrupts);
30 return;
31 }
32 esil->intr0 = NULL;
33 esil->sysc0 = NULL;
34 }
35
36 // does this need to be an API function?
r_anal_esil_handler_new(RAnalEsilHandlerCB cb,void * user)37 R_API RAnalEsilHandler *r_anal_esil_handler_new(RAnalEsilHandlerCB cb, void *user) {
38 r_return_val_if_fail (cb, NULL);
39 RAnalEsilHandler *h = R_NEW0 (RAnalEsilHandler);
40 if (!h) {
41 return NULL;
42 }
43 h->cb = cb;
44 h->user = user;
45 return h;
46 }
47
r_anal_esil_set_interrupt(RAnalEsil * esil,ut32 intr_num,RAnalEsilHandlerCB cb,void * user)48 R_API bool r_anal_esil_set_interrupt(RAnalEsil *esil, ut32 intr_num, RAnalEsilHandlerCB cb, void *user) {
49 r_return_val_if_fail (esil && esil->interrupts && cb, false);
50 RAnalEsilHandler *intr = r_anal_esil_handler_new (cb, user);
51 if (!intr) {
52 return false;
53 }
54 // free potentially existing handler
55 free (_get_interrupt (esil, intr_num));
56 // set the new interrupt
57 return _set_interrupt (esil, intr, intr_num);
58 }
59
r_anal_esil_set_syscall(RAnalEsil * esil,ut32 sysc_num,RAnalEsilHandlerCB cb,void * user)60 R_API bool r_anal_esil_set_syscall(RAnalEsil *esil, ut32 sysc_num, RAnalEsilHandlerCB cb, void *user) {
61 r_return_val_if_fail (esil && esil->syscalls && cb, false);
62 RAnalEsilHandler *sysc = r_anal_esil_handler_new (cb, user);
63 if (!sysc) {
64 return false;
65 }
66 // free potentially existing handler
67 free (_get_syscall (esil, sysc_num));
68 // set the new interrupt
69 return _set_syscall (esil, sysc, sysc_num);
70 }
71
r_anal_esil_fire_interrupt(RAnalEsil * esil,ut32 intr_num)72 R_API int r_anal_esil_fire_interrupt(RAnalEsil *esil, ut32 intr_num) {
73 r_return_val_if_fail (esil, false);
74
75 if (esil->cmd && esil->cmd (esil, esil->cmd_intr, intr_num, 0)) { //compatibility
76 return true;
77 }
78
79 if (!esil->interrupts) {
80 eprintf ("no interrupts initialized\n");
81 return false;
82 }
83 RAnalEsilHandler *intr = _get_interrupt (esil, intr_num);
84 return (intr && intr->cb) ? intr->cb (esil, intr_num, intr->user) : false;
85 }
86
r_anal_esil_do_syscall(RAnalEsil * esil,ut32 sysc_num)87 R_API int r_anal_esil_do_syscall(RAnalEsil *esil, ut32 sysc_num) {
88 r_return_val_if_fail (esil, false);
89
90 if (!esil->syscalls) {
91 eprintf ("no syscalls initialized\n");
92 return false;
93 }
94 RAnalEsilHandler *sysc = _get_syscall (esil, sysc_num);
95 return (sysc && sysc->cb) ? sysc->cb (esil, sysc_num, sysc->user) : false;
96 }
97
r_anal_esil_handlers_fini(RAnalEsil * esil)98 R_API void r_anal_esil_handlers_fini(RAnalEsil *esil) {
99 if (esil) {
100 if (esil->interrupts) {
101 R_FREE (esil->intr0);
102 dict_free (esil->interrupts);
103 esil->interrupts = NULL;
104 }
105 if (esil->syscalls) {
106 R_FREE (esil->sysc0);
107 dict_free (esil->syscalls);
108 esil->syscalls = NULL;
109 }
110 }
111 }
112