/*---------------------------------------------------------------------------* Project: Horizon File: os_StackMemory.h Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 24156 $ *---------------------------------------------------------------------------*/ #ifndef NN_OS_OS_STACKMEMORY_H_ #define NN_OS_OS_STACKMEMORY_H_ #include #if NN_PLATFORM_HAS_MMU #include #include #include #include #include #ifdef __cplusplus #include #include #include namespace nn{ namespace os{ namespace detail { void InitializeStackMemory(); } /*! @brief 指定されたメモリ領域をスタック用に隔離するクラスです。 指定されたメモリ領域を 前後に 4 KByte の未マップ領域を確保した異なるアドレスに マッピングしなおします。 前後に未マップ領域が配置されるため、 スタックに使用することでスタックオーバーフローや スタックアンダーフローをデータアボートとして 検出することができます。 */ class StackMemory : public MemoryBlockBase { private: uptr m_MemoryAddress; public: /*! :overload notinit @brief オブジェクトを構築します。 引数を指定しない場合は初期化を行いません。別途 @ref Initialize を呼び出す必要があります。 */ StackMemory() {} /*! :overload init @brief オブジェクトを構築し、メモリ領域の隔離を行います。 内部で Initialize を呼び出します。 @param[in] pMem 隔離するメモリ領域の先頭を挿すポインタ。 4096 Byte アライメントされていなければなりません。 @param[in] size 隔離するメモリ領域のサイズ。 size は 4096 の倍数でなければなりません。 */ explicit StackMemory(void* pMem, size_t size) { Initialize(pMem, size); } /*! @brief メモリ領域を隔離します。 引数で指定されたメモリ領域を 前後に 4 KByte の未マップ領域を確保した異なるアドレスに マッピングしなおします。 以後、Finalize を呼び出すまで指定された指定されたアドレス範囲は アクセス禁止となります。 新たなマッピング先のアドレスは MemoryBlockBase::GetAddress で取得できます。 @param[in] pMem 隔離するメモリ領域の先頭を挿すポインタ。 4096 Byte アライメントされていなければなりません。 @param[in] size 隔離するメモリ領域のサイズ。 size は 4096 の倍数でなければなりません。 */ void Initialize(void* pMem, size_t size); /*! @brief オブジェクトを破棄します。 Finalize が呼び出されていない場合は Finalize の呼び出しも行います。 */ ~StackMemory() { Finalize(); } /*! @brief メモリ領域の隔離を解除します。 隔離先へのマッピングを解除し、 元々のアドレスでアクセス可能な状態に戻します。 */ void* Finalize(); /*! @brief 確保しているメモリ領域の終端アドレスを取得します。 Thread::Start に StackMemoryBlock のインスタンスを 直接渡すためのインターフェイスです。 @return 確保しているメモリ領域の終端アドレスを返します。 */ uptr GetStackBottom() const { return GetAddress() + GetSize(); } /*! @brief 確保しているメモリ領域のサイズを取得します。 Thread::Start に StackMemoryBlock のインスタンスを 直接渡すためのインターフェイスです。 @return 確保しているメモリ領域のサイズを返します。 */ size_t GetStackSize() const { return GetSize(); } void MoveFrom(StackMemory* pFrom); }; }} // namespace nn::os #endif // __cplusplus // 以下、C 用宣言 #include /*! @addtogroup nn_os os @{ @defgroup nn_os_StackMemory_c StackMemory (C) @brief @ref nn::os::StackMemory の C インタフェースモジュールです。 @{ */ /*! @struct nnosStackMemory @brief スタックから確保したメモリブロックを表す C の構造体です。 @brief 対応するクラス @ref nn::os::StackMemory を参照してください。 */ NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosStackMemory, nn::os::StackMemory, 24, u32); /*! @brief 対応する C++ 関数 @ref nn::os::StackMemory::Initialize を参照してください。 */ NN_EXTERN_C void nnosStackMemoryProtect(nnosStackMemory* p, void* pMem, size_t size); /* @brief 対応する C++ 関数 @ref nn::os::StackMemory::Finalize を参照してください。 */ NN_EXTERN_C void nnosStackMemoryUnprotect(nnosStackMemory* p); /*! @brief 対応する C++ 関数 @ref nn::os::StackMemory::GetAddress を参照してください。 */ NN_EXTERN_C uptr nnosStackMemoryGetAddress(nnosStackMemory* p); /*! @brief 対応する C++ 関数 @ref nn::os::StackMemory::GetSize を参照してください。 */ NN_EXTERN_C size_t nnosStackMemoryGetSize(nnosStackMemory* p); /*! @brief 対応する C++ 関数 @ref nn::os::StackMemory::GetStackBottom を参照してください。 */ NN_EXTERN_C uptr nnosStackMemoryGetStackBottom(nnosStackMemory* p); /*! @} @} */ #endif // if NN_PLATFORM_HAS_MMU #endif /* NN_OS_OS_STACKMEMORY_H_ */