move away from syscall counts towards operation counts
[trinity.git] / tables-biarch.c
blob7b9492ac7633c2b2ff2fee0c5d7369e29402a412
1 /*
2 * Functions for handling the system call tables.
3 * These functions are only used on architectures that have both 32 and 64 bit syscalls.
4 */
6 #include <string.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <stdlib.h>
11 #include "trinity.h" // ARRAY_SIZE, alloc_shared
12 #include "arch.h"
13 #include "syscall.h"
14 #include "params.h"
15 #include "log.h"
16 #include "shm.h"
17 #include "tables.h"
19 #define NOTFOUND (unsigned int)-1
21 const struct syscalltable *syscalls_32bit;
22 const struct syscalltable *syscalls_64bit;
24 unsigned int max_nr_32bit_syscalls;
25 unsigned int max_nr_64bit_syscalls;
27 bool use_32bit = FALSE;
28 bool use_64bit = FALSE;
30 void activate_syscall32(unsigned int calln)
32 activate_syscall_in_table(calln, &shm->nr_active_32bit_syscalls, syscalls_32bit, shm->active_syscalls32);
35 void activate_syscall64(unsigned int calln)
37 activate_syscall_in_table(calln, &shm->nr_active_64bit_syscalls, syscalls_64bit, shm->active_syscalls64);
40 void deactivate_syscall32(unsigned int calln)
42 deactivate_syscall_in_table(calln, &shm->nr_active_32bit_syscalls, syscalls_32bit, shm->active_syscalls32);
45 void deactivate_syscall64(unsigned int calln)
47 deactivate_syscall_in_table(calln, &shm->nr_active_64bit_syscalls, syscalls_64bit, shm->active_syscalls64);
51 int validate_syscall_table_64(void)
53 if (shm->nr_active_64bit_syscalls == 0)
54 use_64bit = FALSE;
55 else
56 use_64bit = TRUE;
58 return use_64bit;
61 int validate_syscall_table_32(void)
63 if (shm->nr_active_32bit_syscalls == 0)
64 use_32bit = FALSE;
65 else
66 use_32bit = TRUE;
68 return use_32bit;
71 void toggle_syscall_biarch_n(int calln, const struct syscalltable *table, bool onlyflag, bool doflag, bool state, void (*activate)(unsigned int), int arch_bits, const char *arg_name)
73 if (calln != -1) {
74 struct syscallentry *entry = table[calln].entry;
76 validate_specific_syscall(table, calln);
78 if ((state == TRUE) && onlyflag && doflag) {
79 entry->flags |= ACTIVE;
80 (*activate)(calln);
81 } else {
82 entry->flags |= TO_BE_DEACTIVATED;
86 if ((arch_bits != 0) && (calln != -1))
87 output(0, "Marking %d-bit syscall %s (%d) as to be %sabled.\n",
88 arch_bits, arg_name, calln,
89 state ? "en" : "dis");
92 void toggle_syscall_biarch(const char *arg, bool state)
94 int specific_syscall32 = 0;
95 int specific_syscall64 = 0;
96 char *arg_name = NULL;
97 bool only_32bit = TRUE;
98 bool only_64bit = TRUE;
100 check_user_specified_arch(arg, &arg_name, &only_64bit, &only_32bit);
102 /* If we found a 64bit syscall, validate it. */
103 specific_syscall64 = search_syscall_table(syscalls_64bit, max_nr_64bit_syscalls, arg_name);
104 toggle_syscall_biarch_n(specific_syscall64, syscalls_64bit, only_64bit, do_64_arch, state, &activate_syscall64, 0, arg_name);
106 /* Search for and validate 32bit */
107 specific_syscall32 = search_syscall_table(syscalls_32bit, max_nr_32bit_syscalls, arg_name);
108 toggle_syscall_biarch_n(specific_syscall32, syscalls_32bit, only_32bit, do_32_arch, state, &activate_syscall32, 0, arg_name);
111 if ((!only_32bit) && (!only_64bit)) {
112 outputerr("No idea what architecture for syscall (%s) is.\n", arg);
113 exit(EXIT_FAILURE);
116 if ((specific_syscall64 == -1) && (specific_syscall32 == -1)) {
117 outputerr("No idea what syscall (%s) is.\n", arg);
118 exit(EXIT_FAILURE);
121 if ((specific_syscall64 != -1) && (specific_syscall32 != -1)) {
122 output(0, "Marking syscall %s (64bit:%d 32bit:%d) as to be %sabled.\n",
123 arg_name, specific_syscall64, specific_syscall32,
124 state ? "en" : "dis");
125 goto out;
128 if (specific_syscall64 != -1) {
129 output(0, "Marking 64-bit syscall %s (%d) as to be %sabled.\n",
130 arg, specific_syscall64,
131 state ? "en" : "dis");
132 goto out;
135 if (specific_syscall32 != -1) {
136 output(0, "Marking 32-bit syscall %s (%d) as to be %sabled.\n",
137 arg, specific_syscall32,
138 state ? "en" : "dis");
140 out:
141 clear_check_user_specified_arch(arg, &arg_name);
142 return;
146 void enable_random_syscalls_biarch(void)
148 unsigned int call32 = NOTFOUND, call64 = NOTFOUND;
150 retry:
152 //Search for 64 bit version
153 if (do_64_arch) {
154 struct syscallentry *entry = NULL;
156 call64 = rand() % max_nr_64bit_syscalls;
158 if (validate_specific_syscall_silent(syscalls_64bit, call64) == FALSE)
159 goto retry;
161 if (no_files == TRUE)
162 if (is_syscall_net_related(syscalls_64bit, call64) == FALSE)
163 goto retry;
165 entry = syscalls_64bit[call64].entry;
167 if (entry->flags & TO_BE_DEACTIVATED) {
168 call64 = NOTFOUND;
169 goto try32bit;
172 if (entry->active_number != 0) {
173 call64 = NOTFOUND;
174 goto try32bit;
177 // If we got so far, then activate it.
178 toggle_syscall_biarch_n(call64, syscalls_64bit, TRUE, do_64_arch, TRUE,
179 &activate_syscall64, 64, entry->name);
182 try32bit:
183 //Search for 32 bit version
184 if (do_32_arch) {
185 struct syscallentry *entry = NULL;
187 /* If we enabled a 64bit syscall above, enable its 32-bit counter-part too */
188 if (do_64_arch) {
189 if (call64 == NOTFOUND) {
190 goto just32;
191 } else {
192 call32 = search_syscall_table(syscalls_32bit, max_nr_32bit_syscalls, syscalls_64bit[call64].entry->name);
193 if (call32 == NOTFOUND)
194 return; // syscall is 64-bit only.
196 } else {
197 just32:
198 call32 = rand() % max_nr_32bit_syscalls;
201 if (validate_specific_syscall_silent(syscalls_32bit, call32) == FALSE)
202 return;
204 if (no_files == TRUE) {
205 if (is_syscall_net_related(syscalls_32bit, call32) == FALSE)
206 return;
209 entry = syscalls_32bit[call32].entry;
211 if ((entry->flags & TO_BE_DEACTIVATED) || (entry->active_number != 0))
212 return;
214 //If we got so far, then active it.
215 toggle_syscall_biarch_n(call32, syscalls_32bit, TRUE, do_32_arch, TRUE,
216 &activate_syscall32, 32, entry->name);
220 void disable_non_net_syscalls_biarch(void)
222 struct syscallentry *entry;
223 unsigned int i;
225 for_each_64bit_syscall(i) {
226 entry = syscalls_64bit[i].entry;
228 if (validate_specific_syscall_silent(syscalls_64bit, i) == FALSE)
229 continue;
231 if (entry->flags & ACTIVE) {
232 if (is_syscall_net_related(syscalls_64bit, i) == FALSE) {
233 toggle_syscall_biarch_n(i, syscalls_64bit, FALSE, do_64_arch, FALSE,
234 &activate_syscall64, 64, entry->name);
239 for_each_32bit_syscall(i) {
240 entry = syscalls_32bit[i].entry;
242 if (validate_specific_syscall_silent(syscalls_32bit, i) == FALSE)
243 continue;
245 if (entry->flags & ACTIVE) {
246 if (is_syscall_net_related(syscalls_32bit, i) == FALSE) {
247 toggle_syscall_biarch_n(i, syscalls_32bit, FALSE, do_32_arch, FALSE,
248 &activate_syscall32, 32, entry->name);
254 int setup_syscall_group_biarch(unsigned int group)
256 unsigned int i;
258 for_each_32bit_syscall(i) {
259 if (syscalls_32bit[i].entry->group == group)
260 activate_syscall32(i);
263 if (shm->nr_active_32bit_syscalls == 0)
264 outputstd("No 32-bit syscalls in group\n");
265 else
266 outputstd("Found %d 32-bit syscalls in group\n", shm->nr_active_32bit_syscalls);
268 /* now the 64 bit table*/
269 for_each_64bit_syscall(i) {
270 if (syscalls_64bit[i].entry->group == group)
271 activate_syscall64(i);
274 if (shm->nr_active_64bit_syscalls == 0) {
275 outputstd("No 64-bit syscalls in group\n");
276 return FALSE;
277 } else {
278 outputstd("Found %d 64-bit syscalls in group\n", shm->nr_active_64bit_syscalls);
281 return TRUE;
284 void mark_all_syscalls_active_biarch(void)
286 unsigned int i;
288 if (do_32_arch) {
289 for_each_32bit_syscall(i) {
290 syscalls_32bit[i].entry->flags |= ACTIVE;
291 activate_syscall32(i);
295 if (do_64_arch) {
296 for_each_64bit_syscall(i) {
297 syscalls_64bit[i].entry->flags |= ACTIVE;
298 activate_syscall64(i);
303 void init_syscalls_biarch(void)
305 struct syscallentry *entry;
306 unsigned int i;
308 for_each_64bit_syscall(i) {
309 entry = syscalls_64bit[i].entry;
310 if (entry->flags & ACTIVE)
311 if (entry->init)
312 entry->init();
315 for_each_32bit_syscall(i) {
316 entry = syscalls_32bit[i].entry;
317 if (entry->flags & ACTIVE)
318 if (entry->init)
319 entry->init();
323 void deactivate_disabled_syscalls_biarch(void)
325 struct syscallentry *entry;
326 unsigned int i;
328 for_each_64bit_syscall(i) {
329 entry = syscalls_64bit[i].entry;
330 if (entry->flags & TO_BE_DEACTIVATED) {
331 entry->flags &= ~(ACTIVE|TO_BE_DEACTIVATED);
332 deactivate_syscall64(i);
333 output(0, "Marked 64-bit syscall %s (%d) as deactivated.\n",
334 entry->name, entry->number);
338 for_each_32bit_syscall(i) {
339 entry = syscalls_32bit[i].entry;
340 if (entry->flags & TO_BE_DEACTIVATED) {
341 entry->flags &= ~(ACTIVE|TO_BE_DEACTIVATED);
342 deactivate_syscall32(i);
343 output(0, "Marked 32-bit syscall %s (%d) as deactivated.\n",
344 entry->name, entry->number);
349 void dump_syscall_tables_biarch(void)
351 struct syscallentry *entry;
352 unsigned int i;
354 outputstd("syscalls: %d [32-bit]\n", max_nr_32bit_syscalls);
355 outputstd("syscalls: %d [64-bit]\n", max_nr_64bit_syscalls);
357 for_each_32bit_syscall(i) {
358 entry = syscalls_32bit[i].entry;
359 outputstd("entrypoint %d %s : [32-bit] ",
360 entry->number, entry->name);
361 show_state(entry->flags & ACTIVE);
363 if (entry->flags & AVOID_SYSCALL)
364 outputstd(" AVOID");
366 outputstd("\n");
369 for_each_64bit_syscall(i) {
370 entry = syscalls_64bit[i].entry;
372 outputstd("entrypoint %d %s : [64-bit] ",
373 entry->number, entry->name);
374 show_state(entry->flags & ACTIVE);
376 if (entry->flags & AVOID_SYSCALL)
377 outputstd(" AVOID");
379 outputstd("\n");
383 void display_enabled_syscalls_biarch(void)
385 struct syscallentry *entry;
386 unsigned int i;
388 for_each_64bit_syscall(i) {
389 entry = syscalls_64bit[i].entry;
390 if (entry->flags & ACTIVE)
391 output(0, "64-bit syscall %d:%s enabled.\n", i, entry->name);
394 for_each_32bit_syscall(i) {
395 entry = syscalls_32bit[i].entry;
396 if (entry->flags & ACTIVE)
397 output(0, "32-bit syscall %d:%s enabled.\n", i, entry->name);