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_STATE_GUEST_STATE_OPAQUE_H_
18 #define BERBERIS_GUEST_STATE_GUEST_STATE_OPAQUE_H_
19 
20 #include <atomic>
21 #include <cstddef>
22 #include <cstdint>
23 
24 #include "berberis/guest_state/guest_addr.h"
25 
26 namespace berberis {
27 
28 struct CPUState;
29 struct ThreadState;
30 
31 // TODO(b/294958305): remove this once android_api is migrated to ThreadState
32 using ProcessState = ThreadState;
33 
34 ThreadState* CreateThreadState();
35 void DestroyThreadState(ThreadState* state);
36 
37 class GuestThread;
38 void* GetThreadStateStorage(ThreadState& state);
39 void SetGuestThread(ThreadState& state, GuestThread* thread);
40 GuestThread* GetGuestThread(const ThreadState& state);
41 
42 // Track whether we are in generated code or not.
43 enum GuestThreadResidence : uint8_t {
44   kOutsideGeneratedCode = 0,
45   kInsideGeneratedCode = 1,
46 };
47 
48 GuestThreadResidence GetResidence(const ThreadState& state);
49 void SetResidence(ThreadState& state, GuestThreadResidence residence);
50 
51 // TODO(b/28058920): Refactor into GuestThread.
52 // Pending signals status state machine:
53 //   disabled <-> enabled <-> enabled and pending signals present
54 enum PendingSignalsStatus : uint_least8_t {
55   kPendingSignalsDisabled = 0,  // initial value, must be 0
56   kPendingSignalsEnabled,
57   kPendingSignalsPresent,  // implies enabled
58 };
59 
60 // Values are interpreted as PendingSignalsStatus.
61 std::atomic<uint_least8_t>& GetPendingSignalsStatusAtomic(ThreadState& state);
62 void SetPendingSignalsStatusAtomic(ThreadState& state, PendingSignalsStatus status);
63 
64 const CPUState& GetCPUState(const ThreadState& state);
65 CPUState& GetCPUState(ThreadState& state);
66 void SetCPUState(ThreadState& state, const CPUState& cpu);
67 
68 GuestAddr GetReturnValueRegister(const CPUState& cpu);
69 void SetReturnValueRegister(CPUState& cpu, GuestAddr val);
70 
71 void SetStackRegister(CPUState& cpu, GuestAddr val);
72 GuestAddr GetStackRegister(const CPUState& cpu);
73 
74 void SetLinkRegister(CPUState& cpu, GuestAddr val);
75 GuestAddr GetLinkRegister(const CPUState& cpu);
76 
77 void SetInsnAddr(CPUState& cpu, GuestAddr addr);
78 GuestAddr GetInsnAddr(const CPUState& cpu);
79 
80 // Assuming PC currently points to a supervisor call instruction, advance PC to the next
81 // instruction. Must be implemented according to the guest architecture.
82 void AdvanceInsnAddrBeyondSyscall(CPUState& cpu);
83 
84 // TODO(b/28058920): Refactor into GuestThread.
85 bool ArePendingSignalsPresent(const ThreadState& state);
86 
87 void SetTlsAddr(ThreadState& state, GuestAddr addr);
88 GuestAddr GetTlsAddr(const ThreadState& cpu);
89 
90 // Set the appropriate stack pointer register, if it exists for a given guest architecture.
91 void SetShadowCallStackPointer(CPUState& cpu, GuestAddr scs_sp);
92 
93 std::size_t GetThreadStateRegOffset(int reg);
94 
95 bool DoesCpuStateHaveDedicatedFpRegs();
96 std::size_t GetThreadStateFRegOffset(int freg);
97 
98 bool DoesCpuStateHaveDedicatedVecRegs();
99 std::size_t GetThreadStateVRegOffset(int vreg);
100 
101 bool DoesCpuStateHaveDedicatedSimdRegs();
102 std::size_t GetThreadStateSimdRegOffset(int simd_reg);
103 bool IsSimdOffset(size_t offset);
104 
105 std::size_t GetThreadStateReservationAddressOffset();
106 std::size_t GetThreadStateReservationValueOffset();
107 
108 bool DoesCpuStateHaveFlags();
109 std::size_t GetThreadStateFlagOffset();
110 
111 }  // namespace berberis
112 
113 #endif  // BERBERIS_GUEST_STATE_GUEST_STATE_OPAQUE_H_
114