xref: /aosp_15_r20/art/runtime/arch/context.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_ARCH_CONTEXT_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_ARCH_CONTEXT_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <stddef.h>
21*795d594fSAndroid Build Coastguard Worker #include <stdint.h>
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include "arch/instruction_set.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
25*795d594fSAndroid Build Coastguard Worker #include "entrypoints/quick/runtime_entrypoints_list.h"
26*795d594fSAndroid Build Coastguard Worker 
27*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
28*795d594fSAndroid Build Coastguard Worker 
29*795d594fSAndroid Build Coastguard Worker class QuickMethodFrameInfo;
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker // Representation of a thread's context on the executing machine, used to implement long jumps in
32*795d594fSAndroid Build Coastguard Worker // the quick stack frame layout.
33*795d594fSAndroid Build Coastguard Worker class Context {
34*795d594fSAndroid Build Coastguard Worker  public:
35*795d594fSAndroid Build Coastguard Worker   // Creates a context for the running architecture
36*795d594fSAndroid Build Coastguard Worker   EXPORT static Context* Create();
37*795d594fSAndroid Build Coastguard Worker 
~Context()38*795d594fSAndroid Build Coastguard Worker   virtual ~Context() {}
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker   // Re-initializes the registers for context re-use.
41*795d594fSAndroid Build Coastguard Worker   virtual void Reset() = 0;
42*795d594fSAndroid Build Coastguard Worker 
43*795d594fSAndroid Build Coastguard Worker   template <InstructionSet kIsa>
CalleeSaveAddress(uint8_t * frame,int num,size_t frame_size)44*795d594fSAndroid Build Coastguard Worker   static uintptr_t* CalleeSaveAddress(uint8_t* frame, int num, size_t frame_size) {
45*795d594fSAndroid Build Coastguard Worker     static constexpr size_t kPointerSize = static_cast<size_t>(GetInstructionSetPointerSize(kIsa));
46*795d594fSAndroid Build Coastguard Worker     // Callee saves are held at the top of the frame
47*795d594fSAndroid Build Coastguard Worker     uint8_t* save_addr = frame + frame_size - ((num + 1) * kPointerSize);
48*795d594fSAndroid Build Coastguard Worker     if (kIsa == InstructionSet::kX86 || kIsa == InstructionSet::kX86_64) {
49*795d594fSAndroid Build Coastguard Worker       save_addr -= kPointerSize;  // account for return address
50*795d594fSAndroid Build Coastguard Worker     }
51*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<uintptr_t*>(save_addr);
52*795d594fSAndroid Build Coastguard Worker   }
53*795d594fSAndroid Build Coastguard Worker 
54*795d594fSAndroid Build Coastguard Worker   // Reads values from callee saves in the given frame. The frame also holds
55*795d594fSAndroid Build Coastguard Worker   // the method that holds the layout.
56*795d594fSAndroid Build Coastguard Worker   virtual void FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& fr) = 0;
57*795d594fSAndroid Build Coastguard Worker 
58*795d594fSAndroid Build Coastguard Worker   // Sets the stack pointer value.
59*795d594fSAndroid Build Coastguard Worker   virtual void SetSP(uintptr_t new_sp) = 0;
60*795d594fSAndroid Build Coastguard Worker 
61*795d594fSAndroid Build Coastguard Worker   // Sets the program counter value.
62*795d594fSAndroid Build Coastguard Worker   virtual void SetPC(uintptr_t new_pc) = 0;
63*795d594fSAndroid Build Coastguard Worker 
64*795d594fSAndroid Build Coastguard Worker   // Sets the first argument register.
65*795d594fSAndroid Build Coastguard Worker   virtual void SetArg0(uintptr_t new_arg0_value) = 0;
66*795d594fSAndroid Build Coastguard Worker 
67*795d594fSAndroid Build Coastguard Worker   // Returns whether the given GPR is accessible (read or write).
68*795d594fSAndroid Build Coastguard Worker   virtual bool IsAccessibleGPR(uint32_t reg) = 0;
69*795d594fSAndroid Build Coastguard Worker 
70*795d594fSAndroid Build Coastguard Worker   // Gets the given GPRs address.
71*795d594fSAndroid Build Coastguard Worker   virtual uintptr_t* GetGPRAddress(uint32_t reg) = 0;
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker   // Reads the given GPR. The caller is responsible for checking the register
74*795d594fSAndroid Build Coastguard Worker   // is accessible with IsAccessibleGPR.
75*795d594fSAndroid Build Coastguard Worker   virtual uintptr_t GetGPR(uint32_t reg) = 0;
76*795d594fSAndroid Build Coastguard Worker 
77*795d594fSAndroid Build Coastguard Worker   // Sets the given GPR. The caller is responsible for checking the register
78*795d594fSAndroid Build Coastguard Worker   // is accessible with IsAccessibleGPR.
79*795d594fSAndroid Build Coastguard Worker   virtual void SetGPR(uint32_t reg, uintptr_t value) = 0;
80*795d594fSAndroid Build Coastguard Worker 
81*795d594fSAndroid Build Coastguard Worker   // Returns whether the given FPR is accessible (read or write).
82*795d594fSAndroid Build Coastguard Worker   virtual bool IsAccessibleFPR(uint32_t reg) = 0;
83*795d594fSAndroid Build Coastguard Worker 
84*795d594fSAndroid Build Coastguard Worker   // Reads the given FPR. The caller is responsible for checking the register
85*795d594fSAndroid Build Coastguard Worker   // is accessible with IsAccessibleFPR.
86*795d594fSAndroid Build Coastguard Worker   virtual uintptr_t GetFPR(uint32_t reg) = 0;
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker   // Sets the given FPR. The caller is responsible for checking the register
89*795d594fSAndroid Build Coastguard Worker   // is accessible with IsAccessibleFPR.
90*795d594fSAndroid Build Coastguard Worker   virtual void SetFPR(uint32_t reg, uintptr_t value) = 0;
91*795d594fSAndroid Build Coastguard Worker 
92*795d594fSAndroid Build Coastguard Worker   // Smashes the caller save registers. If we're throwing, we don't want to return bogus values.
93*795d594fSAndroid Build Coastguard Worker   virtual void SmashCallerSaves() = 0;
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker   // Set `new_value` to the physical register containing the dex PC pointer in
96*795d594fSAndroid Build Coastguard Worker   // an nterp frame.
SetNterpDexPC(uintptr_t new_value)97*795d594fSAndroid Build Coastguard Worker   virtual void SetNterpDexPC([[maybe_unused]] uintptr_t new_value) { abort(); }
98*795d594fSAndroid Build Coastguard Worker 
99*795d594fSAndroid Build Coastguard Worker   // Copies the values of GPRs and FPRs registers from this context to external buffers;
100*795d594fSAndroid Build Coastguard Worker   // the use case is to do a long jump afterwards.
101*795d594fSAndroid Build Coastguard Worker   virtual void CopyContextTo(uintptr_t* gprs, uintptr_t* fprs) = 0;
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker   enum {
104*795d594fSAndroid Build Coastguard Worker     kBadGprBase = 0xebad6070,
105*795d594fSAndroid Build Coastguard Worker     kBadFprBase = 0xebad8070,
106*795d594fSAndroid Build Coastguard Worker   };
107*795d594fSAndroid Build Coastguard Worker };
108*795d594fSAndroid Build Coastguard Worker 
109*795d594fSAndroid Build Coastguard Worker }  // namespace art
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_ARCH_CONTEXT_H_
112