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