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