diff options
Diffstat (limited to 'src/osd/modules/lib/osdlib_macosx.cpp')
-rw-r--r-- | src/osd/modules/lib/osdlib_macosx.cpp | 228 |
1 files changed, 158 insertions, 70 deletions
diff --git a/src/osd/modules/lib/osdlib_macosx.cpp b/src/osd/modules/lib/osdlib_macosx.cpp index 372293ec1a3..54836f9ec69 100644 --- a/src/osd/modules/lib/osdlib_macosx.cpp +++ b/src/osd/modules/lib/osdlib_macosx.cpp @@ -8,26 +8,26 @@ // //============================================================ -#include <stdlib.h> -#include <unistd.h> -#include <sys/mman.h> -#include <sys/sysctl.h> -#include <sys/types.h> -#include <signal.h> -#include <dlfcn.h> +// MAME headers +#include "osdcore.h" +#include "osdlib.h" +#include <csignal> #include <cstdio> +#include <cstdlib> #include <iomanip> #include <memory> +#include <dlfcn.h> +#include <sys/mman.h> +#include <sys/sysctl.h> +#include <sys/types.h> +#include <unistd.h> #include <mach/mach.h> #include <mach/mach_time.h> #include <Carbon/Carbon.h> -// MAME headers -#include "osdcore.h" -#include "osdlib.h" //============================================================ // osd_getenv @@ -56,36 +56,6 @@ void osd_process_kill() kill(getpid(), SIGKILL); } -//============================================================ -// 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) - return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); -#elif defined(SDLMAME_UNIX) - 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 @@ -98,7 +68,7 @@ void osd_break_into_debugger(const char *message) struct kinfo_proc info; info.kp_proc.p_flag = 0; std::size_t infosz = sizeof(info); - sysctl(mib, ARRAY_LENGTH(mib), &info, &infosz, nullptr, 0); + sysctl(mib, std::size(mib), &info, &infosz, nullptr, 0); if (info.kp_proc.p_flag & P_TRACED) { printf("MAME exception: %s\n", message); @@ -113,10 +83,26 @@ void osd_break_into_debugger(const char *message) //============================================================ +// osd_get_cache_line_size +//============================================================ + +std::pair<std::error_condition, unsigned> osd_get_cache_line_size() noexcept +{ + size_t result = 0; + size_t resultsize = sizeof(result); + int const err = sysctlbyname("hw.cachelinesize", &result, &resultsize, 0, 0); + if (!err) + return std::make_pair(std::error_condition(), unsigned(result)); + else + return std::make_pair(std::error_condition(err, std::generic_category()), 0U); +} + + +//============================================================ // osd_get_clipboard_text //============================================================ -std::string osd_get_clipboard_text(void) +std::string osd_get_clipboard_text() noexcept { std::string result; bool has_result = false; @@ -152,31 +138,48 @@ std::string osd_get_clipboard_text(void) CFStringEncoding encoding; if (UTTypeConformsTo(flavor_type, kUTTypeUTF16PlainText)) encoding = kCFStringEncodingUTF16; - else if (UTTypeConformsTo (flavor_type, kUTTypeUTF8PlainText)) + else if (UTTypeConformsTo(flavor_type, kUTTypeUTF8PlainText)) encoding = kCFStringEncodingUTF8; - else if (UTTypeConformsTo (flavor_type, kUTTypePlainText)) + else if (UTTypeConformsTo(flavor_type, kUTTypePlainText)) encoding = kCFStringEncodingMacRoman; else continue; CFDataRef flavor_data; err = PasteboardCopyItemFlavorData(pasteboard_ref, item_id, flavor_type, &flavor_data); + if (err) + continue; - if (!err) + CFDataRef utf8_data; + if (kCFStringEncodingUTF8 == encoding) + { + utf8_data = flavor_data; + } + else { CFStringRef string_ref = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, flavor_data, encoding); - CFDataRef data_ref = CFStringCreateExternalRepresentation (kCFAllocatorDefault, string_ref, kCFStringEncodingUTF8, '?'); - CFRelease(string_ref); CFRelease(flavor_data); + if (!string_ref) + continue; - CFIndex const length = CFDataGetLength(data_ref); - CFRange const range = CFRangeMake(0, length); - - result.resize(length); - CFDataGetBytes(data_ref, range, reinterpret_cast<unsigned char *>(&result[0])); - has_result = true; + utf8_data = CFStringCreateExternalRepresentation(kCFAllocatorDefault, string_ref, kCFStringEncodingUTF8, '?'); + CFRelease(string_ref); + } - CFRelease(data_ref); + if (utf8_data) + { + CFIndex const length = CFDataGetLength(utf8_data); + CFRange const range = CFRangeMake(0, length); + try + { + result.resize(length); + CFDataGetBytes(utf8_data, range, reinterpret_cast<UInt8 *>(result.data())); + has_result = true; + } + catch (std::bad_alloc const &) + { + } + CFRelease(utf8_data); } } @@ -188,34 +191,72 @@ std::string osd_get_clipboard_text(void) return result; } + //============================================================ -// osd_getpid +// osd_set_clipboard_text //============================================================ -int osd_getpid(void) +std::error_condition osd_set_clipboard_text(std::string_view text) noexcept { - return getpid(); + // FIXME: better conversion of OSStatus to std::error_condition + OSStatus err; + + CFDataRef const data = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<UInt8 const *>(text.data()), text.length()); + if (!data) + return std::errc::not_enough_memory; + + PasteboardRef pasteboard_ref; + err = PasteboardCreate(kPasteboardClipboard, &pasteboard_ref); + if (err) + { + CFRelease(data); + return std::errc::io_error; + } + + err = PasteboardClear(pasteboard_ref); + if (err) + { + CFRelease(data); + CFRelease(pasteboard_ref); + return std::errc::io_error; + } + + err = PasteboardPutItemFlavor(pasteboard_ref, PasteboardItemID(1), kUTTypeUTF8PlainText, data, kPasteboardFlavorNoFlags); + CFRelease(data); + CFRelease(pasteboard_ref); + if (err) + return std::errc::io_error; + + return std::error_condition(); } + //============================================================ -// dynamic_module_posix_impl +// osd_getpid //============================================================ +int osd_getpid() noexcept +{ + return getpid(); +} + + 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 @@ -225,19 +266,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; @@ -254,12 +293,61 @@ 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) noexcept +{ + 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, unsigned intent, std::size_t &size, std::size_t &page_size) noexcept +{ + 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; + void *const result(mmap(nullptr, s, PROT_NONE, MAP_ANON | MAP_SHARED, -1, 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) noexcept +{ + munmap(start, size); +} + +bool virtual_memory_allocation::do_set_access(void *start, std::size_t size, unsigned access) noexcept +{ + 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(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 |