• 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 #ifndef BERBERIS_GUEST_OS_PRIMITIVES_GUEST_SIGNAL_ACTION_H_
18 #define BERBERIS_GUEST_OS_PRIMITIVES_GUEST_SIGNAL_ACTION_H_
19 
20 #include <array>
21 #include <csignal>
22 
23 #include "berberis/base/checks.h"
24 #include "berberis/guest_os_primitives/guest_signal.h"
25 #include "berberis/guest_os_primitives/guest_signal_arch.h"
26 
27 namespace berberis {
28 
29 // Signal is 'claimed' when it has guest handler/action. For a claimed signal, actual host action
30 // is a wrapper that invokes guest code (or suspends handling until region exit).
31 class GuestSignalAction {
32  public:
33   using host_sa_sigaction_t = void (*)(int, siginfo_t*, void*);
34 
GuestSignalAction()35   constexpr GuestSignalAction()
36       : claimed_guest_sa_{.guest_sa_sigaction = Guest_SIG_DFL, .sa_flags = 0, .sa_mask = {}} {}
37 
38   GuestSignalAction(const GuestSignalAction& other) = default;
39   GuestSignalAction& operator=(const GuestSignalAction& other) = default;
40 
41   bool Change(int sig,
42               const Guest_sigaction* new_sa,
43               host_sa_sigaction_t claimed_host_sa_sigaction,
44               Guest_sigaction* old_sa,
45               int* error);
46 
GetClaimedGuestAction()47   const Guest_sigaction& GetClaimedGuestAction() const {
48     CHECK(IsClaimed());
49     return claimed_guest_sa_;
50   }
51 
52  private:
IsClaimed()53   bool IsClaimed() const { return claimed_guest_sa_.guest_sa_sigaction != Guest_SIG_DFL; }
54 
Claim(const Guest_sigaction * sa)55   void Claim(const Guest_sigaction* sa) {
56     CHECK_NE(Guest_SIG_DFL, sa->guest_sa_sigaction);
57     claimed_guest_sa_ = *sa;
58   }
59 
Unclaim()60   void Unclaim() { claimed_guest_sa_.guest_sa_sigaction = Guest_SIG_DFL; }
61 
62   Guest_sigaction claimed_guest_sa_;  // Guest_SIG_DFL when not claimed.
63 };
64 
65 // It's essentially a typedef. But we make it a class to forward declare in guest_thread.h.
66 class GuestSignalActionsTable : public std::array<GuestSignalAction, Guest__KERNEL__NSIG> {
67  public:
68   GuestSignalActionsTable() = default;
69   GuestSignalActionsTable(const GuestSignalActionsTable& other) = default;
70   GuestSignalActionsTable& operator=(const GuestSignalActionsTable& other) = default;
71 };
72 
73 }  // namespace berberis
74 
75 #endif  // BERBERIS_GUEST_OS_PRIMITIVES_GUEST_SIGNAL_ACTION_H_
76