1 /* radare - LGPL - Copyright 2014-2020 - pancake */
2
3 #include <r_debug.h>
4
5 #define DB dbg->sgnls
6
7 // TODO: this must be done by the debugger plugin
8 // which is stored already in SDB.. but this is faster :P
9 static struct {
10 const char *k;
11 const char *v;
12 } signals[] = {
13 // hardcoded from linux
14 { "SIGHUP", "1" },
15 { "SIGINT", "2" },
16 { "SIGQUIT", "3" },
17 { "SIGILL", "4" },
18 { "SIGTRAP", "5" },
19 { "SIGABRT", "6" },
20 // { "SIGIOT", "6" },
21 { "SIGBUS", "7" },
22 { "SIGFPE", "8" },
23 { "SIGKILL", "9" },
24 { "SIGUSR1", "10" },
25 { "SIGSEGV", "11" },
26 { "SIGUSR2", "12" },
27 { "SIGPIPE", "13" },
28 { "SIGALRM", "14" },
29 { "SIGTERM", "15" },
30 { "SIGSTKFLT", "16" },
31 { "SIGCHLD", "17" },
32 { "SIGCONT", "18" },
33 { "SIGSTOP", "19" },
34 { "SIGTSTP", "20" },
35 { "SIGTTIN", "21" },
36 { "SIGTTOU", "22" },
37 { "SIGURG", "23" },
38 { "SIGXCPU", "24" },
39 { "SIGXFSZ", "25" },
40 { "SIGVTALRM", "26" },
41 { "SIGPROF", "27" },
42 { "SIGWINCH", "28" },
43 { "SIGIO", "29" },
44 { "SIGPOLL", "SIGIO" },
45 { "SIGLOST", "29" },
46 { "SIGPWR", "30" },
47 { "SIGSYS", "31" },
48 { "SIGRTMIN", "32" },
49 { "SIGRTMAX", "NSIG" },
50 { NULL }
51 };
52
r_debug_signal_init(RDebug * dbg)53 R_API void r_debug_signal_init(RDebug *dbg) {
54 int i;
55 // XXX
56 DB = sdb_new (NULL, "signals", 0);
57 for (i=0; signals[i].k; i++) {
58 sdb_set (DB, signals[i].k, signals[i].v, 0);
59 sdb_set (DB, signals[i].v, signals[i].k, 0);
60 }
61 }
62
siglistcb(void * p,const char * k,const char * v)63 static bool siglistcb (void *p, const char *k, const char *v) {
64 static char key[32] = "cfg.";
65 RDebug *dbg = (RDebug *)p;
66 int opt, mode = dbg->_mode;
67 if (atoi (k) > 0) {
68 strncpy (key + 4, k, 20);
69 opt = sdb_num_get (DB, key, 0);
70 if (opt) {
71 r_cons_printf ("%s %s", k, v);
72 if (opt & R_DBG_SIGNAL_CONT) {
73 r_cons_strcat (" cont");
74 }
75 if (opt & R_DBG_SIGNAL_SKIP) {
76 r_cons_strcat (" skip");
77 }
78 r_cons_newline ();
79 } else {
80 if (mode == 0) {
81 r_cons_printf ("%s %s\n", k, v);
82 }
83 }
84 }
85 return true;
86 }
87
siglistjsoncb(void * p,const char * k,const char * v)88 static bool siglistjsoncb(void *p, const char *k, const char *v) {
89 static char key[32] = "cfg.";
90 RDebug *dbg = (RDebug *)p;
91 int opt;
92 if (atoi (k) > 0) {
93 strncpy (key + 4, k, 20);
94 opt = (int)sdb_num_get (DB, key, 0);
95 pj_o (dbg->pj);
96 pj_ks (dbg->pj, "signum", k);
97 pj_ks (dbg->pj, "name", v);
98 pj_k (dbg->pj, "option");
99 if (opt & R_DBG_SIGNAL_CONT) {
100 pj_s (dbg->pj, "cont");
101 } else if (opt & R_DBG_SIGNAL_SKIP) {
102 pj_s (dbg->pj, "skip");
103 } else {
104 pj_null (dbg->pj);
105 }
106 pj_end (dbg->pj);
107 }
108 return true;
109 }
110
r_debug_signal_list(RDebug * dbg,int mode)111 R_API void r_debug_signal_list(RDebug *dbg, int mode) {
112 dbg->_mode = mode;
113 switch (mode) {
114 case 0:
115 case 1:
116 sdb_foreach (DB, siglistcb, dbg);
117 break;
118 case 2:
119 if (!dbg->pj) {
120 return;
121 }
122 pj_a (dbg->pj);
123 sdb_foreach (DB, siglistjsoncb, dbg);
124 pj_end (dbg->pj);
125 r_cons_println (pj_string (dbg->pj));
126 break;
127 }
128 dbg->_mode = 0;
129 }
130
r_debug_signal_send(RDebug * dbg,int num)131 R_API int r_debug_signal_send(RDebug *dbg, int num) {
132 return r_sandbox_kill (dbg->pid, num);
133 }
134
r_debug_signal_setup(RDebug * dbg,int num,int opt)135 R_API void r_debug_signal_setup(RDebug *dbg, int num, int opt) {
136 sdb_queryf (DB, "cfg.%d=%d", num, opt);
137 }
138
r_debug_signal_what(RDebug * dbg,int num)139 R_API int r_debug_signal_what(RDebug *dbg, int num) {
140 char k[32];
141 snprintf (k, sizeof (k), "cfg.%d", num);
142 return sdb_num_get (DB, k, 0);
143 }
144
r_debug_signal_set(RDebug * dbg,int num,ut64 addr)145 R_API int r_debug_signal_set(RDebug *dbg, int num, ut64 addr) {
146 // TODO
147 // r_debug_syscall (dbg, "signal", "addr");
148 return 0;
149 }
150
151 /* TODO rename to _kill_ -> _signal_ */
r_debug_kill_list(RDebug * dbg)152 R_API RList *r_debug_kill_list(RDebug *dbg) {
153 if (dbg->h->kill_list) {
154 return dbg->h->kill_list (dbg);
155 }
156 return NULL;
157 }
158
r_debug_kill_setup(RDebug * dbg,int sig,int action)159 R_API int r_debug_kill_setup(RDebug *dbg, int sig, int action) {
160 eprintf ("TODO: set signal handlers of child\n");
161 // TODO: must inject code to call signal()
162 #if 0
163 if (dbg->h->kill_setup)
164 return dbg->h->kill_setup (dbg, sig, action);
165 #endif
166 // TODO: implement r_debug_kill_setup
167 return false;
168 }
169