move_pages: just use calloc
[trinity.git] / children / random-syscalls.c
blob812666ad3282b2e43026cff803aa6691a0a9544e
1 /*
2 * Call a single random syscall with random args.
3 */
5 #include <signal.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
10 #include "arch.h" // biarch
11 #include "child.h"
12 #include "syscall.h"
13 #include "locks.h"
14 #include "log.h"
15 #include "random.h"
16 #include "shm.h"
17 #include "signals.h"
18 #include "pids.h"
19 #include "tables.h"
22 * This function decides if we're going to be doing a 32bit or 64bit syscall.
23 * There are various factors involved here, from whether we're on a 32-bit only arch
24 * to 'we asked to do a 32bit only syscall' and more.. Hairy.
27 static int *active_syscalls;
29 static bool choose_syscall_table(void)
31 bool do32 = FALSE;
33 if (biarch == FALSE) {
34 active_syscalls = shm->active_syscalls;
35 do32 = TRUE;
36 } else {
38 /* First, check that we have syscalls enabled in either table. */
39 if (validate_syscall_table_64() == FALSE) {
40 use_64bit = FALSE;
41 /* If no 64bit syscalls enabled, force 32bit. */
42 do32 = TRUE;
45 if (validate_syscall_table_32() == FALSE)
46 use_32bit = FALSE;
48 /* If both tables enabled, pick randomly. */
49 if ((use_64bit == TRUE) && (use_32bit == TRUE)) {
50 /* 10% possibility of a 32bit syscall */
51 if (rand() % 100 < 10)
52 do32 = TRUE;
55 if (do32 == FALSE) {
56 syscalls = syscalls_64bit;
57 active_syscalls = shm->active_syscalls64;
58 max_nr_syscalls = max_nr_64bit_syscalls;
59 } else {
60 syscalls = syscalls_32bit;
61 active_syscalls = shm->active_syscalls32;
62 max_nr_syscalls = max_nr_32bit_syscalls;
65 return do32;
68 bool child_random_syscalls(int childno)
70 unsigned int syscallnr;
71 bool do32;
73 retry:
74 if (no_syscalls_enabled() == TRUE) {
75 output(0, "[%d] No more syscalls enabled. Exiting\n", getpid());
76 shm->exit_reason = EXIT_NO_SYSCALLS_ENABLED;
77 return FAIL;
80 /* Ok, we're doing another syscall, let's pick one. */
81 do32 = choose_syscall_table();
82 syscallnr = rand() % max_nr_syscalls;
84 /* If we got a syscallnr which is not active repeat the attempt,
85 * since another child has switched that syscall off already.*/
86 if (active_syscalls[syscallnr] == 0)
87 goto retry;
89 syscallnr = active_syscalls[syscallnr] - 1;
91 if (validate_specific_syscall_silent(syscalls, syscallnr) == FALSE) {
92 if (biarch == FALSE) {
93 deactivate_syscall(syscallnr);
94 } else {
95 if (do32 == TRUE)
96 deactivate_syscall32(syscallnr);
97 else
98 deactivate_syscall64(syscallnr);
100 goto retry;
103 /* critical section for shm updates. */
104 lock(&shm->syscall_lock);
105 shm->syscall[childno].do32bit = do32;
106 shm->syscall[childno].nr = syscallnr;
107 unlock(&shm->syscall_lock);
109 if (syscalls_todo) {
110 if (shm->total_syscalls_done >= syscalls_todo) {
111 output(0, "Reached maximum syscall count (todo = %d, done = %d), exiting...\n",
112 syscalls_todo, shm->total_syscalls_done);
113 shm->exit_reason = EXIT_REACHED_COUNT;
117 /* Do the actual syscall. */
118 return mkcall(childno);