diff --git a/meson.build b/meson.build index 01681df..fa4334e 100644 --- a/meson.build +++ b/meson.build @@ -12,6 +12,7 @@ executable(meson.project_name(), 'src/wren/configuration.cpp', 'src/wren/def_configuration.cpp', 'src/wren/dynafunc_maker.cpp', + 'src/dynafunc_amd64_gnu.S', dependencies: [wren_dep], install: true, ) diff --git a/src/dynafunc_amd64_gnu.asm b/src/dynafunc_amd64_gnu.S similarity index 76% rename from src/dynafunc_amd64_gnu.asm rename to src/dynafunc_amd64_gnu.S index 59ef322..8615028 100644 --- a/src/dynafunc_amd64_gnu.asm +++ b/src/dynafunc_amd64_gnu.S @@ -2,8 +2,12 @@ #objcopy -j .text -O binary dynafunc.o dynafunc.bin #xxd -i dynafunc.bin -dynafunc: +.global g_dynafunc +.global g_dynafunc_end + +g_dynafunc: movq $0xdeadbeefdeadbeef, %rdi movq $0xbadc0ffee0ddf00d, %rdx jmp *%rdx ret +g_dynafunc_end: diff --git a/src/wren/dynafunc_maker.cpp b/src/wren/dynafunc_maker.cpp index 9c7f0b0..5e8177a 100644 --- a/src/wren/dynafunc_maker.cpp +++ b/src/wren/dynafunc_maker.cpp @@ -14,13 +14,12 @@ namespace wren { namespace { -#if defined(__amd64__) and defined(__gnu_linux__) //see src/dynafunc_amd64_gnu.asm - const constexpr unsigned char g_dynafunc[] = { - 0x48, 0xbf, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0x48, 0xba, - 0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba, 0xff, 0xe2, 0xc3 - }; - const constexpr unsigned int g_dynafunc_len = 23; + extern "C" const char g_dynafunc[]; + 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}; @@ -43,9 +42,8 @@ namespace wren { std::copy(ptr, ptr + sizeof(T), subseq); } - void make_dynafunc_asm(unsigned char* out, unsigned int len, VM* ptr1, foreign_method_t ptr2) { - assert(g_dynafunc_len == len); - std::copy(g_dynafunc, g_dynafunc + g_dynafunc_len, out); + void make_dynafunc_asm(unsigned char* out, VM* ptr1, foreign_method_t ptr2) { + std::copy(g_dynafunc, g_dynafunc_end, out); replace_ptr(out, out + g_dynafunc_len, g_dynafunc_ptr1, ptr1); replace_ptr(out, out + g_dynafunc_len, g_dynafunc_ptr2, ptr2); @@ -69,7 +67,7 @@ namespace wren { void* DynafuncMaker::make (VM* vm, foreign_method_t cb) { unsigned char* const mem = allocate_chunk(); - make_dynafunc_asm(mem, g_dynafunc_len, vm, cb); + make_dynafunc_asm(mem, vm, cb); return mem; }