1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: os_StackMemory.h 4 5 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 24156 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NN_OS_OS_STACKMEMORY_H_ 17 #define NN_OS_OS_STACKMEMORY_H_ 18 19 #include <nn/config.h> 20 #if NN_PLATFORM_HAS_MMU 21 22 #include <nn/types.h> 23 #include <nn/Handle.h> 24 #include <nn/svc.h> 25 #include <nn/os/CTR/os_MemoryConfig.h> 26 #include <nn/os/os_MemoryBlockBase.h> 27 28 #ifdef __cplusplus 29 30 #include <nn/util/util_NonCopyable.h> 31 #include <nn/os/os_SvcTypes.autogen.h> 32 #include <nn/util/util_Result.h> 33 34 namespace nn{ namespace os{ 35 36 namespace detail 37 { 38 void InitializeStackMemory(); 39 } 40 41 42 /*! 43 @brief 指定されたメモリ領域をスタック用に隔離するクラスです。 44 45 指定されたメモリ領域を 46 前後に 4 KByte の未マップ領域を確保した異なるアドレスに 47 マッピングしなおします。 48 49 前後に未マップ領域が配置されるため、 50 スタックに使用することでスタックオーバーフローや 51 スタックアンダーフローをデータアボートとして 52 検出することができます。 53 */ 54 class StackMemory : public MemoryBlockBase 55 { 56 private: 57 uptr m_MemoryAddress; 58 59 public: 60 /*! 61 :overload notinit 62 63 @brief オブジェクトを構築します。 64 65 引数を指定しない場合は初期化を行いません。別途 @ref Initialize を呼び出す必要があります。 66 */ StackMemory()67 StackMemory() {} 68 69 /*! 70 :overload init 71 72 @brief オブジェクトを構築し、メモリ領域の隔離を行います。 73 74 内部で Initialize を呼び出します。 75 76 @param[in] pMem 隔離するメモリ領域の先頭を挿すポインタ。 77 4096 Byte アライメントされていなければなりません。 78 @param[in] size 隔離するメモリ領域のサイズ。 79 size は 4096 の倍数でなければなりません。 80 */ StackMemory(void * pMem,size_t size)81 explicit StackMemory(void* pMem, size_t size) { Initialize(pMem, size); } 82 83 84 /*! 85 @brief メモリ領域を隔離します。 86 87 引数で指定されたメモリ領域を 88 前後に 4 KByte の未マップ領域を確保した異なるアドレスに 89 マッピングしなおします。 90 以後、Finalize を呼び出すまで指定された指定されたアドレス範囲は 91 アクセス禁止となります。 92 新たなマッピング先のアドレスは MemoryBlockBase::GetAddress で取得できます。 93 94 @param[in] pMem 隔離するメモリ領域の先頭を挿すポインタ。 95 4096 Byte アライメントされていなければなりません。 96 @param[in] size 隔離するメモリ領域のサイズ。 97 size は 4096 の倍数でなければなりません。 98 */ 99 void Initialize(void* pMem, size_t size); 100 101 /*! 102 @brief オブジェクトを破棄します。 103 104 Finalize が呼び出されていない場合は 105 Finalize の呼び出しも行います。 106 */ ~StackMemory()107 ~StackMemory() { Finalize(); } 108 109 /*! 110 @brief メモリ領域の隔離を解除します。 111 112 隔離先へのマッピングを解除し、 113 元々のアドレスでアクセス可能な状態に戻します。 114 */ 115 void* Finalize(); 116 117 /*! 118 @brief 確保しているメモリ領域の終端アドレスを取得します。 119 120 Thread::Start に StackMemoryBlock のインスタンスを 121 直接渡すためのインターフェイスです。 122 123 @return 確保しているメモリ領域の終端アドレスを返します。 124 */ GetStackBottom()125 uptr GetStackBottom() const { return GetAddress() + GetSize(); } 126 127 /*! 128 @brief 確保しているメモリ領域のサイズを取得します。 129 130 Thread::Start に StackMemoryBlock のインスタンスを 131 直接渡すためのインターフェイスです。 132 133 @return 確保しているメモリ領域のサイズを返します。 134 */ GetStackSize()135 size_t GetStackSize() const { return GetSize(); } 136 137 void MoveFrom(StackMemory* pFrom); 138 }; 139 140 141 142 }} // namespace nn::os 143 144 #endif // __cplusplus 145 146 // 以下、C 用宣言 147 148 #include <nn/util/detail/util_CLibImpl.h> 149 150 /*! 151 @addtogroup nn_os os 152 @{ 153 154 @defgroup nn_os_StackMemory_c StackMemory (C) 155 156 @brief @ref nn::os::StackMemory の C インタフェースモジュールです。 157 158 @{ 159 */ 160 161 /*! 162 @struct nnosStackMemory 163 @brief スタックから確保したメモリブロックを表す C の構造体です。 164 165 @brief 対応するクラス @ref nn::os::StackMemory を参照してください。 166 */ 167 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosStackMemory, nn::os::StackMemory, 24, u32); 168 169 170 /*! 171 @brief 対応する C++ 関数 @ref nn::os::StackMemory::Initialize を参照してください。 172 */ 173 NN_EXTERN_C void nnosStackMemoryProtect(nnosStackMemory* p, void* pMem, size_t size); 174 175 /* 176 @brief 対応する C++ 関数 @ref nn::os::StackMemory::Finalize を参照してください。 177 */ 178 NN_EXTERN_C void nnosStackMemoryUnprotect(nnosStackMemory* p); 179 180 /*! 181 @brief 対応する C++ 関数 @ref nn::os::StackMemory::GetAddress を参照してください。 182 */ 183 NN_EXTERN_C uptr nnosStackMemoryGetAddress(nnosStackMemory* p); 184 185 /*! 186 @brief 対応する C++ 関数 @ref nn::os::StackMemory::GetSize を参照してください。 187 */ 188 NN_EXTERN_C size_t nnosStackMemoryGetSize(nnosStackMemory* p); 189 190 /*! 191 @brief 対応する C++ 関数 @ref nn::os::StackMemory::GetStackBottom を参照してください。 192 */ 193 NN_EXTERN_C uptr nnosStackMemoryGetStackBottom(nnosStackMemory* p); 194 195 /*! 196 @} 197 198 @} 199 */ 200 201 #endif // if NN_PLATFORM_HAS_MMU 202 #endif /* NN_OS_OS_STACKMEMORY_H_ */ 203