2 * Functions for handling the system call tables.
3 * These functions are only used on architectures that have both 32 and 64 bit syscalls.
11 #include "trinity.h" // ARRAY_SIZE, alloc_shared
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)
61 int validate_syscall_table_32(void)
63 if (shm
->nr_active_32bit_syscalls
== 0)
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
)
74 validate_specific_syscall(table
, calln
);
76 if ((state
== TRUE
) && onlyflag
&& doflag
) {
77 table
[calln
].entry
->flags
|= ACTIVE
;
80 table
[calln
].entry
->flags
|= TO_BE_DEACTIVATED
;
84 if ((arch_bits
!= 0) && (calln
!= -1))
85 output(0, "Marking %d-bit syscall %s (%d) as to be %sabled.\n",
86 arch_bits
, arg_name
, calln
,
87 state
? "en" : "dis");
90 void toggle_syscall_biarch(const char *arg
, bool state
)
92 int specific_syscall32
= 0;
93 int specific_syscall64
= 0;
94 char *arg_name
= NULL
;
95 bool only_32bit
= TRUE
;
96 bool only_64bit
= TRUE
;
98 check_user_specified_arch(arg
, &arg_name
, &only_64bit
, &only_32bit
);
100 /* If we found a 64bit syscall, validate it. */
101 specific_syscall64
= search_syscall_table(syscalls_64bit
, max_nr_64bit_syscalls
, arg_name
);
102 toggle_syscall_biarch_n(specific_syscall64
, syscalls_64bit
, only_64bit
, do_64_arch
, state
, &activate_syscall64
, 0, arg_name
);
104 /* Search for and validate 32bit */
105 specific_syscall32
= search_syscall_table(syscalls_32bit
, max_nr_32bit_syscalls
, arg_name
);
106 toggle_syscall_biarch_n(specific_syscall32
, syscalls_32bit
, only_32bit
, do_32_arch
, state
, &activate_syscall32
, 0, arg_name
);
109 if ((!only_32bit
) && (!only_64bit
)) {
110 outputerr("No idea what architecture for syscall (%s) is.\n", arg
);
114 if ((specific_syscall64
== -1) && (specific_syscall32
== -1)) {
115 outputerr("No idea what syscall (%s) is.\n", arg
);
119 if ((specific_syscall64
!= -1) && (specific_syscall32
!= -1)) {
120 output(0, "Marking syscall %s (64bit:%d 32bit:%d) as to be %sabled.\n",
121 arg_name
, specific_syscall64
, specific_syscall32
,
122 state
? "en" : "dis");
123 clear_check_user_specified_arch(arg
, &arg_name
);
127 if (specific_syscall64
!= -1) {
128 output(0, "Marking 64-bit syscall %s (%d) as to be %sabled.\n",
129 arg
, specific_syscall64
,
130 state
? "en" : "dis");
131 clear_check_user_specified_arch(arg
, &arg_name
);
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");
139 clear_check_user_specified_arch(arg
, &arg_name
);
144 void enable_random_syscalls_biarch(void)
146 unsigned int call32
= NOTFOUND
, call64
= NOTFOUND
;
150 //Search for 64 bit version
152 call64
= rand() % max_nr_64bit_syscalls
;
153 if (validate_specific_syscall_silent(syscalls_64bit
, call64
) == FALSE
)
156 if (no_files
== TRUE
)
157 if (is_syscall_net_related(syscalls_64bit
, call64
) == FALSE
)
160 if (syscalls_64bit
[call64
].entry
->flags
& TO_BE_DEACTIVATED
)
163 if (syscalls_64bit
[call64
].entry
->active_number
!= 0)
166 // If we got so far, then activate it.
167 toggle_syscall_biarch_n(call64
, syscalls_64bit
, TRUE
, do_64_arch
, TRUE
,
168 &activate_syscall64
, 64, syscalls_64bit
[call64
].entry
->name
);
172 //Search for 32 bit version
175 // FIXME: WTF is going on here?
177 call32
= search_syscall_table(syscalls_32bit
, max_nr_32bit_syscalls
, syscalls_64bit
[call64
].entry
->name
);
179 if (syscalls_64bit
[call64
].entry
->flags
& TO_BE_DEACTIVATED
)
180 call64
= NOTFOUND
; //mark as not found in order not to increment i.
182 call32
= rand() % max_nr_32bit_syscalls
;
185 if (validate_specific_syscall_silent(syscalls_32bit
, call32
) == FALSE
) {
186 if (call64
== NOTFOUND
)
192 if (no_files
== TRUE
) {
193 if (is_syscall_net_related(syscalls_32bit
, call32
) == FALSE
) {
194 if (call64
== NOTFOUND
)
201 if ((syscalls_32bit
[call32
].entry
->flags
& TO_BE_DEACTIVATED
) || (syscalls_32bit
[call32
].entry
->active_number
!= 0)) {
202 if (call64
== NOTFOUND
)
208 //If we got so far, then active it.
209 toggle_syscall_biarch_n(call32
, syscalls_32bit
, TRUE
, do_32_arch
, TRUE
,
210 &activate_syscall32
, 32, syscalls_32bit
[call32
].entry
->name
);
214 void disable_non_net_syscalls_biarch(void)
218 for_each_64bit_syscall(i
) {
219 if (validate_specific_syscall_silent(syscalls_64bit
, i
) == FALSE
)
222 if (syscalls_64bit
[i
].entry
->flags
& ACTIVE
) {
223 if (is_syscall_net_related(syscalls_64bit
, i
) == FALSE
) {
224 toggle_syscall_biarch_n(i
, syscalls_64bit
, FALSE
, do_64_arch
, FALSE
,
225 &activate_syscall64
, 64, syscalls_64bit
[i
].entry
->name
);
230 for_each_32bit_syscall(i
) {
231 if (validate_specific_syscall_silent(syscalls_32bit
, i
) == FALSE
)
234 if (syscalls_32bit
[i
].entry
->flags
& ACTIVE
) {
235 if (is_syscall_net_related(syscalls_32bit
, i
) == FALSE
) {
236 toggle_syscall_biarch_n(i
, syscalls_32bit
, FALSE
, do_32_arch
, FALSE
,
237 &activate_syscall32
, 32, syscalls_32bit
[i
].entry
->name
);
243 int setup_syscall_group_biarch(unsigned int group
)
247 for_each_32bit_syscall(i
) {
248 if (syscalls_32bit
[i
].entry
->group
== group
)
249 activate_syscall32(i
);
252 if (shm
->nr_active_32bit_syscalls
== 0)
253 outputstd("No 32-bit syscalls in group\n");
255 outputstd("Found %d 32-bit syscalls in group\n", shm
->nr_active_32bit_syscalls
);
257 /* now the 64 bit table*/
258 for_each_64bit_syscall(i
) {
259 if (syscalls_64bit
[i
].entry
->group
== group
)
260 activate_syscall64(i
);
263 if (shm
->nr_active_64bit_syscalls
== 0) {
264 outputstd("No 64-bit syscalls in group\n");
267 outputstd("Found %d 64-bit syscalls in group\n", shm
->nr_active_64bit_syscalls
);
273 void mark_all_syscalls_active_biarch(void)
278 for_each_32bit_syscall(i
) {
279 syscalls_32bit
[i
].entry
->flags
|= ACTIVE
;
280 activate_syscall32(i
);
285 for_each_64bit_syscall(i
) {
286 syscalls_64bit
[i
].entry
->flags
|= ACTIVE
;
287 activate_syscall64(i
);
292 void init_syscalls_biarch(void)
296 for_each_64bit_syscall(i
) {
297 if (syscalls_64bit
[i
].entry
->flags
& ACTIVE
)
298 if (syscalls_64bit
[i
].entry
->init
)
299 syscalls_64bit
[i
].entry
->init();
302 for_each_32bit_syscall(i
) {
303 if (syscalls_32bit
[i
].entry
->flags
& ACTIVE
)
304 if (syscalls_32bit
[i
].entry
->init
)
305 syscalls_32bit
[i
].entry
->init();
309 void deactivate_disabled_syscalls_biarch(void)
313 for_each_64bit_syscall(i
) {
314 if (syscalls_64bit
[i
].entry
->flags
& TO_BE_DEACTIVATED
) {
315 syscalls_64bit
[i
].entry
->flags
&= ~(ACTIVE
|TO_BE_DEACTIVATED
);
316 deactivate_syscall64(i
);
317 output(0, "Marked 64-bit syscall %s (%d) as deactivated.\n",
318 syscalls_64bit
[i
].entry
->name
, syscalls_64bit
[i
].entry
->number
);
322 for_each_32bit_syscall(i
) {
323 if (syscalls_32bit
[i
].entry
->flags
& TO_BE_DEACTIVATED
) {
324 syscalls_32bit
[i
].entry
->flags
&= ~(ACTIVE
|TO_BE_DEACTIVATED
);
325 deactivate_syscall32(i
);
326 output(0, "Marked 32-bit syscall %s (%d) as deactivated.\n",
327 syscalls_32bit
[i
].entry
->name
, syscalls_32bit
[i
].entry
->number
);
332 void dump_syscall_tables_biarch(void)
336 outputstd("syscalls: %d [32-bit]\n", max_nr_32bit_syscalls
);
337 outputstd("syscalls: %d [64-bit]\n", max_nr_64bit_syscalls
);
339 for_each_32bit_syscall(i
) {
340 outputstd("entrypoint %d %s : [32-bit] ",
341 syscalls_32bit
[i
].entry
->number
,
342 syscalls_32bit
[i
].entry
->name
);
343 show_state(syscalls_32bit
[i
].entry
->flags
& ACTIVE
);
345 if (syscalls_32bit
[i
].entry
->flags
& AVOID_SYSCALL
)
350 for_each_64bit_syscall(i
) {
351 outputstd("entrypoint %d %s : [64-bit] ",
352 syscalls_64bit
[i
].entry
->number
,
353 syscalls_64bit
[i
].entry
->name
);
354 show_state(syscalls_64bit
[i
].entry
->flags
& ACTIVE
);
355 if (syscalls_64bit
[i
].entry
->flags
& AVOID_SYSCALL
)
362 void display_enabled_syscalls_biarch(void)
366 for_each_64bit_syscall(i
) {
367 if (syscalls_64bit
[i
].entry
->flags
& ACTIVE
)
368 output(0, "64-bit syscall %d:%s enabled.\n", i
, syscalls_64bit
[i
].entry
->name
);
371 for_each_32bit_syscall(i
) {
372 if (syscalls_32bit
[i
].entry
->flags
& ACTIVE
)
373 output(0, "32-bit syscall %d:%s enabled.\n", i
, syscalls_32bit
[i
].entry
->name
);