• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "berberis/kernel_api/runtime_bridge.h"
18 
19 #include <cerrno>
20 #include <cstdlib>
21 
22 #include "berberis/base/bit_util.h"
23 #include "berberis/base/config.h"
24 #include "berberis/base/tracing.h"
25 #include "berberis/guest_os_primitives/guest_signal.h"
26 #include "berberis/guest_os_primitives/guest_thread.h"
27 #include "berberis/guest_os_primitives/guest_thread_manager.h"
28 #include "berberis/kernel_api/sys_mman_emulation.h"
29 
30 #include "sigevent_emulation.h"
31 
32 namespace berberis {
33 
RunGuestSyscall___NR_rt_sigaction(long sig_num_arg,long act_arg,long old_act_arg,long sigset_size_arg)34 long RunGuestSyscall___NR_rt_sigaction(long sig_num_arg,
35                                        long act_arg,
36                                        long old_act_arg,
37                                        long sigset_size_arg) {
38   TRACE("'rt_sigaction' called for signal %ld", sig_num_arg);
39   int sig_num = static_cast<int>(sig_num_arg);
40   const Guest_sigaction* act = bit_cast<const Guest_sigaction*>(act_arg);
41   Guest_sigaction* old_act = bit_cast<Guest_sigaction*>(old_act_arg);
42   size_t sigset_size = bit_cast<size_t>(sigset_size_arg);
43 
44   if (sigset_size != sizeof(Guest_sigset_t)) {
45     errno = EINVAL;
46     return -1;
47   }
48 
49   int error;
50   if (SetGuestSignalHandler(sig_num, act, old_act, &error)) {
51     return 0;
52   }
53   errno = error;
54   return -1;
55 }
56 
RunGuestSyscall___NR_sigaltstack(long stack,long old_stack)57 long RunGuestSyscall___NR_sigaltstack(long stack, long old_stack) {
58   int error;
59   if (GetCurrentGuestThread()->SigAltStack(
60           bit_cast<const stack_t*>(stack), bit_cast<stack_t*>(old_stack), &error)) {
61     return 0;
62   }
63   errno = error;
64   return -1;
65 }
66 
RunGuestSyscall___NR_timer_create(long arg_1,long arg_2,long arg_3)67 long RunGuestSyscall___NR_timer_create(long arg_1, long arg_2, long arg_3) {
68   struct sigevent host_sigevent;
69   return syscall(__NR_timer_create,
70                  arg_1,
71                  ConvertGuestSigeventToHost(bit_cast<struct sigevent*>(arg_2), &host_sigevent),
72                  arg_3);
73 }
74 
RunGuestSyscall___NR_exit(long code)75 long RunGuestSyscall___NR_exit(long code) {
76   ExitCurrentThread(code);
77   return 0;
78 }
79 
RunGuestSyscall___NR_clone(long arg_1,long arg_2,long arg_3,long arg_4,long arg_5)80 long RunGuestSyscall___NR_clone(long arg_1, long arg_2, long arg_3, long arg_4, long arg_5) {
81   // NOTE: clone syscall argument ordering is architecture dependent.  This implementation assumes
82   // CLONE_BACKWARDS is enabled (tls before child_tid), which is true for both x86 and RISC-V.
83   return CloneGuestThread(GetCurrentGuestThread(), arg_1, arg_2, arg_3, arg_4, arg_5);
84 }
85 
RunGuestSyscall___NR_mmap(long arg_1,long arg_2,long arg_3,long arg_4,long arg_5,long arg_6)86 long RunGuestSyscall___NR_mmap(long arg_1,
87                                long arg_2,
88                                long arg_3,
89                                long arg_4,
90                                long arg_5,
91                                long arg_6) {
92   return bit_cast<long>(MmapForGuest(bit_cast<void*>(arg_1),         // addr
93                                      bit_cast<size_t>(arg_2),        // length
94                                      static_cast<int>(arg_3),        // prot
95                                      static_cast<int>(arg_4),        // flags
96                                      static_cast<int>(arg_5),        // fd
97                                      static_cast<off64_t>(arg_6)));  // offset
98 }
99 
RunGuestSyscall___NR_mmap2(long arg_1,long arg_2,long arg_3,long arg_4,long arg_5,long arg_6)100 long RunGuestSyscall___NR_mmap2(long arg_1,
101                                 long arg_2,
102                                 long arg_3,
103                                 long arg_4,
104                                 long arg_5,
105                                 long arg_6) {
106   return bit_cast<long>(
107       MmapForGuest(bit_cast<void*>(arg_1),                                  // addr
108                    bit_cast<size_t>(arg_2),                                 // length
109                    static_cast<int>(arg_3),                                 // prot
110                    static_cast<int>(arg_4),                                 // flags
111                    static_cast<int>(arg_5),                                 // fd
112                    static_cast<off64_t>(arg_6) * config::kGuestPageSize));  // pgoffset to offset
113 }
114 
RunGuestSyscall___NR_munmap(long arg_1,long arg_2)115 long RunGuestSyscall___NR_munmap(long arg_1, long arg_2) {
116   return static_cast<long>(MunmapForGuest(bit_cast<void*>(arg_1),     // addr
117                                           bit_cast<size_t>(arg_2)));  // length
118 }
119 
RunGuestSyscall___NR_mprotect(long arg_1,long arg_2,long arg_3)120 long RunGuestSyscall___NR_mprotect(long arg_1, long arg_2, long arg_3) {
121   return static_cast<long>(MprotectForGuest(bit_cast<void*>(arg_1),     // addr
122                                             bit_cast<size_t>(arg_2),    // length
123                                             static_cast<int>(arg_3)));  // prot
124 }
125 
RunGuestSyscall___NR_mremap(long arg_1,long arg_2,long arg_3,long arg_4,long arg_5)126 long RunGuestSyscall___NR_mremap(long arg_1, long arg_2, long arg_3, long arg_4, long arg_5) {
127   return bit_cast<long>(MremapForGuest(bit_cast<void*>(arg_1),    // old_addr
128                                        bit_cast<size_t>(arg_2),   // old_size
129                                        bit_cast<size_t>(arg_3),   // new_size
130                                        static_cast<int>(arg_4),   // flags
131                                        bit_cast<void*>(arg_5)));  // new_addr
132 }
133 
134 }  // namespace berberis
135