WIP
This commit is contained in:
parent
4e2437dbd6
commit
c60428c600
2
dependencies/trampoline/src
vendored
2
dependencies/trampoline/src
vendored
@ -1 +1 @@
|
|||||||
Subproject commit b2cf446e9dd5593c388c1f244c527741070f7a26
|
Subproject commit 027e58ee9bdcfef285c16e731c8db218082b9639
|
@ -29,7 +29,7 @@ static void setup_environment(const options_t &options) {
|
|||||||
bind_to_env("_MCPI_ONLY_GENERATE", options.only_generate);
|
bind_to_env("_MCPI_ONLY_GENERATE", options.only_generate);
|
||||||
#endif
|
#endif
|
||||||
#ifdef MCPI_USE_NATIVE_TRAMPOLINE
|
#ifdef MCPI_USE_NATIVE_TRAMPOLINE
|
||||||
bind_to_env(TRAMPOLINE_USE_PTRACE_ENV, options.use_ptrace_trampoline);
|
bind_to_env(TRAMPOLINE_USE_PIPES_ENV, !options.use_ptrace_trampoline);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// GTK Dark Mode
|
// GTK Dark Mode
|
||||||
|
@ -20,7 +20,7 @@ if(BUILD_NATIVE_COMPONENTS)
|
|||||||
elseif(BUILD_ARM_COMPONENTS)
|
elseif(BUILD_ARM_COMPONENTS)
|
||||||
# Guest Component
|
# Guest Component
|
||||||
add_library(media-layer-core SHARED src/guest/guest.cpp ${MEDIA_LAYER_TRAMPOLINE_SRC} $<TARGET_OBJECTS:media-layer-extras>)
|
add_library(media-layer-core SHARED src/guest/guest.cpp ${MEDIA_LAYER_TRAMPOLINE_SRC} $<TARGET_OBJECTS:media-layer-extras>)
|
||||||
target_link_libraries(media-layer-core PUBLIC media-layer-headers PRIVATE reborn-util PRIVATE trampoline-headers)
|
target_link_libraries(media-layer-core PUBLIC media-layer-headers PRIVATE reborn-util PRIVATE trampoline-headers PRIVATE rt)
|
||||||
target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_TRAMPOLINE_GUEST)
|
target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
# Install
|
# Install
|
||||||
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
|
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
|
||||||
|
@ -21,25 +21,100 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params))
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer
|
// Track GL State
|
||||||
|
struct gl_array_state_t {
|
||||||
|
bool enabled = false;
|
||||||
|
GLint size = 0;
|
||||||
|
GLenum type = 0;
|
||||||
|
GLsizei stride = 0;
|
||||||
|
uint32_t pointer = 0;
|
||||||
|
bool operator==(const gl_array_state_t &other) const {
|
||||||
|
return enabled == other.enabled && size == other.size && type == other.type && stride == other.stride && pointer == other.pointer;
|
||||||
|
}
|
||||||
|
bool operator!=(const gl_array_state_t &other) const {
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct gl_state_t {
|
||||||
|
GLuint bound_array_buffer = 0;
|
||||||
|
GLuint bound_texture = 0;
|
||||||
|
gl_array_state_t vertex_array;
|
||||||
|
gl_array_state_t color_array;
|
||||||
|
gl_array_state_t tex_coord_array;
|
||||||
|
// Update State
|
||||||
|
static typeof(glVertexPointer) *get_array_pointer_function(const GLenum array) {
|
||||||
|
switch (array) {
|
||||||
|
case GL_VERTEX_ARRAY: {
|
||||||
|
return glVertexPointer;
|
||||||
|
}
|
||||||
|
case GL_COLOR_ARRAY: {
|
||||||
|
return glColorPointer;
|
||||||
|
}
|
||||||
|
case GL_TEXTURE_COORD_ARRAY: {
|
||||||
|
return glTexCoordPointer;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
ERR("Unsupported Array Type: %i", array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gl_array_state_t &get_array_state(const GLenum array) {
|
||||||
|
switch (array) {
|
||||||
|
case GL_VERTEX_ARRAY: {
|
||||||
|
return vertex_array;
|
||||||
|
}
|
||||||
|
case GL_COLOR_ARRAY: {
|
||||||
|
return color_array;
|
||||||
|
}
|
||||||
|
case GL_TEXTURE_COORD_ARRAY: {
|
||||||
|
return tex_coord_array;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
ERR("Unsupported Array Function");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
#define CALL_GL_POINTER(unique_id, name) \
|
void enable_disable_array(const GLenum array, const bool value) {
|
||||||
CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) \
|
get_array_state(array).enabled = value;
|
||||||
trampoline(size, type, stride, uint32_t(pointer)); \
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define CALL_GL_POINTER(unique_id, name) \
|
void send_array_to_driver(GLenum array) {
|
||||||
CALL(unique_id, name, unused, unused) \
|
gl_array_state_t state = get_array_state(array);
|
||||||
GLint size = args.next<GLint>(); \
|
if (state.enabled) {
|
||||||
GLenum type = args.next<GLenum>(); \
|
glEnableClientState(array);
|
||||||
GLsizei stride = args.next<GLsizei>(); \
|
} else {
|
||||||
const void *pointer = (const void *) (uint64_t) args.next<uint32_t>(); \
|
glDisableClientState(array);
|
||||||
func(size, type, stride, pointer); \
|
}
|
||||||
return 0; \
|
typeof(glVertexPointer) *func = get_array_pointer_function(array);
|
||||||
|
func(state.size, state.type, state.stride, (const void *) uintptr_t(state.pointer));
|
||||||
|
}
|
||||||
|
void send_arrays_to_driver() {
|
||||||
|
send_array_to_driver(GL_VERTEX_ARRAY);
|
||||||
|
send_array_to_driver(GL_COLOR_ARRAY);
|
||||||
|
send_array_to_driver(GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
};
|
||||||
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
|
static gl_state_t gl_state;
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL_GL_POINTER(12, glVertexPointer)
|
// 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer
|
||||||
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
|
#define CALL_GL_POINTER(name, array) \
|
||||||
|
void name(GLint size, GLenum type, GLsizei stride, const void *pointer) { \
|
||||||
|
gl_array_state_t &state = gl_state.get_array_state(array); \
|
||||||
|
state.size = size; \
|
||||||
|
state.type = type; \
|
||||||
|
state.stride = stride; \
|
||||||
|
state.pointer = uint32_t(pointer); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define CALL_GL_POINTER(name, array)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CALL_GL_POINTER(glVertexPointer, GL_VERTEX_ARRAY)
|
||||||
|
|
||||||
CALL(13, glLineWidth, void, (GLfloat width))
|
CALL(13, glLineWidth, void, (GLfloat width))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
@ -63,8 +138,12 @@ CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
|
|||||||
|
|
||||||
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
|
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(mode, first, count);
|
trampoline(gl_state, mode, first, count);
|
||||||
#else
|
#else
|
||||||
|
gl_state_t gl_state = args.next<gl_state_t>();
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, gl_state.bound_array_buffer);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gl_state.bound_texture);
|
||||||
|
gl_state.send_arrays_to_driver();
|
||||||
GLenum mode = args.next<GLenum>();
|
GLenum mode = args.next<GLenum>();
|
||||||
GLint first = args.next<GLint>();
|
GLint first = args.next<GLint>();
|
||||||
GLsizei count = args.next<GLsizei>();
|
GLsizei count = args.next<GLsizei>();
|
||||||
@ -97,8 +176,9 @@ CALL(17, glClear, void, (GLbitfield mask))
|
|||||||
|
|
||||||
CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage))
|
CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, copy_array(size, (unsigned char *) data), usage);
|
trampoline(gl_state.bound_array_buffer, target, copy_array(size, (unsigned char *) data), usage);
|
||||||
#else
|
#else
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, args.next<GLuint>());
|
||||||
GLenum target = args.next<GLenum>();
|
GLenum target = args.next<GLenum>();
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
const unsigned char *data = args.next_arr<unsigned char>(&size);
|
const unsigned char *data = args.next_arr<unsigned char>(&size);
|
||||||
@ -139,7 +219,7 @@ CALL(21, glMatrixMode, void, (GLenum mode))
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL_GL_POINTER(22, glColorPointer)
|
CALL_GL_POINTER(glColorPointer, GL_COLOR_ARRAY)
|
||||||
|
|
||||||
CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
@ -156,8 +236,9 @@ CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
|||||||
|
|
||||||
CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param))
|
CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, pname, param);
|
trampoline(gl_state.bound_texture, target, pname, param);
|
||||||
#else
|
#else
|
||||||
|
glBindTexture(GL_TEXTURE_2D, args.next<GLuint>());
|
||||||
GLenum target = args.next<GLenum>();
|
GLenum target = args.next<GLenum>();
|
||||||
GLenum pname = args.next<GLenum>();
|
GLenum pname = args.next<GLenum>();
|
||||||
GLint param = args.next<GLint>();
|
GLint param = args.next<GLint>();
|
||||||
@ -204,8 +285,9 @@ static int get_texture_size(const GLsizei width, const GLsizei height, const GLe
|
|||||||
|
|
||||||
CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels))
|
CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, level, internalformat, width, height, border, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels));
|
trampoline(gl_state.bound_texture, target, level, internalformat, width, height, border, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels));
|
||||||
#else
|
#else
|
||||||
|
glBindTexture(GL_TEXTURE_2D, args.next<GLuint>());
|
||||||
GLenum target = args.next<GLenum>();
|
GLenum target = args.next<GLenum>();
|
||||||
GLint level = args.next<GLint>();
|
GLint level = args.next<GLint>();
|
||||||
GLint internalformat = args.next<GLint>();
|
GLint internalformat = args.next<GLint>();
|
||||||
@ -229,14 +311,11 @@ CALL(26, glEnable, void, (GLenum cap))
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL(27, glEnableClientState, void, (GLenum array))
|
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(array);
|
void glEnableClientState(const GLenum array) {
|
||||||
#else
|
gl_state.enable_disable_array(array, true);
|
||||||
func(args.next<GLenum>());
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
|
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
@ -249,16 +328,13 @@ CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL_GL_POINTER(41, glTexCoordPointer)
|
CALL_GL_POINTER(glTexCoordPointer, GL_TEXTURE_COORD_ARRAY)
|
||||||
|
|
||||||
CALL(29, glDisableClientState, void, (GLenum array))
|
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(array);
|
void glDisableClientState(const GLenum array) {
|
||||||
#else
|
gl_state.enable_disable_array(array, false);
|
||||||
func(args.next<GLenum>());
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far))
|
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
@ -280,16 +356,15 @@ CALL(31, glDepthFunc, void, (GLenum func))
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer))
|
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, buffer);
|
void glBindBuffer(const GLenum target, const GLuint buffer) {
|
||||||
#else
|
if (target == GL_ARRAY_BUFFER) {
|
||||||
GLenum target = args.next<GLenum>();
|
gl_state.bound_array_buffer = buffer;
|
||||||
GLenum buffer = args.next<GLenum>();
|
} else {
|
||||||
func(target, buffer);
|
ERR("Unsupported Buffer Binding: %u", target);
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha))
|
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
@ -403,8 +478,9 @@ CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLb
|
|||||||
|
|
||||||
CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels))
|
CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, level, xoffset, yoffset, width, height, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels));
|
trampoline(gl_state.bound_texture, target, level, xoffset, yoffset, width, height, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels));
|
||||||
#else
|
#else
|
||||||
|
glBindTexture(GL_TEXTURE_2D, args.next<GLuint>());
|
||||||
GLenum target = args.next<GLenum>();
|
GLenum target = args.next<GLenum>();
|
||||||
GLint level = args.next<GLint>();
|
GLint level = args.next<GLint>();
|
||||||
GLint xoffset = args.next<GLint>();
|
GLint xoffset = args.next<GLint>();
|
||||||
@ -485,16 +561,15 @@ CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params))
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL(49, glBindTexture, void, (GLenum target, GLuint texture))
|
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, texture);
|
void glBindTexture(const GLenum target, const GLuint texture) {
|
||||||
#else
|
if (target == GL_TEXTURE_2D) {
|
||||||
GLenum target = args.next<GLenum>();
|
gl_state.bound_texture = texture;
|
||||||
GLuint texture = args.next<GLuint>();
|
} else {
|
||||||
func(target, texture);
|
ERR("Unsupported Texture Binding: %u", target);
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
|
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include "guest.h"
|
#include "guest.h"
|
||||||
|
|
||||||
@ -16,8 +17,7 @@ static uint32_t trampoline_syscall(const uint32_t id, const uint32_t length, con
|
|||||||
return *(uint32_t *) args;
|
return *(uint32_t *) args;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pipe Method
|
// Pipe Method (Native Trampoline Only)
|
||||||
#ifdef MCPI_USE_NATIVE_TRAMPOLINE
|
|
||||||
static int get_pipe(const char *env) {
|
static int get_pipe(const char *env) {
|
||||||
const char *value = getenv(env);
|
const char *value = getenv(env);
|
||||||
if (value == nullptr) {
|
if (value == nullptr) {
|
||||||
@ -26,7 +26,7 @@ static int get_pipe(const char *env) {
|
|||||||
std::string str = value;
|
std::string str = value;
|
||||||
return std::stoi(str);
|
return std::stoi(str);
|
||||||
}
|
}
|
||||||
static uint32_t trampoline_pipe(const uint32_t id, const uint32_t length, const unsigned char *args) {
|
static uint32_t trampoline_pipe(const uint32_t id) {
|
||||||
// Get Pipes
|
// Get Pipes
|
||||||
static int arguments_pipe = -1;
|
static int arguments_pipe = -1;
|
||||||
static int return_value_pipe = -1;
|
static int return_value_pipe = -1;
|
||||||
@ -34,13 +34,8 @@ static uint32_t trampoline_pipe(const uint32_t id, const uint32_t length, const
|
|||||||
arguments_pipe = get_pipe(TRAMPOLINE_ARGUMENTS_PIPE_ENV);
|
arguments_pipe = get_pipe(TRAMPOLINE_ARGUMENTS_PIPE_ENV);
|
||||||
return_value_pipe = get_pipe(TRAMPOLINE_RETURN_VALUE_PIPE_ENV);
|
return_value_pipe = get_pipe(TRAMPOLINE_RETURN_VALUE_PIPE_ENV);
|
||||||
}
|
}
|
||||||
// Write Arguments
|
// Write ID
|
||||||
trampoline_pipe_arguments data = {
|
if (write(arguments_pipe, &id, sizeof(uint32_t)) != sizeof(uint32_t)) {
|
||||||
.id = id,
|
|
||||||
.length = length,
|
|
||||||
.args_addr = uint32_t(args)
|
|
||||||
};
|
|
||||||
if (write(arguments_pipe, &data, sizeof(trampoline_pipe_arguments)) != sizeof(trampoline_pipe_arguments)) {
|
|
||||||
ERR("Unable To Write Trampoline Command");
|
ERR("Unable To Write Trampoline Command");
|
||||||
}
|
}
|
||||||
// Return
|
// Return
|
||||||
@ -50,29 +45,42 @@ static uint32_t trampoline_pipe(const uint32_t id, const uint32_t length, const
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static uint32_t trampoline_pipe(__attribute__((unused)) const uint32_t id, __attribute__((unused)) const uint32_t length, __attribute__((unused)) const unsigned char *args) {
|
|
||||||
IMPOSSIBLE();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Main Function
|
// Main Function
|
||||||
uint32_t _raw_trampoline(const uint32_t id, const uint32_t length, const unsigned char *args) {
|
uint32_t _raw_trampoline(const uint32_t id, const uint32_t length, const unsigned char *args) {
|
||||||
// Configure Method
|
// Configure Method
|
||||||
static int use_syscall = -1;
|
static int use_syscall = -1;
|
||||||
if (use_syscall == -1) {
|
if (use_syscall == -1) {
|
||||||
use_syscall =
|
use_syscall = getenv(TRAMPOLINE_USE_PIPES_ENV) == nullptr;
|
||||||
#ifdef MCPI_USE_NATIVE_TRAMPOLINE
|
|
||||||
getenv(TRAMPOLINE_USE_PTRACE_ENV) != nullptr
|
|
||||||
#else
|
|
||||||
1
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
// Use Correct Method
|
// Use Correct Method
|
||||||
if (use_syscall) {
|
if (use_syscall) {
|
||||||
return trampoline_syscall(id, length, args);
|
return trampoline_syscall(id, length, args);
|
||||||
} else {
|
} else {
|
||||||
return trampoline_pipe(id, length, args);
|
return trampoline_pipe(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Arguments Memory
|
||||||
|
unsigned char *get_arguments_memory() {
|
||||||
|
static unsigned char fallback[MAX_TRAMPOLINE_ARGS_SIZE];
|
||||||
|
// Find Result
|
||||||
|
static unsigned char *ret = nullptr;
|
||||||
|
if (ret == nullptr) {
|
||||||
|
ret = fallback;
|
||||||
|
// Try Shared Memory
|
||||||
|
const char *shared_memory_name = getenv(TRAMPOLINE_SHARED_MEMORY_ENV);
|
||||||
|
if (shared_memory_name != nullptr) {
|
||||||
|
int fd = shm_open(shared_memory_name, O_RDWR, 0600);
|
||||||
|
if (fd == -1) {
|
||||||
|
ERR("Unable To Open Shared Memory: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
ret = (unsigned char *) mmap(nullptr, MAX_TRAMPOLINE_ARGS_SIZE, PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (ret == MAP_FAILED) {
|
||||||
|
ERR("Unable To Map Shared Memory: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return
|
||||||
|
return ret;
|
||||||
|
}
|
@ -5,11 +5,12 @@
|
|||||||
#include "../common/common.h"
|
#include "../common/common.h"
|
||||||
|
|
||||||
// Trampoline Function
|
// Trampoline Function
|
||||||
|
unsigned char *get_arguments_memory();
|
||||||
uint32_t _raw_trampoline(uint32_t id, uint32_t length, const unsigned char *args);
|
uint32_t _raw_trampoline(uint32_t id, uint32_t length, const unsigned char *args);
|
||||||
|
|
||||||
// Compile Trampoline Arguments
|
// Compile Trampoline Arguments
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void _handle_trampoline_arg(unsigned char *&out, const T arg) {
|
void _handle_trampoline_arg(unsigned char *&out, const T &arg) {
|
||||||
block_pointer(T);
|
block_pointer(T);
|
||||||
*(T *) out = arg;
|
*(T *) out = arg;
|
||||||
out += sizeof(T);
|
out += sizeof(T);
|
||||||
@ -33,7 +34,7 @@ struct copy_array {
|
|||||||
const void *data;
|
const void *data;
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
inline void _handle_trampoline_arg<copy_array>(unsigned char *&out, const copy_array arg) {
|
inline void _handle_trampoline_arg<copy_array>(unsigned char *&out, const copy_array &arg) {
|
||||||
*(uint32_t *) out = arg.size;
|
*(uint32_t *) out = arg.size;
|
||||||
out += sizeof(uint32_t);
|
out += sizeof(uint32_t);
|
||||||
if (arg.size > 0) {
|
if (arg.size > 0) {
|
||||||
@ -45,7 +46,7 @@ inline void _handle_trampoline_arg<copy_array>(unsigned char *&out, const copy_a
|
|||||||
__attribute__((unused)) static void _add_to_trampoline_args(__attribute__((unused)) unsigned char *&out) {
|
__attribute__((unused)) static void _add_to_trampoline_args(__attribute__((unused)) unsigned char *&out) {
|
||||||
}
|
}
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
void _add_to_trampoline_args(unsigned char *&out, T first, Args... args) {
|
void _add_to_trampoline_args(unsigned char *&out, const T &first, const Args... args) {
|
||||||
_handle_trampoline_arg(out, first);
|
_handle_trampoline_arg(out, first);
|
||||||
_add_to_trampoline_args(out, args...);
|
_add_to_trampoline_args(out, args...);
|
||||||
}
|
}
|
||||||
@ -53,7 +54,7 @@ void _add_to_trampoline_args(unsigned char *&out, T first, Args... args) {
|
|||||||
// Main Trampoline Function
|
// Main Trampoline Function
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
unsigned int _trampoline(unsigned int id, Args... args) {
|
unsigned int _trampoline(unsigned int id, Args... args) {
|
||||||
static unsigned char out[MAX_TRAMPOLINE_ARGS_SIZE];
|
static unsigned char *out = get_arguments_memory();
|
||||||
unsigned char *end = out;
|
unsigned char *end = out;
|
||||||
_add_to_trampoline_args(end, args...);
|
_add_to_trampoline_args(end, args...);
|
||||||
const uint32_t length = end - out;
|
const uint32_t length = end - out;
|
||||||
|
@ -87,7 +87,7 @@ CALL(8, media_swap_buffers, void, ())
|
|||||||
|
|
||||||
CALL(9, media_cleanup, void, ())
|
CALL(9, media_cleanup, void, ())
|
||||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline(false);
|
||||||
#else
|
#else
|
||||||
func();
|
func();
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user