1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2021 Benjamin Berg <benjamin@sipsolutions.net>
4 */
5
6 #include <sysdep/stub.h>
7
syscall_handler(struct stub_data * d)8 static __always_inline int syscall_handler(struct stub_data *d)
9 {
10 int i;
11 unsigned long res;
12
13 for (i = 0; i < d->syscall_data_len; i++) {
14 struct stub_syscall *sc = &d->syscall_data[i];
15
16 switch (sc->syscall) {
17 case STUB_SYSCALL_MMAP:
18 res = stub_syscall6(STUB_MMAP_NR,
19 sc->mem.addr, sc->mem.length,
20 sc->mem.prot,
21 MAP_SHARED | MAP_FIXED,
22 sc->mem.fd, sc->mem.offset);
23 if (res != sc->mem.addr) {
24 d->err = res;
25 d->syscall_data_len = i;
26 return -1;
27 }
28 break;
29 case STUB_SYSCALL_MUNMAP:
30 res = stub_syscall2(__NR_munmap,
31 sc->mem.addr, sc->mem.length);
32 if (res) {
33 d->err = res;
34 d->syscall_data_len = i;
35 return -1;
36 }
37 break;
38 case STUB_SYSCALL_MPROTECT:
39 res = stub_syscall3(__NR_mprotect,
40 sc->mem.addr, sc->mem.length,
41 sc->mem.prot);
42 if (res) {
43 d->err = res;
44 d->syscall_data_len = i;
45 return -1;
46 }
47 break;
48 default:
49 d->err = -95; /* EOPNOTSUPP */
50 d->syscall_data_len = i;
51 return -1;
52 }
53 }
54
55 d->err = 0;
56 d->syscall_data_len = 0;
57
58 return 0;
59 }
60
61 void __section(".__syscall_stub")
stub_syscall_handler(void)62 stub_syscall_handler(void)
63 {
64 struct stub_data *d = get_stub_data();
65
66 syscall_handler(d);
67
68 trap_myself();
69 }
70