From f7af9c3316153ed43ec784fecf0e548cd5deff88 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Mon, 22 Apr 2019 10:12:28 +1000 Subject: [PATCH] include/coreinit: First pass at coreinit/codegen.h --- include/coreinit/codegen.h | 128 ++++++++++++++++++ .../test_compile_headers_list.h | 1 + 2 files changed, 129 insertions(+) create mode 100644 include/coreinit/codegen.h diff --git a/include/coreinit/codegen.h b/include/coreinit/codegen.h new file mode 100644 index 0000000..893d55d --- /dev/null +++ b/include/coreinit/codegen.h @@ -0,0 +1,128 @@ +#pragma once +#include + +/** + * \defgroup coreinit_codegen Codegen + * \ingroup coreinit + * + * Controls a memory area that can switch between writable and + * executable states, allowing dynamic code generation. + * For some applications, a codegen area is avilable for things like JIT or + * otherwise generating CPU instructions on the fly. Enabled apps can use + * \link OSCodegenGetVirtAddrRange \endlink to discover this area, then use + * \link OSSwitchSecCodeGenMode \endlink or \link OSCodegenCopy \endlink to + * move instructions in and out before executing them. Codegen can only be used + * from a specific, predetermined CPU core - see + * \link OSGetCodegenCore \endlink. Codegen can only be used when enabled in an + * app's cos.xml. + * + * + * + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +//! The memory permissions for the codegen area. +typedef enum OSCodegenSecMode +{ + //! The area can be read or written to, but not executed. + CODEGEN_RW_ = 0, + //! The area can be read or executed, but not written to. + CODEGEN_R_X = 1, +} OSCodegenSecMode; + +/** + * Gets the location and size of codegen memory, if available. + * + * \param outVirtualAddress + * Pointer to write the virtual address of the codegen area to. Will write 0 if + * codegen isn't available. + * + * \param outSize + * Pointer to write the size of the codegen area to. Will write 0 if codegen + * isn't available. + * + * \sa + * - \link OSGetSecCodeGenMode \endlink + */ +void +OSCodegenGetVirtAddrRange(uint32_t* outVirtualAddress, + uint32_t* outSize); + +/** + * Gets the CPU core that's allowed to use codegen. + * + * \return + * The core id of the core that can use codegen. + * + * \sa + * - \link OSGetCoreId \endlink + * + * + */ +uint32_t +OSGetCodegenCore(); + +uint32_t +OSGetCodegenMode(); + +/** + * Switches the permissions on the codegen memory area. Use this function to + * move between writing code and executing it. + * + * \param mode + * The memory permission mode to use - one of \link OSCodegenSecMode \endlink. + * + * \returns + * \c true on success, or \c false on a failure, such as codegen not being + * available for this app or CPU core. + */ +BOOL +OSSwitchSecCodeGenMode(OSCodegenSecMode mode); + +//TODO: online docs imply this returns true if codegen is *enabled*, though the +//name would imply it gets rw/rx status. +uint32_t +OSGetSecCodeGenMode(); + +/** + * Copies data from normal memory into the codegen area, leaving the area in + * \link CODEGEN_R_X \endlink mode. + * This function copies into the codegen area regardless + * of the current permission status by switching modes as required for the copy. + * + * \param dst + * The starting virtual address of the area in codegen memory to copy to. Must + * be a valid pointer + * + * \param src + * The starting virtual address of the source to copy from. Must be a valid + * pointer. + * + * \param size + * The size of the data to copy. Must not be 0, and must be small + * enough such that dst + size does not pass the end of the codegen + * area (see \link OSCodegenGetVirtAddrRange \endlink). + * + * \return + * \c TRUE on success, indicating the codegen area is now in + * \link CODEGEN_R_X \endlink, or \c FALSE on an error, such as invalid pointers + * or codegen not being available. + * + * + */ +BOOL +OSCodegenCopy(void* dst, void* src, size_t size); + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/tests/test_compile_headers_common/test_compile_headers_list.h b/tests/test_compile_headers_common/test_compile_headers_list.h index ef9ffcd..dde4168 100644 --- a/tests/test_compile_headers_common/test_compile_headers_list.h +++ b/tests/test_compile_headers_common/test_compile_headers_list.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include