Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 75 additions & 90 deletions src/osd/modules/lib/osdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <type_traits>
#include <vector>
#include <memory>
#include <cstdint> // For std::uint8_t

/*-----------------------------------------------------------------------------
osd_process_kill: kill the current process
Expand All @@ -36,7 +37,6 @@

void osd_process_kill();


/*-----------------------------------------------------------------------------
osd_setenv: set environment variable

Expand All @@ -53,98 +53,85 @@ void osd_process_kill();

int osd_setenv(const char *name, const char *value, int overwrite);


/*-----------------------------------------------------------------------------
osd_get_clipboard_text: retrieves text from the clipboard
-----------------------------------------------------------------------------*/
std::string osd_get_clipboard_text();


namespace osd {

bool invalidate_instruction_cache(void const *start, std::size_t size);


class virtual_memory_allocation
{
class virtual_memory_allocation {
public:
enum : unsigned
{
NONE = 0x00,
READ = 0x01,
WRITE = 0x02,
EXECUTE = 0x04,
READ_WRITE = READ | WRITE,
READ_EXECUTE = READ | EXECUTE,
READ_WRITE_EXECUTE = READ | WRITE | EXECUTE
};

virtual_memory_allocation(virtual_memory_allocation const &) = delete;
virtual_memory_allocation &operator=(virtual_memory_allocation const &) = delete;

virtual_memory_allocation() { }
virtual_memory_allocation(std::initializer_list<std::size_t> blocks, unsigned intent)
{
m_memory = do_alloc(blocks, intent, m_size, m_page_size);
}
virtual_memory_allocation(virtual_memory_allocation &&that) : m_memory(that.m_memory), m_size(that.m_size), m_page_size(that.m_page_size)
{
that.m_memory = nullptr;
that.m_size = that.m_page_size = 0U;
}
~virtual_memory_allocation()
{
if (m_memory)
do_free(m_memory, m_size);
}

explicit operator bool() const { return bool(m_memory); }
void *get() { return m_memory; }
std::size_t size() const { return m_size; }
std::size_t page_size() const { return m_page_size; }

bool set_access(std::size_t start, std::size_t size, unsigned access)
{
if ((start % m_page_size) || (size % m_page_size) || (start > m_size) || ((m_size - start) < size))
return false;
else
return do_set_access(reinterpret_cast<std::uint8_t *>(m_memory) + start, size, access);
}

virtual_memory_allocation &operator=(std::nullptr_t)
{
if (m_memory)
do_free(m_memory, m_size);
m_memory = nullptr;
m_size = m_page_size = 0U;
return *this;
}

virtual_memory_allocation &operator=(virtual_memory_allocation &&that)
{
if (&that != this)
{
if (m_memory)
do_free(m_memory, m_size);
m_memory = that.m_memory;
m_size = that.m_size;
m_page_size = that.m_page_size;
that.m_memory = nullptr;
that.m_size = that.m_page_size = 0U;
}
return *this;
}
enum : unsigned {
NONE = 0x00,
READ = 0x01,
WRITE = 0x02,
EXECUTE = 0x04,
READ_WRITE = READ | WRITE,
READ_EXECUTE = READ | EXECUTE,
READ_WRITE_EXECUTE = READ | WRITE | EXECUTE
};

virtual_memory_allocation(virtual_memory_allocation const &) = delete;
virtual_memory_allocation &operator=(virtual_memory_allocation const &) = delete;

virtual_memory_allocation() { }
virtual_memory_allocation(std::initializer_list<std::size_t> blocks, unsigned intent) {
m_memory = do_alloc(blocks, intent, m_size, m_page_size);
}
virtual_memory_allocation(virtual_memory_allocation &&that) : m_memory(that.m_memory), m_size(that.m_size), m_page_size(that.m_page_size) {
that.m_memory = nullptr;
that.m_size = that.m_page_size = 0U;
}
~virtual_memory_allocation() {
if (m_memory)
do_free(m_memory, m_size);
}

explicit operator bool() const { return bool(m_memory); }
void *get() { return m_memory; }
std::size_t size() const { return m_size; }
std::size_t page_size() const { return m_page_size; }

bool set_access(std::size_t start, std::size_t size, unsigned access) {
if ((start % m_page_size) || (size % m_page_size) || (start > m_size) || ((m_size - start) < size))
return false;
else
return do_set_access(reinterpret_cast<std::uint8_t *>(m_memory) + start, size, access);
}

virtual_memory_allocation &operator=(std::nullptr_t) {
if (m_memory)
do_free(m_memory, m_size);
m_memory = nullptr;
m_size = m_page_size = 0U;
return *this;
}

virtual_memory_allocation &operator=(virtual_memory_allocation &&that) {
if (&that != this) {
if (m_memory)
do_free(m_memory, m_size);
m_memory = that.m_memory;
m_size = that.m_size;
m_page_size = that.m_page_size;
that.m_memory = nullptr;
that.m_size = that.m_page_size = 0U;
}
return *this;
}

private:
static void *do_alloc(std::initializer_list<std::size_t> blocks, unsigned intent, std::size_t &size, std::size_t &page_size);
static void do_free(void *start, std::size_t size);
static bool do_set_access(void *start, std::size_t size, unsigned access);
static void *do_alloc(std::initializer_list<std::size_t> blocks, unsigned intent, std::size_t &size, std::size_t &page_size);
static void do_free(void *start, std::size_t size);
static bool do_set_access(void *start, std::size_t size, unsigned access);

void *m_memory = nullptr;
std::size_t m_size = 0U, m_page_size = 0U;
void *m_memory = nullptr;
std::size_t m_size = 0U, m_page_size = 0U;
};


/*-----------------------------------------------------------------------------
dynamic_module: load functions from optional shared libraries

Expand All @@ -156,25 +143,23 @@ class virtual_memory_allocation
revisions of a same library)
-----------------------------------------------------------------------------*/

class dynamic_module
{
class dynamic_module {
public:
typedef std::unique_ptr<dynamic_module> ptr;
typedef std::unique_ptr<dynamic_module> ptr;

static ptr open(std::vector<std::string> &&libraries);
static ptr open(std::vector<std::string> &&libraries);

virtual ~dynamic_module() { };
virtual ~dynamic_module() { };

template <typename T>
typename std::enable_if_t<std::is_pointer_v<T>, T> bind(char const *symbol)
{
return reinterpret_cast<T>(get_symbol_address(symbol));
}
template <typename T>
typename std::enable_if_t<std::is_pointer_v<T>, T> bind(char const *symbol) {
return reinterpret_cast<T>(get_symbol_address(symbol));
}

protected:
typedef void (*generic_fptr_t)();
typedef void (*generic_fptr_t)();

virtual generic_fptr_t get_symbol_address(char const *symbol) = 0;
virtual generic_fptr_t get_symbol_address(char const *symbol) = 0;
};

} // namespace osd
Expand Down