From ac3c3f66d2004ef9b915f168cca02d15e1d8c360 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Thu, 21 Nov 2024 17:17:19 +0100 Subject: [PATCH 1/4] Initial commit, add base for NodeJS and constructor for MetaCall, still a lot of work to do. --- source/metacall/include/metacall/metacall.h | 6 +- source/metacall/source/metacall.c | 23 +++ source/portability/CMakeLists.txt | 5 +- .../include/portability/portability.h | 1 + ...ler_detection.h => portability_compiler.h} | 6 +- .../portability/portability_constructor.h | 79 ++++++++++ source/ports/node_port/CMakeLists.txt | 43 +++++- source/ports/node_port/index.js | 142 +++++++++++++----- 8 files changed, 253 insertions(+), 52 deletions(-) rename source/portability/include/portability/{portability_compiler_detection.h => portability_compiler.h} (99%) create mode 100644 source/portability/include/portability/portability_constructor.h diff --git a/source/metacall/include/metacall/metacall.h b/source/metacall/include/metacall/metacall.h index a1cea928fe..3e841fdcfa 100644 --- a/source/metacall/include/metacall/metacall.h +++ b/source/metacall/include/metacall/metacall.h @@ -58,10 +58,8 @@ struct metacall_initialize_configuration_type; struct metacall_initialize_configuration_type { - char *tag; - void *options; // TODO: We should use a MetaCall value MAP here and merge it with the configuration. - // By this way loaders will be able to access this information in the backend and we - // can use a weak API in order to implement this successfully + const char *tag; /* Tag referring to the loader */ + void *options; /* Value of type Map that will be merged merged into the configuration of the loader */ }; typedef void *(*metacall_await_callback)(void *, void *); diff --git a/source/metacall/source/metacall.c b/source/metacall/source/metacall.c index 45ce6bf0fb..45b949c708 100644 --- a/source/metacall/source/metacall.c +++ b/source/metacall/source/metacall.c @@ -35,6 +35,8 @@ #include +#include + #include #include @@ -68,6 +70,27 @@ static int metacall_plugin_extension_load(void); static void *metacallv_method(void *target, const char *name, method_invoke_ptr call, vector v, void *args[], size_t size); static type_id *metacall_type_ids(void *args[], size_t size); +/* -- Costructors -- */ + +portability_constructor(metacall_constructor) +{ + const char *metacall_host = environment_variable_get("METACALL_HOST", NULL); + + if (metacall_host != NULL) + { + struct metacall_initialize_configuration_type config[] = { + { metacall_host, NULL /* TODO: Initialize the map and define { host: true } */ }, + { NULL, NULL } + }; + + if (metacall_initialize_ex(config) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall host constructor failed to initialize"); + exit(1); + } + } +} + /* -- Methods -- */ const char *metacall_serial(void) diff --git a/source/portability/CMakeLists.txt b/source/portability/CMakeLists.txt index 17d2b2159b..2841f3aaa7 100644 --- a/source/portability/CMakeLists.txt +++ b/source/portability/CMakeLists.txt @@ -35,16 +35,17 @@ set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") set(headers ${include_path}/portability.h ${include_path}/portability_assert.h - ${include_path}/portability_path.h + ${include_path}/portability_constructor.h ${include_path}/portability_executable_path.h ${include_path}/portability_library_path.h + ${include_path}/portability_path.h ) set(sources ${source_path}/portability.c - ${source_path}/portability_path.c ${source_path}/portability_executable_path.c ${source_path}/portability_library_path.c + ${source_path}/portability_path.c ) # Group source files diff --git a/source/portability/include/portability/portability.h b/source/portability/include/portability/portability.h index 6316fda482..75af3411bb 100644 --- a/source/portability/include/portability/portability.h +++ b/source/portability/include/portability/portability.h @@ -27,6 +27,7 @@ #include #include +#include #include #ifdef __cplusplus diff --git a/source/portability/include/portability/portability_compiler_detection.h b/source/portability/include/portability/portability_compiler.h similarity index 99% rename from source/portability/include/portability/portability_compiler_detection.h rename to source/portability/include/portability/portability_compiler.h index ec2e4eaaa3..871adf1811 100644 --- a/source/portability/include/portability/portability_compiler_detection.h +++ b/source/portability/include/portability/portability_compiler.h @@ -18,8 +18,8 @@ * */ -#ifndef PORTABILITY_COMPILER_DETECTION_H -#define PORTABILITY_COMPILER_DETECTION_H 1 +#ifndef PORTABILITY_COMPILER_H +#define PORTABILITY_COMPILER_H 1 /* TODO: This needs to be implemented properly, including another file for architecture and operative system detection */ @@ -490,4 +490,4 @@ // PORTABILITY_THREAD_LOCAL not defined for this configuration. #endif -#endif /* PORTABILITY_COMPILER_DETECTION_H */ +#endif /* PORTABILITY_COMPILER_H */ diff --git a/source/portability/include/portability/portability_constructor.h b/source/portability/include/portability/portability_constructor.h new file mode 100644 index 0000000000..9dc72a8389 --- /dev/null +++ b/source/portability/include/portability/portability_constructor.h @@ -0,0 +1,79 @@ +/* + * Portability Library by Parra Studios + * A generic cross-platform portability utility. + * + * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef PORTABILITY_CONSTRUCTOR_H +#define PORTABILITY_CONSTRUCTOR_H 1 + +/* -- Headers -- */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* -- Headers -- */ + +#include + +#include +#include + +/* -- Macros -- */ + +#ifndef portability_constructor + + #ifdef __cplusplus + #define portability_constructor(ctor) \ + static void ctor(void); \ + static struct PREPROCESSOR_CONCAT(ctor, _type) \ + { \ + PREPROCESSOR_CONCAT(ctor, _type) \ + (void) \ + { \ + ctor(); \ + } \ + } PREPROCESSOR_CONCAT(ctor, _ctor); \ + static void ctor(void) + #elif defined(_MSC_VER) + /* TODO: Test MSVC version in release mode */ + #pragma section(".CRT$XCU", read) + #define portability_constructor_impl(ctor, prefix) \ + static void ctor(void); \ + __declspec(allocate(".CRT$XCU")) void (*PREPROCESSOR_CONCAT(ctor, _ptr))(void) = ctor; \ + __pragma(comment(linker, "/include:" prefix PREPROCESSOR_STRINGIFY(ctor) "_ptr")) static void ctor(void) + #ifdef _WIN64 + #define portability_constructor(ctor) portability_constructor_impl(ctor, "") + #else + #define portability_constructor(ctor) portability_constructor_impl(ctor, "_") + #endif + #else + #define portability_constructor(ctor) \ + static void ctor(void) __attribute__((constructor)); \ + static void ctor(void) + #endif + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABILITY_CONSTRUCTOR_H */ diff --git a/source/ports/node_port/CMakeLists.txt b/source/ports/node_port/CMakeLists.txt index 2402d2a7f6..9cbb94fbcd 100644 --- a/source/ports/node_port/CMakeLists.txt +++ b/source/ports/node_port/CMakeLists.txt @@ -93,12 +93,6 @@ if(NOT OPTION_BUILD_CLI OR NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_ return() endif() -set(node_port_test "${target}_test") - -# -# Define test -# - if(OPTION_BUILD_THREAD_SANITIZER AND OPTION_BUILD_LOADERS_CS) # TODO: This test fails when run with thread sanitizer: # @@ -121,6 +115,14 @@ if(OPTION_BUILD_THREAD_SANITIZER AND OPTION_BUILD_LOADERS_CS) return() endif() +# +# Define test +# + +set(node_port_test "${target}_test") + +message(STATUS "Test ${node_port_test}") + add_test(NAME ${target} COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$" -D "INPUT=${CMAKE_CURRENT_SOURCE_DIR}/test/commands/node_port.txt" -P "${CMAKE_SOURCE_DIR}/source/cli/metacallcli/test/commands/command_runner.cmake" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} @@ -213,3 +215,32 @@ test_environment_variables(${target} ${TESTS_ENVIRONMENT_VARIABLES_RS} ${TESTS_ENVIRONMENT_VARIABLES_OPENSSL} ) + +# +# Test importing NodeJS Port from node.exe +# + +set(node_port_test_exec "${node_port_test}_executable") + +message(STATUS "Test ${node_port_test_exec}") + +add_test(NAME ${node_port_test_exec} + COMMAND ${NodeJS_EXECUTABLE} test/index.js + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + +# Define test labels +set_property(TEST ${node_port_test_exec} + PROPERTY LABELS ${node_port_test_exec} +) + +# Environment variables +test_environment_variables(${node_port_test_exec} + "" + ${TESTS_ENVIRONMENT_VARIABLES} + ${TESTS_ENVIRONMENT_VARIABLES_COB} + ${TESTS_ENVIRONMENT_VARIABLES_C} + ${TESTS_ENVIRONMENT_VARIABLES_RS} + ${TESTS_ENVIRONMENT_VARIABLES_OPENSSL} + "METACALL_INSTALL_PATH=${PROJECT_OUTPUT_DIR}" +) diff --git a/source/ports/node_port/index.js b/source/ports/node_port/index.js index 10fcbf24e2..0120fbf617 100644 --- a/source/ports/node_port/index.js +++ b/source/ports/node_port/index.js @@ -22,55 +22,123 @@ const mod = require('module'); const path = require('path'); +const fs = require('fs').promises; const { URL } = require('url'); /* TODO: RPC Loader */ -const addon = (() => { - try { - /* This forces metacall port to be run always by metacall cli */ - return process._linkedBinding('node_loader_port_module'); - } catch (e) { - console.error('MetaCall failed to load, probably you are importing this file from NodeJS directly.'); - console.error('You should use MetaCall CLI instead. Install it from: https://github.com/metacall/install'); - throw e; - - /* TODO: Until we find a better way to do this, we should disable it */ - /* - const write = (data, cb) => { - if (!process.stdout.write(data)) { - process.stdout.once('drain', cb); - } else { - process.nextTick(cb); +async function findFilesRecursively(dirPattern, filePattern, depthLimit = Infinity) { + const stack = [{ dir: dirPattern, depth: 0 }]; + const files = []; + const dirRegex = new RegExp(dirPattern); + const fileRegex = new RegExp(filePattern); + + while (stack.length > 0) { + const { dir, depth } = stack.pop(); + + try { + if (!dirRegex.test(dir)) { + continue; } - }; - // Notify synchronously that we are launching MetaCall - write('NodeJS detected, launching MetaCall...\n', () => { - try { - const { spawnSync } = require('child_process'); - const args = [...process.argv]; + if (depth > depthLimit) { + continue; + } - args.shift(); + const items = await fs.readdir(dir); - const result = spawnSync('metacall', args, {}); + for (const item of items) { + const fullPath = path.join(dir, item); + const stat = await fs.stat(fullPath); - if (result.error && result.error.code === 'ENOENT') { - write('MetaCall not found. Please install MetaCall from: https://github.com/metacall/install and run it again.\n', () => { - process.exit(1); - }); + if (stat.isDirectory()) { + stack.push({ dir: fullPath, depth: depth + 1 }); + } else if (stat.isFile() && fileRegex.test(item)) { + files.push(fullPath); } + } + } catch (err) { + console.error(`Error reading directory ${dir}:`, err); + } + } - process.exit(result.status !== null ? result.status : 1); - } catch (e) { - const message = 'MetaCall failed to load, probably you are importing this file from NodeJS directly.\n' - + e.message + '\n' - + 'Install MetaCall from: https://github.com/metacall/install and run it again.\n'; + return files; +} - write(message, () => { - throw e; - }); +const platformInstallPaths = () => { + switch (process.platform) { + case 'win32': + return { + paths: [ path.join(process.env['LOCALAPPDATA'], 'MetaCall', 'metacall') ], + name: 'metacall.dll' } - }); + case 'darwin': + return { + paths: [ '/opt/homebrew/lib/', '/usr/local/lib/' ], + name: 'libmetacall.dylib' + } + case 'linux': + return { + paths: [ '/usr/local/lib/', '/gnu/lib/' ], + name: 'libmetacall.so' + } + } + + throw new Error(`Platform ${process.platform} not supported`) +} + +const searchPaths = () => { + const customPath = process.env['METACALL_INSTALL_PATH']; + + if (customPath) { + return { + paths: [ customPath ], + name: /^(lib)?metacall(d)?\.(so|dylib|dll)$/ + } + } + + return platformInstallPaths() +} + +const findLibrary = async () => { + const searchData = searchPaths(); + + for (const p of searchData.paths) { + const files = await findFilesRecursively(p, searchData.name, 0); + + if (files.length !== 0) { + return files[0]; + } + } + + throw new Error('MetaCall library not found, if you have it in a special folder, define it through METACALL_INSTALL_PATH') +} + +const addon = (() => { + try { + /* If the binding can be loaded, it means MetaCall is being + * imported from the node_loader, in that case the runtime + * was initialized by node_loader itself and we can proceed. + */ + return process._linkedBinding('node_loader_port_module'); + } catch (e) { + /* If the port cannot be found, it means MetaCall port has + * been imported for the first time from node.exe, the + * runtime in this case has been initialized by node.exe, + * and MetaCall is not initialized */ + process.env['METACALL_HOST'] = 'node'; + + findLibrary().then(library => { + const { constants } = require('os'); + const m = { exports: {} }; + + process.dlopen(m, library, constants.dlopen.RTLD_GLOBAL | constants.dlopen.RTLD_NOW); + + // TODO: What to do with m? should we use process._linkedBinding instead, no? + + }).catch(err => { + console.log(err); + process.exit(1); + }); } })(); From 3ed5d236280fd983782615866234231958d3f229 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Thu, 21 Nov 2024 23:32:02 +0100 Subject: [PATCH 2/4] Implemented cwd and options map. --- source/loader/source/loader_impl.c | 7 +- source/loader/source/loader_manager_impl.c | 12 ++- source/metacall/source/metacall.c | 19 ++++- source/portability/CMakeLists.txt | 2 + .../portability/portability_working_path.h | 54 ++++++++++++++ .../source/portability_working_path.c | 74 +++++++++++++++++++ 6 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 source/portability/include/portability/portability_working_path.h create mode 100644 source/portability/source/portability_working_path.c diff --git a/source/loader/source/loader_impl.c b/source/loader/source/loader_impl.c index c6ccf3297a..6b7bbafe34 100644 --- a/source/loader/source/loader_impl.c +++ b/source/loader/source/loader_impl.c @@ -87,7 +87,7 @@ struct loader_impl_type loader_impl_data data; /* Derived metadata provided by the loader, usually contains the data of the VM, Interpreter or JIT */ context ctx; /* Contains the objects, classes and functions loaded in the global scope of each loader */ set type_info_map; /* Stores a set indexed by type name of all of the types existing in the loader (global scope (TODO: may need refactor per handle)) */ - void *options; /* Additional initialization options passed in the initialize phase */ + value options; /* Additional initialization options passed in the initialize phase */ set exec_path_map; /* Set of execution paths passed by the end user */ }; @@ -1539,6 +1539,11 @@ void loader_impl_destroy_deallocate(loader_impl impl) context_destroy(impl->ctx); + if (impl->options != NULL) + { + value_type_destroy(impl->options); + } + free(impl); } diff --git a/source/loader/source/loader_manager_impl.c b/source/loader/source/loader_manager_impl.c index b22fa15273..f3f4375a63 100644 --- a/source/loader/source/loader_manager_impl.c +++ b/source/loader/source/loader_manager_impl.c @@ -26,8 +26,8 @@ #include -#include #include +#include #include @@ -52,8 +52,8 @@ static void *loader_manager_impl_is_destroyed_ptr = NULL; vector loader_manager_impl_script_paths_initialize(void) { - portability_executable_path_str exe_path_str = { 0 }; - portability_executable_path_length exe_path_str_length = 0; + portability_working_path_str cwd_path_str = { 0 }; + portability_working_path_length cwd_path_str_length = 0; char *script_path = NULL; size_t script_path_size = 0; vector script_paths = vector_create_type(char *); @@ -63,11 +63,9 @@ vector loader_manager_impl_script_paths_initialize(void) return NULL; } - if (portability_executable_path(exe_path_str, &exe_path_str_length) == 0) + if (portability_working_path(cwd_path_str, &cwd_path_str_length) == 0) { - size_t exe_directory_size = portability_path_get_directory_inplace(exe_path_str, exe_path_str_length + 1); - - script_path = environment_variable_path_create(LOADER_SCRIPT_PATH, exe_path_str, exe_directory_size, &script_path_size); + script_path = environment_variable_path_create(LOADER_SCRIPT_PATH, cwd_path_str, cwd_path_str_length + 1, &script_path_size); } else { diff --git a/source/metacall/source/metacall.c b/source/metacall/source/metacall.c index 45b949c708..171c18482d 100644 --- a/source/metacall/source/metacall.c +++ b/source/metacall/source/metacall.c @@ -76,16 +76,33 @@ portability_constructor(metacall_constructor) { const char *metacall_host = environment_variable_get("METACALL_HOST", NULL); + /* We are running from a different host, initialize the loader of the host + * and redirect it to the existing symbols, also avoiding initialization + * and destruction of the runtime as it is being managed externally to MetaCall */ if (metacall_host != NULL) { + static const char host_str[] = "host"; + struct metacall_initialize_configuration_type config[] = { - { metacall_host, NULL /* TODO: Initialize the map and define { host: true } */ }, + { metacall_host, metacall_value_create_map(NULL, 1) }, { NULL, NULL } }; + /* Initialize the loader options with a map defining its options to { "host": true } */ + void **host_tuple, **options_map = metacall_value_to_map(config[0].options); + + options_map[0] = metacall_value_create_array(NULL, 2); + + host_tuple = metacall_value_to_array(options_map[0]); + + host_tuple[0] = metacall_value_create_string(host_str, sizeof(host_str) - 1); + host_tuple[1] = metacall_value_create_bool(1); + + /* Initialize MetaCall with extra options, defining the host properly */ if (metacall_initialize_ex(config) != 0) { log_write("metacall", LOG_LEVEL_ERROR, "MetaCall host constructor failed to initialize"); + metacall_value_destroy(config[0].options); exit(1); } } diff --git a/source/portability/CMakeLists.txt b/source/portability/CMakeLists.txt index 2841f3aaa7..cf4af64c62 100644 --- a/source/portability/CMakeLists.txt +++ b/source/portability/CMakeLists.txt @@ -38,6 +38,7 @@ set(headers ${include_path}/portability_constructor.h ${include_path}/portability_executable_path.h ${include_path}/portability_library_path.h + ${include_path}/portability_working_path.h ${include_path}/portability_path.h ) @@ -45,6 +46,7 @@ set(sources ${source_path}/portability.c ${source_path}/portability_executable_path.c ${source_path}/portability_library_path.c + ${source_path}/portability_working_path.c ${source_path}/portability_path.c ) diff --git a/source/portability/include/portability/portability_working_path.h b/source/portability/include/portability/portability_working_path.h new file mode 100644 index 0000000000..00866a3a90 --- /dev/null +++ b/source/portability/include/portability/portability_working_path.h @@ -0,0 +1,54 @@ +/* + * Portability Library by Parra Studios + * A generic cross-platform portability utility. + * + * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef PORTABILITY_WORKING_PATH_H +#define PORTABILITY_WORKING_PATH_H 1 + +/* -- Headers -- */ + +#include + +#include + +/* -- Type Definitions -- */ + +typedef char portability_working_path_str[PORTABILITY_PATH_SIZE]; + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) +typedef DWORD portability_working_path_length; +#else +typedef size_t portability_working_path_length; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* -- Methods -- */ + +PORTABILITY_API int portability_working_path(portability_working_path_str path, portability_working_path_length *length); + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABILITY_WORKING_PATH_H */ diff --git a/source/portability/source/portability_working_path.c b/source/portability/source/portability_working_path.c new file mode 100644 index 0000000000..1511cef35c --- /dev/null +++ b/source/portability/source/portability_working_path.c @@ -0,0 +1,74 @@ +/* + * Portability Library by Parra Studios + * A generic cross-platform portability utility. + * + * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) + #include +#else + #include +#endif + +int portability_working_path(portability_working_path_str path, portability_working_path_length *length) +{ + const portability_working_path_length path_max_length = PORTABILITY_PATH_SIZE; + + /* Reset the path */ + memset(path, 0, path_max_length); + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) + *length = GetCurrentDirectory(0, NULL); + + if (*length == 0) + { + /* TODO: DWORD dw = GetLastError(); */ + return 1; + } + + if (*length > path_max_length) + { + /* TODO: Handle error */ + return 1; + } + + if (GetCurrentDirectory(*length, path) == 0) + { + /* TODO: DWORD dw = GetLastError(); */ + return 1; + } +#else + if (getcwd(path, path_max_length) == NULL) + { + *length = 0; + /* TODO: Handle error */ + return 1; + } + + *length = strnlen(path, path_max_length); +#endif + + return 0; +} From 8e8fe8b46545a286f452cb0062db7db1aaeb3502 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Fri, 22 Nov 2024 13:25:37 +0100 Subject: [PATCH 3/4] Add functions for detecting host from loader side. --- source/loader/include/loader/loader.h | 10 +-- source/loader/include/loader/loader_impl.h | 6 +- source/loader/source/loader.c | 16 ++++- source/loader/source/loader_impl.c | 37 ++++++++++- source/loaders/node_loader/CMakeLists.txt | 4 +- .../node_loader/source/node_loader_impl.cpp | 39 ++++++------ .../node_loader/source/node_loader_port.cpp | 11 ---- source/metacall/source/metacall.c | 63 ++++++++++--------- 8 files changed, 118 insertions(+), 68 deletions(-) diff --git a/source/loader/include/loader/loader.h b/source/loader/include/loader/loader.h index b7fec73ec5..3c31ba98d4 100644 --- a/source/loader/include/loader/loader.h +++ b/source/loader/include/loader/loader.h @@ -33,10 +33,6 @@ extern "C" { #endif -/* -- Headers -- */ - -#include - /* -- Forward Declarations -- */ struct loader_type; @@ -81,7 +77,11 @@ LOADER_API void *loader_get_handle(const loader_tag tag, const char *name); LOADER_API void loader_set_options(const loader_tag tag, void *options); -LOADER_API void *loader_get_options(const loader_tag tag); +LOADER_API value loader_get_options(const loader_tag tag); + +LOADER_API value loader_get_option(const loader_tag tag, const char *field); + +LOADER_API int loader_get_option_host(const loader_tag tag); LOADER_API int loader_handle_initialize(loader_impl impl, const loader_path name, void **handle_ptr); diff --git a/source/loader/include/loader/loader_impl.h b/source/loader/include/loader/loader_impl.h index c6c8826d6d..8eea205e23 100644 --- a/source/loader/include/loader/loader_impl.h +++ b/source/loader/include/loader/loader_impl.h @@ -67,7 +67,11 @@ LOADER_API void *loader_impl_get_handle(loader_impl impl, const char *name); LOADER_API void loader_impl_set_options(loader_impl impl, void *options); -LOADER_API void *loader_impl_get_options(loader_impl impl); +LOADER_API value loader_impl_get_options(loader_impl impl); + +LOADER_API value loader_impl_get_option(loader_impl impl, const char *field); + +LOADER_API int loader_impl_get_option_host(loader_impl impl); LOADER_API int loader_impl_handle_initialize(plugin_manager manager, plugin p, loader_impl impl, const loader_path name, void **handle_ptr); diff --git a/source/loader/source/loader.c b/source/loader/source/loader.c index 82bb7d5a4f..13b1364458 100644 --- a/source/loader/source/loader.c +++ b/source/loader/source/loader.c @@ -547,13 +547,27 @@ void loader_set_options(const loader_tag tag, void *options) loader_impl_set_options(plugin_impl_type(p, loader_impl), options); } -void *loader_get_options(const loader_tag tag) +value loader_get_options(const loader_tag tag) { plugin p = loader_get_impl_plugin(tag); return loader_impl_get_options(plugin_impl_type(p, loader_impl)); } +value loader_get_option(const loader_tag tag, const char *field) +{ + plugin p = loader_get_impl_plugin(tag); + + return loader_impl_get_option(plugin_impl_type(p, loader_impl), field); +} + +int loader_get_option_host(const loader_tag tag) +{ + plugin p = loader_get_impl_plugin(tag); + + return loader_impl_get_option_host(plugin_impl_type(p, loader_impl)); +} + int loader_handle_initialize(loader_impl impl, const loader_path name, void **handle_ptr) { if (loader_initialize() == 1) diff --git a/source/loader/source/loader_impl.c b/source/loader/source/loader_impl.c index 6b7bbafe34..80c58db320 100644 --- a/source/loader/source/loader_impl.c +++ b/source/loader/source/loader_impl.c @@ -1158,7 +1158,7 @@ void loader_impl_set_options(loader_impl impl, void *options) } } -void *loader_impl_get_options(loader_impl impl) +value loader_impl_get_options(loader_impl impl) { if (impl != NULL) { @@ -1168,6 +1168,41 @@ void *loader_impl_get_options(loader_impl impl) return NULL; } +value loader_impl_get_option(loader_impl impl, const char *field) +{ + value *options_map = value_to_map(impl->options); + size_t i, size = value_type_count(impl->options); + + for (i = 0; i < size; ++i) + { + value *options_tuple = value_to_array(options_map[i]); + + if (value_type_id(options_tuple[0]) == TYPE_STRING) + { + const char *str = value_to_string(options_tuple[0]); + + if (strncmp(str, field, value_type_size(options_tuple[0])) == 0) + { + return options_tuple[1]; + } + } + } + + return NULL; +} + +int loader_impl_get_option_host(loader_impl impl) +{ + value host = loader_impl_get_option(impl, "host"); + + if (host != NULL && value_type_id(host) == TYPE_BOOL) + { + return value_to_bool(host); + } + + return 0; +} + int loader_impl_handle_initialize(plugin_manager manager, plugin p, loader_impl impl, const loader_path name, void **handle_ptr) { if (impl != NULL) diff --git a/source/loaders/node_loader/CMakeLists.txt b/source/loaders/node_loader/CMakeLists.txt index 814f411f71..70108f53e2 100644 --- a/source/loaders/node_loader/CMakeLists.txt +++ b/source/loaders/node_loader/CMakeLists.txt @@ -156,7 +156,9 @@ target_include_directories(${target} target_link_libraries(${target} PRIVATE ${META_PROJECT_NAME}::metacall # MetaCall library - ${NodeJS_LIBRARY} # NodeJS library + + # TODO: Implement delayed load + # ${NodeJS_LIBRARY} # NodeJS library PUBLIC ${DEFAULT_LIBRARIES} diff --git a/source/loaders/node_loader/source/node_loader_impl.cpp b/source/loaders/node_loader/source/node_loader_impl.cpp index bfe6e90c47..af983d29d9 100644 --- a/source/loaders/node_loader/source/node_loader_impl.cpp +++ b/source/loaders/node_loader/source/node_loader_impl.cpp @@ -3937,34 +3937,37 @@ loader_impl_data node_loader_impl_initialize(loader_impl impl, configuration con config }; - /* Create NodeJS thread */ - if (uv_thread_create(&node_impl->thread, node_loader_impl_thread, &thread_data) != 0) + if (loader_impl_get_option_host(impl) == 0) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid NodeJS Thread creation"); + /* Create NodeJS thread */ + if (uv_thread_create(&node_impl->thread, node_loader_impl_thread, &thread_data) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid NodeJS Thread creation"); - /* TODO: Clear resources */ + /* TODO: Clear resources */ - delete node_impl; + delete node_impl; - return NULL; - } + return NULL; + } - /* Wait until start has been launch */ - uv_mutex_lock(&node_impl->mutex); + /* Wait until start has been launch */ + uv_mutex_lock(&node_impl->mutex); - uv_cond_wait(&node_impl->cond, &node_impl->mutex); + uv_cond_wait(&node_impl->cond, &node_impl->mutex); - if (node_impl->error_message != NULL) - { - uv_mutex_unlock(&node_impl->mutex); + if (node_impl->error_message != NULL) + { + uv_mutex_unlock(&node_impl->mutex); - /* TODO: Remove this when implementing thread safe */ - log_write("metacall", LOG_LEVEL_ERROR, node_impl->error_message); + /* TODO: Remove this when implementing thread safe */ + log_write("metacall", LOG_LEVEL_ERROR, node_impl->error_message); - return NULL; - } + return NULL; + } - uv_mutex_unlock(&node_impl->mutex); + uv_mutex_unlock(&node_impl->mutex); + } /* Call initialize function with thread safe */ { diff --git a/source/loaders/node_loader/source/node_loader_port.cpp b/source/loaders/node_loader/source/node_loader_port.cpp index ed681f1e91..8261f6bce9 100644 --- a/source/loaders/node_loader/source/node_loader_port.cpp +++ b/source/loaders/node_loader/source/node_loader_port.cpp @@ -836,17 +836,6 @@ void node_loader_port_exports(napi_env env, napi_value exports) /* This function is called by NodeJs when the module is required */ napi_value node_loader_port_initialize(napi_env env, napi_value exports) { -/* Note: This should not be necessary because we do not allow to use ports outside MetaCall */ -#if 0 - if (metacall_initialize() != 0) - { - /* TODO: Show error message (when error handling is properly implemented in the core lib) */ - napi_throw_error(env, nullptr, "MetaCall failed to initialize"); - - return nullptr; - } -#endif - node_loader_port_exports(env, exports); return exports; diff --git a/source/metacall/source/metacall.c b/source/metacall/source/metacall.c index 171c18482d..8a9ad2eb9c 100644 --- a/source/metacall/source/metacall.c +++ b/source/metacall/source/metacall.c @@ -74,36 +74,39 @@ static type_id *metacall_type_ids(void *args[], size_t size); portability_constructor(metacall_constructor) { - const char *metacall_host = environment_variable_get("METACALL_HOST", NULL); - - /* We are running from a different host, initialize the loader of the host - * and redirect it to the existing symbols, also avoiding initialization - * and destruction of the runtime as it is being managed externally to MetaCall */ - if (metacall_host != NULL) + if (metacall_initialize_flag == 1) { - static const char host_str[] = "host"; + const char *metacall_host = environment_variable_get("METACALL_HOST", NULL); - struct metacall_initialize_configuration_type config[] = { - { metacall_host, metacall_value_create_map(NULL, 1) }, - { NULL, NULL } - }; + /* We are running from a different host, initialize the loader of the host + * and redirect it to the existing symbols, also avoiding initialization + * and destruction of the runtime as it is being managed externally to MetaCall */ + if (metacall_host != NULL) + { + static const char host_str[] = "host"; - /* Initialize the loader options with a map defining its options to { "host": true } */ - void **host_tuple, **options_map = metacall_value_to_map(config[0].options); + struct metacall_initialize_configuration_type config[] = { + { metacall_host, metacall_value_create_map(NULL, 1) }, + { NULL, NULL } + }; - options_map[0] = metacall_value_create_array(NULL, 2); + /* Initialize the loader options with a map defining its options to { "host": true } */ + void **host_tuple, **options_map = metacall_value_to_map(config[0].options); - host_tuple = metacall_value_to_array(options_map[0]); + options_map[0] = metacall_value_create_array(NULL, 2); - host_tuple[0] = metacall_value_create_string(host_str, sizeof(host_str) - 1); - host_tuple[1] = metacall_value_create_bool(1); + host_tuple = metacall_value_to_array(options_map[0]); - /* Initialize MetaCall with extra options, defining the host properly */ - if (metacall_initialize_ex(config) != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall host constructor failed to initialize"); - metacall_value_destroy(config[0].options); - exit(1); + host_tuple[0] = metacall_value_create_string(host_str, sizeof(host_str) - 1); + host_tuple[1] = metacall_value_create_bool(1); + + /* Initialize MetaCall with extra options, defining the host properly */ + if (metacall_initialize_ex(config) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall host constructor failed to initialize"); + metacall_value_destroy(config[0].options); + exit(1); + } } } } @@ -179,6 +182,13 @@ int metacall_initialize(void) { memory_allocator allocator; + if (metacall_initialize_flag == 0) + { + log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall already initialized"); + + return 0; + } + /* Initialize logs by default to stdout if none has been defined */ if (metacall_log_null_flag != 0 && log_size() == 0) { @@ -194,13 +204,6 @@ int metacall_initialize(void) log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall default logger to stdout initialized"); } - if (metacall_initialize_flag == 0) - { - log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall already initialized"); - - return 0; - } - log_write("metacall", LOG_LEVEL_DEBUG, "Initializing MetaCall"); /* Initialize MetaCall version environment variable */ From 355c12f1f274ad381d7bdc67186852ada4a73039 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 27 Nov 2024 23:01:13 +0100 Subject: [PATCH 4/4] Improve dynlink, trying to hook dlsym. --- .../include/cli_core_plugin/cli_core_plugin.h | 4 -- .../cli_sandbox_plugin/cli_sandbox_plugin.h | 4 -- .../include/funchook_detour/funchook_detour.h | 6 -- source/dynlink/CMakeLists.txt | 3 - source/dynlink/include/dynlink/dynlink.h | 1 - source/dynlink/include/dynlink/dynlink_impl.h | 4 -- .../include/dynlink/dynlink_impl_beos.h | 2 - .../include/dynlink/dynlink_impl_macos.h | 2 - .../dynlink/dynlink_impl_symbol_beos.h | 62 ------------------ .../dynlink/dynlink_impl_symbol_macos.h | 62 ------------------ .../dynlink/dynlink_impl_symbol_unix.h | 62 ------------------ .../dynlink/dynlink_impl_symbol_win32.h | 58 ----------------- .../include/dynlink/dynlink_impl_unix.h | 2 - .../include/dynlink/dynlink_impl_win32.h | 2 - .../include/dynlink/dynlink_interface.h | 21 ------- .../dynlink/include/dynlink/dynlink_symbol.h | 63 ------------------- source/dynlink/include/dynlink/dynlink_type.h | 17 +++++ source/dynlink/source/dynlink_impl_beos.c | 2 +- source/dynlink/source/dynlink_impl_macos.c | 3 +- source/dynlink/source/dynlink_impl_unix.c | 2 +- source/dynlink/source/dynlink_impl_win32.c | 2 +- source/dynlink/source/dynlink_symbol.c | 51 --------------- .../plugin_extension/plugin_extension.h | 4 -- .../c_loader/include/c_loader/c_loader.h | 6 -- .../include/cob_loader/cob_loader.h | 6 -- .../cr_loader/include/cr_loader/cr_loader.h | 6 -- .../cs_loader/include/cs_loader/cs_loader.h | 6 -- .../include/dart_loader/dart_loader.h | 6 -- .../include/ext_loader/ext_loader.h | 6 -- .../ext_loader/source/ext_loader_impl.cpp | 4 +- .../include/file_loader/file_loader.h | 6 -- .../include/java_loader/java_loader.h | 6 -- .../jl_loader/include/jl_loader/jl_loader.h | 6 -- .../js_loader/include/js_loader/js_loader.h | 6 -- .../include/jsm_loader/jsm_loader.h | 6 -- .../include/llvm_loader/llvm_loader.h | 6 -- .../include/lua_loader/lua_loader.h | 6 -- .../include/mock_loader/mock_loader.h | 6 -- source/loaders/node_loader/CMakeLists.txt | 2 +- .../include/node_loader/node_loader.h | 6 -- .../node_loader/source/node_loader_impl.cpp | 52 ++++++++------- .../py_loader/include/py_loader/py_loader.h | 6 -- .../rb_loader/include/rb_loader/rb_loader.h | 6 -- .../include/rpc_loader/rpc_loader.h | 6 -- .../rs_loader/include/rs_loader/rs_loader.h | 6 -- .../ts_loader/include/ts_loader/ts_loader.h | 6 -- .../include/wasm_loader/wasm_loader.h | 6 -- source/metacall/source/metacall.c | 59 +++++++++++++++++ source/plugin/source/plugin_descriptor.c | 2 +- source/plugin/source/plugin_loader.c | 9 ++- .../backtrace_plugin/backtrace_plugin.h | 4 -- .../include/sandbox_plugin/sandbox_plugin.h | 4 -- .../sum/include/sum_extension/sum_extension.h | 4 -- .../include/metacall_serial/metacall_serial.h | 6 -- .../rapid_json_serial/rapid_json_serial.h | 6 -- .../dynlink_test/source/dynlink_test.cpp | 6 +- 56 files changed, 120 insertions(+), 603 deletions(-) delete mode 100644 source/dynlink/include/dynlink/dynlink_impl_symbol_beos.h delete mode 100644 source/dynlink/include/dynlink/dynlink_impl_symbol_macos.h delete mode 100644 source/dynlink/include/dynlink/dynlink_impl_symbol_unix.h delete mode 100644 source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h delete mode 100644 source/dynlink/include/dynlink/dynlink_symbol.h delete mode 100644 source/dynlink/source/dynlink_symbol.c diff --git a/source/cli/plugins/cli_core_plugin/include/cli_core_plugin/cli_core_plugin.h b/source/cli/plugins/cli_core_plugin/include/cli_core_plugin/cli_core_plugin.h index e27865d260..6c4446d9eb 100644 --- a/source/cli/plugins/cli_core_plugin/include/cli_core_plugin/cli_core_plugin.h +++ b/source/cli/plugins/cli_core_plugin/include/cli_core_plugin/cli_core_plugin.h @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif CLI_CORE_PLUGIN_API int cli_core_plugin(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(cli_core_plugin); - #ifdef __cplusplus } #endif diff --git a/source/cli/plugins/cli_sandbox_plugin/include/cli_sandbox_plugin/cli_sandbox_plugin.h b/source/cli/plugins/cli_sandbox_plugin/include/cli_sandbox_plugin/cli_sandbox_plugin.h index f0f1aa6711..a11ef6abc0 100644 --- a/source/cli/plugins/cli_sandbox_plugin/include/cli_sandbox_plugin/cli_sandbox_plugin.h +++ b/source/cli/plugins/cli_sandbox_plugin/include/cli_sandbox_plugin/cli_sandbox_plugin.h @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif CLI_SANDBOX_PLUGIN_API int cli_sandbox_plugin(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(cli_sandbox_plugin); - #ifdef __cplusplus } #endif diff --git a/source/detours/funchook_detour/include/funchook_detour/funchook_detour.h b/source/detours/funchook_detour/include/funchook_detour/funchook_detour.h index b1967f77df..551ace90b6 100644 --- a/source/detours/funchook_detour/include/funchook_detour/funchook_detour.h +++ b/source/detours/funchook_detour/include/funchook_detour/funchook_detour.h @@ -27,8 +27,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif @@ -45,8 +43,6 @@ extern "C" { */ FUNCHOOK_DETOUR_API detour_interface funchook_detour_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(funchook_detour_impl_interface_singleton); - /** * @brief * Provide the module information @@ -57,8 +53,6 @@ DYNLINK_SYMBOL_EXPORT(funchook_detour_impl_interface_singleton); */ FUNCHOOK_DETOUR_API const char *funchook_detour_print_info(void); -DYNLINK_SYMBOL_EXPORT(funchook_detour_print_info); - #ifdef __cplusplus } #endif diff --git a/source/dynlink/CMakeLists.txt b/source/dynlink/CMakeLists.txt index 0c1bd92942..dbb770bec9 100644 --- a/source/dynlink/CMakeLists.txt +++ b/source/dynlink/CMakeLists.txt @@ -47,9 +47,7 @@ set(headers ${include_path}/dynlink.h ${include_path}/dynlink_flags.h ${include_path}/dynlink_impl.h - ${include_path}/dynlink_impl_symbol_${DYNLINK_IMPL_INTERFACE_NAME}.h ${include_path}/dynlink_impl_${DYNLINK_IMPL_INTERFACE_NAME}.h - ${include_path}/dynlink_symbol.h ) set(sources @@ -57,7 +55,6 @@ set(sources ${source_path}/dynlink_impl.c ${source_path}/dynlink_impl_${DYNLINK_IMPL_INTERFACE_NAME}.c ${source_path}/dynlink_interface.c - ${source_path}/dynlink_symbol.c ) # Group source files diff --git a/source/dynlink/include/dynlink/dynlink.h b/source/dynlink/include/dynlink/dynlink.h index 2b42705a6c..77102c9e1b 100644 --- a/source/dynlink/include/dynlink/dynlink.h +++ b/source/dynlink/include/dynlink/dynlink.h @@ -29,7 +29,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/source/dynlink/include/dynlink/dynlink_impl.h b/source/dynlink/include/dynlink/dynlink_impl.h index 3185db4aac..8f09c51951 100644 --- a/source/dynlink/include/dynlink/dynlink_impl.h +++ b/source/dynlink/include/dynlink/dynlink_impl.h @@ -33,10 +33,6 @@ extern "C" { #endif -/* -- Headers -- */ - -#include - /* -- Methods -- */ /** diff --git a/source/dynlink/include/dynlink/dynlink_impl_beos.h b/source/dynlink/include/dynlink/dynlink_impl_beos.h index f77adbb3ee..60efcdc2a1 100644 --- a/source/dynlink/include/dynlink/dynlink_impl_beos.h +++ b/source/dynlink/include/dynlink/dynlink_impl_beos.h @@ -25,8 +25,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/source/dynlink/include/dynlink/dynlink_impl_macos.h b/source/dynlink/include/dynlink/dynlink_impl_macos.h index d2bce45dd4..404235e30c 100644 --- a/source/dynlink/include/dynlink/dynlink_impl_macos.h +++ b/source/dynlink/include/dynlink/dynlink_impl_macos.h @@ -25,8 +25,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/source/dynlink/include/dynlink/dynlink_impl_symbol_beos.h b/source/dynlink/include/dynlink/dynlink_impl_symbol_beos.h deleted file mode 100644 index 6530fd895b..0000000000 --- a/source/dynlink/include/dynlink/dynlink_impl_symbol_beos.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef DYNLINK_IMPL_SYMBOL_BEOS_H -#define DYNLINK_IMPL_SYMBOL_BEOS_H 1 - -/* -- Headers -- */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_PREFIX \ - dynlink_symbol_ - -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_EXPORT(name) \ - DYNLINK_API struct dynlink_symbol_addr_beos_type DYNLINK_SYMBOL_NAME(name) = { \ - (dynlink_symbol_addr_beos_impl)&name \ - } - -#define DYNLINK_SYMBOL_GET(name) \ - ((dynlink_symbol_addr_beos)(name))->symbol - -/* -- Type definitions -- */ - -typedef void (*dynlink_symbol_addr_beos_impl)(void); - -typedef struct dynlink_symbol_addr_beos_type -{ - dynlink_symbol_addr_beos_impl symbol; -} * dynlink_symbol_addr_beos; - -typedef dynlink_symbol_addr_beos dynlink_symbol_addr; - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_IMPL_SYMBOL_BEOS_H */ diff --git a/source/dynlink/include/dynlink/dynlink_impl_symbol_macos.h b/source/dynlink/include/dynlink/dynlink_impl_symbol_macos.h deleted file mode 100644 index 7d92286e65..0000000000 --- a/source/dynlink/include/dynlink/dynlink_impl_symbol_macos.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef DYNLINK_IMPL_SYMBOL_MACOS_H -#define DYNLINK_IMPL_SYMBOL_MACOS_H 1 - -/* -- Headers -- */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_PREFIX \ - dynlink_symbol_ - -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_EXPORT(name) \ - DYNLINK_API struct dynlink_symbol_addr_macos_type DYNLINK_SYMBOL_NAME(name) = { \ - (dynlink_symbol_addr_macos_impl)&name \ - } - -#define DYNLINK_SYMBOL_GET(name) \ - ((dynlink_symbol_addr_macos)(name))->symbol - -/* -- Type definitions -- */ - -typedef void (*dynlink_symbol_addr_macos_impl)(void); - -typedef struct dynlink_symbol_addr_macos_type -{ - dynlink_symbol_addr_macos_impl symbol; -} * dynlink_symbol_addr_macos; - -typedef dynlink_symbol_addr_macos dynlink_symbol_addr; - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_IMPL_SYMBOL_MACOS_H */ diff --git a/source/dynlink/include/dynlink/dynlink_impl_symbol_unix.h b/source/dynlink/include/dynlink/dynlink_impl_symbol_unix.h deleted file mode 100644 index 56a66a91b3..0000000000 --- a/source/dynlink/include/dynlink/dynlink_impl_symbol_unix.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef DYNLINK_IMPL_SYMBOL_UNIX_H -#define DYNLINK_IMPL_SYMBOL_UNIX_H 1 - -/* -- Headers -- */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_PREFIX \ - dynlink_symbol_ - -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_EXPORT(name) \ - DYNLINK_API struct dynlink_symbol_addr_unix_type DYNLINK_SYMBOL_NAME(name) = { \ - (dynlink_symbol_addr_unix_impl)&name \ - } - -#define DYNLINK_SYMBOL_GET(name) \ - ((dynlink_symbol_addr_unix)(name))->symbol - -/* -- Type definitions -- */ - -typedef void (*dynlink_symbol_addr_unix_impl)(void); - -typedef struct dynlink_symbol_addr_unix_type -{ - dynlink_symbol_addr_unix_impl symbol; -} * dynlink_symbol_addr_unix; - -typedef dynlink_symbol_addr_unix dynlink_symbol_addr; - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_IMPL_SYMBOL_UNIX_H */ diff --git a/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h b/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h deleted file mode 100644 index 670ece3712..0000000000 --- a/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef DYNLINK_IMPL_SYMBOL_WIN32_H -#define DYNLINK_IMPL_SYMBOL_WIN32_H 1 - -/* -- Headers -- */ - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_PREFIX - -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_EXPORT(name) \ - DYNLINK_NO_EXPORT struct \ - { \ - char name; \ - } PREPROCESSOR_CONCAT(dynlink_no_export_, name) - -#define DYNLINK_SYMBOL_GET(name) name - -/* -- Type definitions -- */ - -typedef void (*dynlink_symbol_addr_win32)(void); - -typedef dynlink_symbol_addr_win32 dynlink_symbol_addr; - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_IMPL_SYMBOL_WIN32_H */ diff --git a/source/dynlink/include/dynlink/dynlink_impl_unix.h b/source/dynlink/include/dynlink/dynlink_impl_unix.h index 7cd53898b8..cb239a1d8c 100644 --- a/source/dynlink/include/dynlink/dynlink_impl_unix.h +++ b/source/dynlink/include/dynlink/dynlink_impl_unix.h @@ -25,8 +25,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/source/dynlink/include/dynlink/dynlink_impl_win32.h b/source/dynlink/include/dynlink/dynlink_impl_win32.h index 17daeb7112..9bd39af77e 100644 --- a/source/dynlink/include/dynlink/dynlink_impl_win32.h +++ b/source/dynlink/include/dynlink/dynlink_impl_win32.h @@ -25,8 +25,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/source/dynlink/include/dynlink/dynlink_interface.h b/source/dynlink/include/dynlink/dynlink_interface.h index b0f710c032..0a33fa6086 100644 --- a/source/dynlink/include/dynlink/dynlink_interface.h +++ b/source/dynlink/include/dynlink/dynlink_interface.h @@ -28,18 +28,14 @@ #include #if defined(WIN32) || defined(_WIN32) - #include #include #elif defined(unix) || defined(__unix__) || defined(__unix) || \ defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) || \ (((defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__)) && (defined(MAC_OS_X_VERSION_10_15) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15))) - #include #include #elif (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) - #include #include #elif defined(__HAIKU__) || defined(__BEOS__) - #include #include #else #error "Unsupported platform for dynlink" @@ -50,27 +46,10 @@ #include #include -#include - #ifdef __cplusplus extern "C" { #endif -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_PREFIX_STR() \ - PREPROCESSOR_STRINGIFY_OR_EMPTY(DYNLINK_SYMBOL_PREFIX) - -#define DYNLINK_SYMBOL_NAME(name) \ - PREPROCESSOR_CONCAT(DYNLINK_SYMBOL_PREFIX, name) - -#define DYNLINK_SYMBOL_NAME_STR(name) \ - PREPROCESSOR_STRINGIFY(DYNLINK_SYMBOL_NAME(name)) - -#define DYNLINK_SYMBOL_STR(name) \ - DYNLINK_SYMBOL_PREFIX_STR() \ - name - /* -- Type definitions -- */ typedef dynlink_symbol_addr *dynlink_symbol_addr_ptr; diff --git a/source/dynlink/include/dynlink/dynlink_symbol.h b/source/dynlink/include/dynlink/dynlink_symbol.h deleted file mode 100644 index d0319663f5..0000000000 --- a/source/dynlink/include/dynlink/dynlink_symbol.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef DYNLINK_SYMBOL_H -#define DYNLINK_SYMBOL_H 1 - -/* -- Headers -- */ - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_NAME_SIZE 0xFF - -/* -- Type Definitions -- */ - -typedef char dynlink_symbol_name_man[DYNLINK_SYMBOL_NAME_SIZE]; - -/* -- Methods -- */ - -/** -* @brief -* Get convert a symbol to name mangled for cross-platform dynamic loading -* -* @param[in] symbol_name -* Reference to name of the of dynamically linked shared object symbol -* -* @param[out] symbol_mangled -* Reference to mangled name of the of dynamically linked shared object symbol -* -* @return -* Returns zero if @symbol_name was correctly mangled -*/ -DYNLINK_API size_t dynlink_symbol_name_mangle(dynlink_symbol_name symbol_name, size_t symbol_name_length, dynlink_symbol_name_man symbol_mangled); - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_H */ diff --git a/source/dynlink/include/dynlink/dynlink_type.h b/source/dynlink/include/dynlink/dynlink_type.h index c883ec2dab..7661172e78 100644 --- a/source/dynlink/include/dynlink/dynlink_type.h +++ b/source/dynlink/include/dynlink/dynlink_type.h @@ -44,6 +44,23 @@ typedef const char *dynlink_symbol_name; /**< Dynamically linked shared o typedef portability_library_path_str dynlink_library_path_str; /**< Dynamically linked shared object symbol name */ typedef void *dynlink_impl; /**< Dynamically linked shared object implementation */ typedef char dynlink_name_impl[PORTABILITY_PATH_SIZE]; /**< Allocated copy of dynamically linked shared object name */ +typedef void (*dynlink_symbol_addr)(void); /**< Function pointer referring to a symbol address */ + +/* -- Macros -- */ + +#define dynlink_symbol_cast(type, symbol, result) \ + do \ + { \ + union \ + { \ + type ptr; \ + dynlink_symbol_addr fn; \ + } cast; \ +\ + cast.ptr = (symbol); \ + (result) = cast.fn; \ +\ + } while (0) #ifdef __cplusplus } diff --git a/source/dynlink/source/dynlink_impl_beos.c b/source/dynlink/source/dynlink_impl_beos.c index 8ce81828f5..bc28312af9 100644 --- a/source/dynlink/source/dynlink_impl_beos.c +++ b/source/dynlink/source/dynlink_impl_beos.c @@ -85,7 +85,7 @@ int dynlink_impl_interface_symbol_beos(dynlink handle, dynlink_impl impl, dynlin return 1; } - *addr = (dynlink_symbol_addr)symbol; + dynlink_symbol_cast(void *, symbol, *addr); return (*addr == NULL); } diff --git a/source/dynlink/source/dynlink_impl_macos.c b/source/dynlink/source/dynlink_impl_macos.c index 6447c73902..672b39771b 100644 --- a/source/dynlink/source/dynlink_impl_macos.c +++ b/source/dynlink/source/dynlink_impl_macos.c @@ -133,10 +133,11 @@ dynlink_impl dynlink_impl_interface_load_macos(dynlink handle) int dynlink_impl_interface_symbol_macos(dynlink handle, dynlink_impl impl, dynlink_symbol_name name, dynlink_symbol_addr *addr) { NSSymbol symbol = NSLookupSymbolInModule(impl, name); + void *symbol_addr = NSAddressOfSymbol(symbol); (void)handle; - *addr = (dynlink_symbol_addr)NSAddressOfSymbol(symbol); + dynlink_symbol_cast(void *, symbol_addr, *addr); return (*addr == NULL); } diff --git a/source/dynlink/source/dynlink_impl_unix.c b/source/dynlink/source/dynlink_impl_unix.c index a6455dd648..4c00300c65 100644 --- a/source/dynlink/source/dynlink_impl_unix.c +++ b/source/dynlink/source/dynlink_impl_unix.c @@ -105,7 +105,7 @@ int dynlink_impl_interface_symbol_unix(dynlink handle, dynlink_impl impl, dynlin (void)handle; - *addr = (dynlink_symbol_addr)symbol; + dynlink_symbol_cast(void *, symbol, *addr); return (*addr == NULL); } diff --git a/source/dynlink/source/dynlink_impl_win32.c b/source/dynlink/source/dynlink_impl_win32.c index 8ea74bb24f..75d576f0fd 100644 --- a/source/dynlink/source/dynlink_impl_win32.c +++ b/source/dynlink/source/dynlink_impl_win32.c @@ -76,7 +76,7 @@ int dynlink_impl_interface_symbol_win32(dynlink handle, dynlink_impl impl, dynli (void)handle; - *addr = (dynlink_symbol_addr)proc_addr; + dynlink_symbol_cast(FARPROC, proc_addr, *addr); return (*addr == NULL); } diff --git a/source/dynlink/source/dynlink_symbol.c b/source/dynlink/source/dynlink_symbol.c deleted file mode 100644 index 35ac3861d7..0000000000 --- a/source/dynlink/source/dynlink_symbol.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -/* -- Headers -- */ - -#include -#include - -#include - -/* -- Methods -- */ - -size_t dynlink_symbol_name_mangle(dynlink_symbol_name symbol_name, size_t symbol_name_length, dynlink_symbol_name_man symbol_mangled) -{ - static const char symbol_prefix[] = DYNLINK_SYMBOL_PREFIX_STR(); - static size_t symbol_prefix_length = sizeof(symbol_prefix) - 1; - size_t length = symbol_name_length + symbol_prefix_length; - - if (symbol_mangled == NULL) - { - return length; - } - - if (symbol_prefix_length > 0) - { - memcpy(symbol_mangled, symbol_prefix, symbol_prefix_length); - } - - memcpy(&symbol_mangled[symbol_prefix_length], symbol_name, symbol_name_length); - - symbol_mangled[length] = '\0'; - - return length; -} diff --git a/source/extensions/plugin_extension/include/plugin_extension/plugin_extension.h b/source/extensions/plugin_extension/include/plugin_extension/plugin_extension.h index ef5d86dc55..7b65599132 100644 --- a/source/extensions/plugin_extension/include/plugin_extension/plugin_extension.h +++ b/source/extensions/plugin_extension/include/plugin_extension/plugin_extension.h @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif PLUGIN_EXTENSION_API int plugin_extension(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(plugin_extension); - #ifdef __cplusplus } #endif diff --git a/source/loaders/c_loader/include/c_loader/c_loader.h b/source/loaders/c_loader/include/c_loader/c_loader.h index 0e083cb018..159d45a62a 100644 --- a/source/loaders/c_loader/include/c_loader/c_loader.h +++ b/source/loaders/c_loader/include/c_loader/c_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif C_LOADER_API loader_impl_interface c_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(c_loader_impl_interface_singleton); - C_LOADER_API const char *c_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(c_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/cob_loader/include/cob_loader/cob_loader.h b/source/loaders/cob_loader/include/cob_loader/cob_loader.h index 92c6412aa3..4344cf2571 100644 --- a/source/loaders/cob_loader/include/cob_loader/cob_loader.h +++ b/source/loaders/cob_loader/include/cob_loader/cob_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif COB_LOADER_API loader_impl_interface cob_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(cob_loader_impl_interface_singleton); - COB_LOADER_API const char *cob_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(cob_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/cr_loader/include/cr_loader/cr_loader.h b/source/loaders/cr_loader/include/cr_loader/cr_loader.h index 628f387e66..33e01700f6 100644 --- a/source/loaders/cr_loader/include/cr_loader/cr_loader.h +++ b/source/loaders/cr_loader/include/cr_loader/cr_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif CR_LOADER_API loader_impl_interface cr_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(cr_loader_impl_interface_singleton); - CR_LOADER_API const char *cr_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(cr_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/cs_loader/include/cs_loader/cs_loader.h b/source/loaders/cs_loader/include/cs_loader/cs_loader.h index 546a515caf..37aa49c71a 100644 --- a/source/loaders/cs_loader/include/cs_loader/cs_loader.h +++ b/source/loaders/cs_loader/include/cs_loader/cs_loader.h @@ -13,20 +13,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif CS_LOADER_API loader_impl_interface cs_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(cs_loader_impl_interface_singleton); - CS_LOADER_API const char *cs_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(cs_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/dart_loader/include/dart_loader/dart_loader.h b/source/loaders/dart_loader/include/dart_loader/dart_loader.h index 8b6530480d..15dab7185a 100644 --- a/source/loaders/dart_loader/include/dart_loader/dart_loader.h +++ b/source/loaders/dart_loader/include/dart_loader/dart_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif DART_LOADER_API loader_impl_interface dart_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(dart_loader_impl_interface_singleton); - DART_LOADER_API const char *dart_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(dart_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/ext_loader/include/ext_loader/ext_loader.h b/source/loaders/ext_loader/include/ext_loader/ext_loader.h index 580ab2ff7d..d1a9db118c 100644 --- a/source/loaders/ext_loader/include/ext_loader/ext_loader.h +++ b/source/loaders/ext_loader/include/ext_loader/ext_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif EXT_LOADER_API loader_impl_interface ext_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(ext_loader_impl_interface_singleton); - EXT_LOADER_API const char *ext_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(ext_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/ext_loader/source/ext_loader_impl.cpp b/source/loaders/ext_loader/source/ext_loader_impl.cpp index 25b8385a53..caa235182f 100644 --- a/source/loaders/ext_loader/source/ext_loader_impl.cpp +++ b/source/loaders/ext_loader/source/ext_loader_impl.cpp @@ -76,7 +76,7 @@ typedef struct loader_impl_ext_handle_type union loader_impl_function_cast { - void *ptr; + dynlink_symbol_addr ptr; int (*fn)(void *, void *); }; @@ -352,7 +352,7 @@ int ext_loader_impl_discover(loader_impl impl, loader_handle handle, context ctx { loader_impl_function_cast function_cast; - function_cast.ptr = static_cast(ext.addr); + function_cast.ptr = ext.addr; if (function_cast.fn(impl, loader_impl_handle_container_of(impl, handle)) != 0) { diff --git a/source/loaders/file_loader/include/file_loader/file_loader.h b/source/loaders/file_loader/include/file_loader/file_loader.h index b596e15378..4fff999e25 100644 --- a/source/loaders/file_loader/include/file_loader/file_loader.h +++ b/source/loaders/file_loader/include/file_loader/file_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif FILE_LOADER_API loader_impl_interface file_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(file_loader_impl_interface_singleton); - FILE_LOADER_API const char *file_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(file_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/java_loader/include/java_loader/java_loader.h b/source/loaders/java_loader/include/java_loader/java_loader.h index 4db5d86c2e..b0aaa901d0 100644 --- a/source/loaders/java_loader/include/java_loader/java_loader.h +++ b/source/loaders/java_loader/include/java_loader/java_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif JAVA_LOADER_API loader_impl_interface java_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(java_loader_impl_interface_singleton); - JAVA_LOADER_API const char *java_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(java_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/jl_loader/include/jl_loader/jl_loader.h b/source/loaders/jl_loader/include/jl_loader/jl_loader.h index 574e095044..02d588657b 100644 --- a/source/loaders/jl_loader/include/jl_loader/jl_loader.h +++ b/source/loaders/jl_loader/include/jl_loader/jl_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif JL_LOADER_API loader_impl_interface jl_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(jl_loader_impl_interface_singleton); - JL_LOADER_API const char *jl_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(jl_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/js_loader/include/js_loader/js_loader.h b/source/loaders/js_loader/include/js_loader/js_loader.h index 7af1acf54b..7bbcce7f70 100644 --- a/source/loaders/js_loader/include/js_loader/js_loader.h +++ b/source/loaders/js_loader/include/js_loader/js_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif JS_LOADER_API loader_impl_interface js_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(js_loader_impl_interface_singleton); - JS_LOADER_API const char *js_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(js_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/jsm_loader/include/jsm_loader/jsm_loader.h b/source/loaders/jsm_loader/include/jsm_loader/jsm_loader.h index b3d633549a..6b74e75197 100644 --- a/source/loaders/jsm_loader/include/jsm_loader/jsm_loader.h +++ b/source/loaders/jsm_loader/include/jsm_loader/jsm_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif JSM_LOADER_API loader_impl_interface jsm_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(jsm_loader_impl_interface_singleton); - JSM_LOADER_API const char *jsm_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(jsm_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/llvm_loader/include/llvm_loader/llvm_loader.h b/source/loaders/llvm_loader/include/llvm_loader/llvm_loader.h index db405edd83..e395b8ccc2 100644 --- a/source/loaders/llvm_loader/include/llvm_loader/llvm_loader.h +++ b/source/loaders/llvm_loader/include/llvm_loader/llvm_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif LLVM_LOADER_API loader_impl_interface llvm_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(llvm_loader_impl_interface_singleton); - LLVM_LOADER_API const char *llvm_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(llvm_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/lua_loader/include/lua_loader/lua_loader.h b/source/loaders/lua_loader/include/lua_loader/lua_loader.h index f93ed53127..8117509070 100644 --- a/source/loaders/lua_loader/include/lua_loader/lua_loader.h +++ b/source/loaders/lua_loader/include/lua_loader/lua_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif LUA_LOADER_API loader_impl_interface lua_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(lua_loader_impl_interface_singleton); - LUA_LOADER_API const char *lua_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(lua_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader.h b/source/loaders/mock_loader/include/mock_loader/mock_loader.h index f92e7d1ddc..2f0302fdf4 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif MOCK_LOADER_API loader_impl_interface mock_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(mock_loader_impl_interface_singleton); - MOCK_LOADER_API const char *mock_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(mock_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/node_loader/CMakeLists.txt b/source/loaders/node_loader/CMakeLists.txt index 70108f53e2..a9bf13c675 100644 --- a/source/loaders/node_loader/CMakeLists.txt +++ b/source/loaders/node_loader/CMakeLists.txt @@ -158,7 +158,7 @@ target_link_libraries(${target} ${META_PROJECT_NAME}::metacall # MetaCall library # TODO: Implement delayed load - # ${NodeJS_LIBRARY} # NodeJS library + ${NodeJS_LIBRARY} # NodeJS library PUBLIC ${DEFAULT_LIBRARIES} diff --git a/source/loaders/node_loader/include/node_loader/node_loader.h b/source/loaders/node_loader/include/node_loader/node_loader.h index 8660376395..84b1009bea 100644 --- a/source/loaders/node_loader/include/node_loader/node_loader.h +++ b/source/loaders/node_loader/include/node_loader/node_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif NODE_LOADER_API loader_impl_interface node_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(node_loader_impl_interface_singleton); - NODE_LOADER_API const char *node_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(node_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/node_loader/source/node_loader_impl.cpp b/source/loaders/node_loader/source/node_loader_impl.cpp index af983d29d9..720c7b1a27 100644 --- a/source/loaders/node_loader/source/node_loader_impl.cpp +++ b/source/loaders/node_loader/source/node_loader_impl.cpp @@ -783,27 +783,35 @@ static HMODULE (*get_module_handle_a_ptr)(_In_opt_ LPCSTR) = NULL; /* TODO: Impl /* -- Methods -- */ +#if NODE_MAJOR_VERSION >= 12 + #define node_loader_impl_register_module_id node::ModuleFlags::kLinked | 0x08 /* NM_F_DELETEME */ +#else + #define node_loader_impl_register_module_id 0x02 | 0x08 /* NM_F_LINKED | NM_F_DELETEME */ +#endif + #if 1 // NODE_MAJOR_VERSION < 18 - #if NODE_MAJOR_VERSION >= 12 - #define node_loader_impl_register_module_id node::ModuleFlags::kLinked | 0x08 /* NM_F_DELETEME */ - #else - #define node_loader_impl_register_module_id 0x02 | 0x08 /* NM_F_LINKED | NM_F_DELETEME */ - #endif + #define node_loader_impl_register_binding(module) \ + napi_module_register(&module) +#else + // TODO: This won't work, this must be run after NodeJS has initialized and passing the environment + #define node_loader_impl_register_binding(module) \ + AddLinkedBinding(nullptr, module) +#endif - #define node_loader_impl_register_module(name, fn) \ - do \ - { \ - static napi_module node_loader_module = { \ - NAPI_MODULE_VERSION, \ - node_loader_impl_register_module_id, \ - __FILE__, \ - fn, \ - name, \ - NULL, \ - { 0 } \ - }; \ - napi_module_register(&node_loader_module); \ - } while (0) +#define node_loader_impl_register_module(name, fn) \ + do \ + { \ + static napi_module node_loader_module = { \ + NAPI_MODULE_VERSION, \ + node_loader_impl_register_module_id, \ + __FILE__, \ + fn, \ + name, \ + NULL, \ + { 0 } \ + }; \ + node_loader_impl_register_binding(node_loader_module); \ + } while (0) void node_loader_impl_register_linked_bindings() { @@ -813,9 +821,6 @@ void node_loader_impl_register_linked_bindings() /* Initialize Node Loader Port */ node_loader_impl_register_module("node_loader_port_module", node_loader_port_initialize); } -#else -// TODO: New register implementation -#endif void node_loader_impl_exception(napi_env env, napi_status status) { @@ -3806,9 +3811,8 @@ void node_loader_impl_thread(void *data) #endif */ - // #if NODE_MAJOR_VERSION < 18 + /* Register bindings */ node_loader_impl_register_linked_bindings(); - // #endif /* Unlock node implementation mutex */ uv_mutex_unlock(&node_impl->mutex); diff --git a/source/loaders/py_loader/include/py_loader/py_loader.h b/source/loaders/py_loader/include/py_loader/py_loader.h index 0e655cdb81..cdc88d4155 100644 --- a/source/loaders/py_loader/include/py_loader/py_loader.h +++ b/source/loaders/py_loader/include/py_loader/py_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif PY_LOADER_API loader_impl_interface py_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(py_loader_impl_interface_singleton); - PY_LOADER_API const char *py_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(py_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/rb_loader/include/rb_loader/rb_loader.h b/source/loaders/rb_loader/include/rb_loader/rb_loader.h index 49b53024c0..4d727e5079 100644 --- a/source/loaders/rb_loader/include/rb_loader/rb_loader.h +++ b/source/loaders/rb_loader/include/rb_loader/rb_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif RB_LOADER_API loader_impl_interface rb_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(rb_loader_impl_interface_singleton); - RB_LOADER_API const char *rb_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(rb_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/rpc_loader/include/rpc_loader/rpc_loader.h b/source/loaders/rpc_loader/include/rpc_loader/rpc_loader.h index de574b4b81..a4e399d16e 100644 --- a/source/loaders/rpc_loader/include/rpc_loader/rpc_loader.h +++ b/source/loaders/rpc_loader/include/rpc_loader/rpc_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif RPC_LOADER_API loader_impl_interface rpc_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(rpc_loader_impl_interface_singleton); - RPC_LOADER_API const char *rpc_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(rpc_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/rs_loader/include/rs_loader/rs_loader.h b/source/loaders/rs_loader/include/rs_loader/rs_loader.h index 75f961a332..61e9c11e85 100644 --- a/source/loaders/rs_loader/include/rs_loader/rs_loader.h +++ b/source/loaders/rs_loader/include/rs_loader/rs_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif RS_LOADER_API loader_impl_interface rs_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(rs_loader_impl_interface_singleton); - RS_LOADER_API const char *rs_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(rs_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/ts_loader/include/ts_loader/ts_loader.h b/source/loaders/ts_loader/include/ts_loader/ts_loader.h index 812c4c2496..b433fd9411 100644 --- a/source/loaders/ts_loader/include/ts_loader/ts_loader.h +++ b/source/loaders/ts_loader/include/ts_loader/ts_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif TS_LOADER_API loader_impl_interface ts_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(ts_loader_impl_interface_singleton); - TS_LOADER_API const char *ts_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(ts_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader.h b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader.h index b34e2a5d10..067ea4856f 100644 --- a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader.h +++ b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader.h @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif WASM_LOADER_API loader_impl_interface wasm_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(wasm_loader_impl_interface_singleton); - WASM_LOADER_API const char *wasm_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(wasm_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/metacall/source/metacall.c b/source/metacall/source/metacall.c index 8a9ad2eb9c..a5beb250cd 100644 --- a/source/metacall/source/metacall.c +++ b/source/metacall/source/metacall.c @@ -72,6 +72,65 @@ static type_id *metacall_type_ids(void *args[], size_t size); /* -- Costructors -- */ +/* TODO: Test, abstract and remove this */ +/* +#include + +extern void *__libc_dlsym(void *map, const char *name); +extern void *__libc_dlopen_mode(const char *name, int mode); + +typedef void *(*dynlink_dlsym_fn)(void *, const char *); + +static dynlink_dlsym_fn dynlink_dlsym_fn_ptr = NULL; + +int dynlink_dlsym_initialize(void) +{ + void *handle = __libc_dlopen_mode("libdl.so.2", RTLD_GLOBAL | RTLD_LAZY); + union + { + void *ptr; + dynlink_dlsym_fn fn; + } cast; + + if (handle == NULL) + { + return 1; + } + + cast.ptr = __libc_dlsym(handle, "dlsym"); + + if (cast.ptr == NULL) + { + return 1; + } + + dynlink_dlsym_fn_ptr = cast.fn; + + return 0; +} + +void *dynlink_dlsym(void *handle, const char *symbol) +{ + if (dynlink_dlsym_fn_ptr == NULL) + { + if (dynlink_dlsym_initialize() != 0) + { + return NULL; + } + } + + return dynlink_dlsym_fn_ptr(handle, symbol); +} + +void *dlsym(void *handle, const char *symbol) +{ + printf("HANDLE %p - Symbol: %s\n", handle, symbol); + + return dynlink_dlsym(handle, symbol); +} +*/ +/* TODO-END */ + portability_constructor(metacall_constructor) { if (metacall_initialize_flag == 1) diff --git a/source/plugin/source/plugin_descriptor.c b/source/plugin/source/plugin_descriptor.c index 491895e050..00f463079c 100644 --- a/source/plugin/source/plugin_descriptor.c +++ b/source/plugin/source/plugin_descriptor.c @@ -65,7 +65,7 @@ plugin_descriptor plugin_descriptor_create(char *path, char *library_name, char return NULL; } - descriptor->iface_singleton = (void *(*)(void))DYNLINK_SYMBOL_GET(address); + descriptor->iface_singleton = (void *(*)(void))(address); if (descriptor->iface_singleton == NULL) { diff --git a/source/plugin/source/plugin_loader.c b/source/plugin/source/plugin_loader.c index 5212f7ebb5..a88ccda719 100644 --- a/source/plugin/source/plugin_loader.c +++ b/source/plugin/source/plugin_loader.c @@ -178,20 +178,19 @@ char *plugin_loader_generate_library_name(const char *name, char *suffix) char *plugin_loader_generate_symbol_iface_name(const char *name, char *suffix) { size_t name_length = strlen(name); - size_t mangle_length = dynlink_symbol_name_mangle(name, name_length, NULL); size_t suffix_length = strlen(suffix); - char *symbol_iface_name = malloc(sizeof(char) * (mangle_length + suffix_length + 1)); + char *symbol_iface_name = malloc(sizeof(char) * (name_length + suffix_length + 1)); if (symbol_iface_name == NULL) { return NULL; } - dynlink_symbol_name_mangle(name, name_length, symbol_iface_name); + memcpy(symbol_iface_name, name, name_length); - memcpy(&symbol_iface_name[mangle_length], suffix, suffix_length); + memcpy(&symbol_iface_name[name_length], suffix, suffix_length); - symbol_iface_name[mangle_length + suffix_length] = '\0'; + symbol_iface_name[name_length + suffix_length] = '\0'; return symbol_iface_name; } diff --git a/source/plugins/backtrace_plugin/include/backtrace_plugin/backtrace_plugin.h b/source/plugins/backtrace_plugin/include/backtrace_plugin/backtrace_plugin.h index 5269713f94..7a2ce1f079 100644 --- a/source/plugins/backtrace_plugin/include/backtrace_plugin/backtrace_plugin.h +++ b/source/plugins/backtrace_plugin/include/backtrace_plugin/backtrace_plugin.h @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif BACKTRACE_PLUGIN_API int backtrace_plugin(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(backtrace_plugin); - #ifdef __cplusplus } #endif diff --git a/source/plugins/sandbox_plugin/include/sandbox_plugin/sandbox_plugin.h b/source/plugins/sandbox_plugin/include/sandbox_plugin/sandbox_plugin.h index 12d8c2caf4..68d6d23f42 100644 --- a/source/plugins/sandbox_plugin/include/sandbox_plugin/sandbox_plugin.h +++ b/source/plugins/sandbox_plugin/include/sandbox_plugin/sandbox_plugin.h @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif SANDBOX_PLUGIN_API int sandbox_plugin(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(sandbox_plugin); - #ifdef __cplusplus } #endif diff --git a/source/scripts/extension/sum/include/sum_extension/sum_extension.h b/source/scripts/extension/sum/include/sum_extension/sum_extension.h index 4dd93bc046..386bd4d761 100644 --- a/source/scripts/extension/sum/include/sum_extension/sum_extension.h +++ b/source/scripts/extension/sum/include/sum_extension/sum_extension.h @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif SUM_EXTENSION_API int sum_extension(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(sum_extension); - #ifdef __cplusplus } #endif diff --git a/source/serials/metacall_serial/include/metacall_serial/metacall_serial.h b/source/serials/metacall_serial/include/metacall_serial/metacall_serial.h index 5d4f2e119f..fb80de34c5 100644 --- a/source/serials/metacall_serial/include/metacall_serial/metacall_serial.h +++ b/source/serials/metacall_serial/include/metacall_serial/metacall_serial.h @@ -27,8 +27,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif @@ -45,8 +43,6 @@ extern "C" { */ METACALL_SERIAL_API serial_interface metacall_serial_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(metacall_serial_impl_interface_singleton); - /** * @brief * Provide the module information @@ -57,8 +53,6 @@ DYNLINK_SYMBOL_EXPORT(metacall_serial_impl_interface_singleton); */ METACALL_SERIAL_API const char *metacall_serial_print_info(void); -DYNLINK_SYMBOL_EXPORT(metacall_serial_print_info); - #ifdef __cplusplus } #endif diff --git a/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial.h b/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial.h index 51e32e3b80..106acb20e6 100644 --- a/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial.h +++ b/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial.h @@ -27,8 +27,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif @@ -45,8 +43,6 @@ extern "C" { */ RAPID_JSON_SERIAL_API serial_interface rapid_json_serial_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(rapid_json_serial_impl_interface_singleton); - /** * @brief * Provide the module information @@ -57,8 +53,6 @@ DYNLINK_SYMBOL_EXPORT(rapid_json_serial_impl_interface_singleton); */ RAPID_JSON_SERIAL_API const char *rapid_json_serial_print_info(void); -DYNLINK_SYMBOL_EXPORT(rapid_json_serial_print_info); - #ifdef __cplusplus } #endif diff --git a/source/tests/dynlink_test/source/dynlink_test.cpp b/source/tests/dynlink_test/source/dynlink_test.cpp index dc77a7c6b9..3d69b74a27 100644 --- a/source/tests/dynlink_test/source/dynlink_test.cpp +++ b/source/tests/dynlink_test/source/dynlink_test.cpp @@ -68,17 +68,17 @@ TEST_F(dynlink_test, DefaultConstructor) { static dynlink_symbol_addr mock_loader_print_info_addr; - EXPECT_EQ((int)0, dynlink_symbol(handle, DYNLINK_SYMBOL_STR("mock_loader_print_info"), &mock_loader_print_info_addr)); + EXPECT_EQ((int)0, dynlink_symbol(handle, "mock_loader_print_info", &mock_loader_print_info_addr)); if (mock_loader_print_info_addr != NULL) { - mock_loader_print_func print = DYNLINK_SYMBOL_GET(mock_loader_print_info_addr); + mock_loader_print_func print = mock_loader_print_info_addr; log_write("metacall", LOG_LEVEL_DEBUG, "Print function: %p", (void *)print); log_write("metacall", LOG_LEVEL_DEBUG, "Symbol pointer: %p", (void *)mock_loader_print_info_addr); - if (DYNLINK_SYMBOL_GET(mock_loader_print_info_addr) != NULL) + if (mock_loader_print_info_addr != NULL) { log_write("metacall", LOG_LEVEL_DEBUG, "Pointer is valid"); }