diff options
Diffstat (limited to 'src/osd/modules/lib/osdlib_unix.cpp')
-rw-r--r-- | src/osd/modules/lib/osdlib_unix.cpp | 134 |
1 files changed, 77 insertions, 57 deletions
diff --git a/src/osd/modules/lib/osdlib_unix.cpp b/src/osd/modules/lib/osdlib_unix.cpp index c2a34be7c98..1c51a2666c7 100644 --- a/src/osd/modules/lib/osdlib_unix.cpp +++ b/src/osd/modules/lib/osdlib_unix.cpp @@ -8,23 +8,23 @@ // //============================================================ -#include <cstdlib> -#include <unistd.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <csignal> -#include <dlfcn.h> +// MAME headers +#include "osdcore.h" +#include "osdlib.h" +#include <SDL2/SDL.h> + +#include <csignal> #include <cstdio> +#include <cstdlib> #include <iomanip> #include <memory> +#include <dlfcn.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <unistd.h> -// MAME headers -#include "osdcore.h" -#include "osdlib.h" - -#include <SDL2/SDL.h> //============================================================ // osd_getenv @@ -54,37 +54,6 @@ void osd_process_kill() } //============================================================ -// osd_alloc_executable -// -// allocates "size" bytes of executable memory. this must take -// things like NX support into account. -//============================================================ - -void *osd_alloc_executable(size_t size) -{ -#if defined(SDLMAME_BSD) || defined(SDLMAME_MACOSX) || defined(SDLMAME_EMSCRIPTEN) - return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); -#else - return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, 0, 0); -#endif -} - -//============================================================ -// osd_free_executable -// -// frees memory allocated with osd_alloc_executable -//============================================================ - -void osd_free_executable(void *ptr, size_t size) -{ -#ifdef SDLMAME_SOLARIS - munmap((char *)ptr, size); -#else - munmap(ptr, size); -#endif -} - -//============================================================ // osd_break_into_debugger //============================================================ @@ -133,25 +102,23 @@ int osd_getpid(void) return getpid(); } -//============================================================ -// dynamic_module_posix_impl -//============================================================ namespace osd { + +namespace { + class dynamic_module_posix_impl : public dynamic_module { public: - dynamic_module_posix_impl(std::vector<std::string> &libraries) - : m_module(nullptr) + dynamic_module_posix_impl(std::vector<std::string> &&libraries) : m_libraries(std::move(libraries)) { - m_libraries = libraries; } virtual ~dynamic_module_posix_impl() override { - if (m_module != nullptr) + if (m_module) dlclose(m_module); - }; + } protected: virtual generic_fptr_t get_symbol_address(char const *symbol) override @@ -161,19 +128,17 @@ protected: * one of them, all additional symbols will be loaded from the same library */ if (m_module) - { return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol)); - } for (auto const &library : m_libraries) { - void *module = dlopen(library.c_str(), RTLD_LAZY); + void *const module = dlopen(library.c_str(), RTLD_LAZY); if (module != nullptr) { - generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol)); + generic_fptr_t const function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol)); - if (function != nullptr) + if (function) { m_module = module; return function; @@ -190,12 +155,67 @@ protected: private: std::vector<std::string> m_libraries; - void * m_module; + void * m_module = nullptr; }; +} // anonymous namespace + + +bool invalidate_instruction_cache(void const *start, std::size_t size) +{ + char const *const begin(reinterpret_cast<char const *>(start)); + char const *const end(begin + size); + __builtin___clear_cache(const_cast<char *>(begin), const_cast<char *>(end)); + return true; +} + + +void *virtual_memory_allocation::do_alloc(std::initializer_list<std::size_t> blocks, std::size_t &size, std::size_t &page_size) +{ + long const p(sysconf(_SC_PAGE_SIZE)); + if (0 >= p) + return nullptr; + std::size_t s(0); + for (std::size_t b : blocks) + s += (b + p - 1) / p; + s *= p; + if (!s) + return nullptr; +#if defined(SDLMAME_BSD) || defined(SDLMAME_MACOSX) || defined(SDLMAME_EMSCRIPTEN) + int const fd(-1); +#else + // TODO: portable applications are supposed to use -1 for anonymous mappings - detect whatever requires 0 specifically + int const fd(0); +#endif + void *const result(mmap(nullptr, s, PROT_NONE, MAP_ANON | MAP_SHARED, fd, 0)); + if (result == (void *)-1) + return nullptr; + size = s; + page_size = p; + return result; +} + +void virtual_memory_allocation::do_free(void *start, std::size_t size) +{ + munmap(reinterpret_cast<char *>(start), size); +} + +bool virtual_memory_allocation::do_set_access(void *start, std::size_t size, unsigned access) +{ + int prot((NONE == access) ? PROT_NONE : 0); + if (access & READ) + prot |= PROT_READ; + if (access & WRITE) + prot |= PROT_WRITE; + if (access & EXECUTE) + prot |= PROT_EXEC; + return mprotect(reinterpret_cast<char *>(start), size, prot) == 0; +} + + dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names) { - return std::make_unique<dynamic_module_posix_impl>(names); + return std::make_unique<dynamic_module_posix_impl>(std::move(names)); } } // namespace osd |