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