diff --git a/meson.build b/meson.build index fa4334e..cf953a4 100644 --- a/meson.build +++ b/meson.build @@ -6,13 +6,44 @@ project('wrentest', 'cpp', wren_dep = dependency('wren', version: '>=0.2.0', fallback: ['wren', 'wren_dep']) +os = host_machine.system() +if os == 'gnu' + os = 'hurd' +elif os == 'linux' + os = 'gnu' +endif + +arch = host_machine.cpu() +if arch == 'x86_64' + arch = 'amd64' +endif + +ptr_size = 0 +func_ptr_size = 0 + +conf = configuration_data() +if os == 'gnu' and arch == 'amd64' + ptr_size = 8 + func_ptr_size = 8 +endif + +conf.set('POINTER_SIZE', ptr_size) +conf.set('FUNC_POINTER_SIZE', func_ptr_size) + +project_config_file = configure_file( + input: 'src/config.h.in', + output: 'config.h', + configuration: conf +) + executable(meson.project_name(), + project_config_file, 'src/main.cpp', 'src/wren/vm.cpp', 'src/wren/configuration.cpp', 'src/wren/def_configuration.cpp', 'src/wren/dynafunc_maker.cpp', - 'src/dynafunc_amd64_gnu.S', + 'src/dynafunc_' + arch + '_' + os + '.S', dependencies: [wren_dep], install: true, ) diff --git a/src/config.h.in b/src/config.h.in new file mode 100644 index 0000000..7b18b7f --- /dev/null +++ b/src/config.h.in @@ -0,0 +1,10 @@ +#pragma once + +#define ASM_PTR_SIZE @POINTER_SIZE@ +#define ASM_FUNC_PTR_SIZE @FUNC_POINTER_SIZE@ + +#if defined(__cplusplus) +static_assert(sizeof(void*) == ASM_PTR_SIZE, "Build system reports an unexpected pointer size, please ensure assembly code is correct"); + +static_assert(sizeof(void(*)(int)) == ASM_FUNC_PTR_SIZE, "Build system reports an unexpected function pointer size, please ensure assembly code is correct"); +#endif diff --git a/src/wren/dynafunc_maker.cpp b/src/wren/dynafunc_maker.cpp index 5e8177a..c2e2b64 100644 --- a/src/wren/dynafunc_maker.cpp +++ b/src/wren/dynafunc_maker.cpp @@ -4,6 +4,7 @@ #endif #include "dynafunc_maker.hpp" +#include "config.h" #include #include #include //for sysconf() @@ -19,14 +20,12 @@ namespace wren { extern "C" const char g_dynafunc_end[]; const unsigned int g_dynafunc_len = g_dynafunc_end - g_dynafunc; -#if defined(__amd64__) and defined(__gnu_linux__) - const constexpr unsigned int g_dynafunc_ptr1_size = 8; - const constexpr unsigned int g_dynafunc_ptr2_size = 8; - const constexpr unsigned char g_dynafunc_ptr1[g_dynafunc_ptr1_size] = {0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde}; - const constexpr unsigned char g_dynafunc_ptr2[g_dynafunc_ptr2_size] = {0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba}; -#else -# error "Not implemented on this platform" -#endif + const constexpr unsigned int g_dynafunc_ptr1_size = ASM_PTR_SIZE; + const constexpr unsigned int g_dynafunc_ptr2_size = ASM_FUNC_PTR_SIZE; + const constexpr unsigned char g_dynafunc_ptr1[] = {0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde}; + const constexpr unsigned char g_dynafunc_ptr2[] = {0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba}; + static_assert(sizeof(g_dynafunc_ptr1) / sizeof(g_dynafunc_ptr1[0]) >= g_dynafunc_ptr1_size); + static_assert(sizeof(g_dynafunc_ptr2) / sizeof(g_dynafunc_ptr2[0]) >= g_dynafunc_ptr2_size); template void replace_ptr( @@ -35,8 +34,8 @@ namespace wren { const unsigned char (&search)[S], T replace ) { - static_assert(sizeof(T) == S, "Unexpected pointer size"); - const auto subseq = std::search(beg, end, search, search + S); + static_assert(sizeof(T) <= S, "Unexpected pointer size"); + const auto subseq = std::search(beg, end, search, search + sizeof(T)); assert(subseq != end); const auto ptr = reinterpret_cast(&replace); std::copy(ptr, ptr + sizeof(T), subseq);