diff --git a/include/helpers/plugin_handler.hpp b/include/helpers/plugin_handler.hpp index 3751c5f57..a6f41036b 100644 --- a/include/helpers/plugin_handler.hpp +++ b/include/helpers/plugin_handler.hpp @@ -38,7 +38,7 @@ namespace hex { private: static inline std::string s_pluginFolder; - static inline std::vector s_plugins; + static inline std::vector s_plugins; }; } \ No newline at end of file diff --git a/include/views/view_pattern.hpp b/include/views/view_pattern.hpp index 809bbd6e8..77cc38fd2 100644 --- a/include/views/view_pattern.hpp +++ b/include/views/view_pattern.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -33,7 +34,7 @@ namespace hex { TextEditor m_textEditor; std::vector> m_console; - void loadPatternFile(std::string path); + void loadPatternFile(std::string_view path); void clearPatternData(); void parsePattern(char *buffer); }; diff --git a/plugins/builtin/CMakeLists.txt b/plugins/builtin/CMakeLists.txt index 23fce8bf6..200edc136 100644 --- a/plugins/builtin/CMakeLists.txt +++ b/plugins/builtin/CMakeLists.txt @@ -26,12 +26,15 @@ target_link_libraries(${PROJECT_NAME} PRIVATE libimhex LLVMDemangle) # ---- No need to change anything from here downwards unless you know what you're doing ---- # set(CMAKE_CXX_STANDARD 20) -set(CMAKE_SHARED_LIBRARY_PREFIX "plugin") +set(CMAKE_SHARED_LIBRARY_PREFIX "") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".hexplug") if (WIN32) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -Wl,--allow-multiple-definition") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -Wl,--allow-multiple-definition -fvisibility=hidden") endif() +add_compile_definitions(IMHEX_PLUGIN_NAME=${PROJECT_NAME}) + if (NOT TARGET libimhex) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libimhex ${CMAKE_CURRENT_BINARY_DIR}/plugins/libimhex) endif() \ No newline at end of file diff --git a/plugins/example/CMakeLists.txt b/plugins/example/CMakeLists.txt index 7a25c31f6..e8cf06ff7 100644 --- a/plugins/example/CMakeLists.txt +++ b/plugins/example/CMakeLists.txt @@ -18,12 +18,15 @@ target_link_libraries(${PROJECT_NAME} PRIVATE libimhex) # ---- No need to change anything from here downwards unless you know what you're doing ---- # set(CMAKE_CXX_STANDARD 20) -set(CMAKE_SHARED_LIBRARY_PREFIX "plugin") +set(CMAKE_SHARED_LIBRARY_PREFIX "") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".hexplug") if (WIN32) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -Wl,--allow-multiple-definition") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -Wl,--allow-multiple-definition -fvisibility=hidden") endif() +add_compile_definitions(IMHEX_PLUGIN_NAME=${PROJECT_NAME}) + if (NOT TARGET libimhex) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libimhex ${CMAKE_CURRENT_BINARY_DIR}/plugins/libimhex) endif() \ No newline at end of file diff --git a/plugins/libimhex/include/hex/plugin.hpp b/plugins/libimhex/include/hex/plugin.hpp index 2a691727e..9b26133b6 100644 --- a/plugins/libimhex/include/hex/plugin.hpp +++ b/plugins/libimhex/include/hex/plugin.hpp @@ -11,7 +11,9 @@ #include #include -#define IMHEX_PLUGIN_SETUP namespace hex::plugin::internal { \ - void initializePlugin(); \ - } \ - void hex::plugin::internal::initializePlugin() +#define IMHEX_PLUGIN_SETUP IMHEX_PLUGIN_SETUP_IMPL(IMHEX_PLUGIN_NAME) + +#define IMHEX_PLUGIN_SETUP_IMPL(name) namespace hex::plugin::name::internal { \ + [[gnu::visibility("default")]] void initializePlugin(); \ + } \ + void hex::plugin::name::internal::initializePlugin() diff --git a/source/helpers/plugin_handler.cpp b/source/helpers/plugin_handler.cpp index 0fee48a9a..1b8f493f1 100644 --- a/source/helpers/plugin_handler.cpp +++ b/source/helpers/plugin_handler.cpp @@ -1,51 +1,66 @@ #include "helpers/plugin_handler.hpp" #include + #include namespace hex { + namespace fs = std::filesystem; + // hex::plugin::internal::initializePlugin() - constexpr auto InitializePluginSymbol = "_ZN3hex6plugin8internal16initializePluginEv"; + constexpr auto InitializePluginSymbol = "_ZN3hex6plugin%d%s8internal16initializePluginEv"; Plugin::Plugin(std::string_view path) { + auto fileName = fs::path(path).stem(); + auto symbolName = hex::format(InitializePluginSymbol, fileName.string().length(), fileName.string().c_str()); this->m_handle = dlopen(path.data(), RTLD_LAZY); - if (this->m_handle == nullptr) return; - this->m_initializePluginFunction = reinterpret_cast(dlsym(this->m_handle, InitializePluginSymbol)); + printf("Loaded plugin %s\n", path.data()); + + + this->m_initializePluginFunction = reinterpret_cast(dlsym(this->m_handle, symbolName.c_str())); + printf("Symbol %s at %p\n", symbolName.c_str(), this->m_initializePluginFunction); + } Plugin::~Plugin() { + printf("Plugin unloaded\n"); dlclose(this->m_handle); } void Plugin::initializePlugin() const { - if (this->m_initializePluginFunction != nullptr) + if (this->m_initializePluginFunction != nullptr) { + printf("Initializing plugin\n"); this->m_initializePluginFunction(); + printf("Initialized plugin\n"); + } } void PluginHandler::load(std::string_view pluginFolder) { - PluginHandler::unload(); - if (!std::filesystem::exists(pluginFolder)) throw std::runtime_error("Failed to find plugin folder"); PluginHandler::s_pluginFolder = pluginFolder; for (auto& pluginPath : std::filesystem::directory_iterator(pluginFolder)) { - if (pluginPath.is_regular_file()) - PluginHandler::s_plugins.emplace_back(pluginPath.path().string()); + if (pluginPath.is_regular_file() && pluginPath.path().extension() == ".hexplug") + PluginHandler::s_plugins.push_back(new Plugin(pluginPath.path().string())); } } void PluginHandler::unload() { + for (auto &plugin : PluginHandler::s_plugins) + delete plugin; + PluginHandler::s_plugins.clear(); PluginHandler::s_pluginFolder.clear(); } void PluginHandler::reload() { + PluginHandler::unload(); PluginHandler::load(PluginHandler::s_pluginFolder); } diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp index f5e11ad56..49073d93d 100644 --- a/source/views/view_pattern.cpp +++ b/source/views/view_pattern.cpp @@ -153,11 +153,11 @@ namespace hex { size_t size = ftell(file); rewind(file); - std::vector buffer( size + 1, 0x00); - fread(buffer.data(), 1, size, file); + std::vector patternBuffer( size + 1, 0x00); + fread(patternBuffer.data(), 1, size, file); fclose(file); - preprocessor.preprocess(buffer.data()); + preprocessor.preprocess(patternBuffer.data()); if (foundCorrectType) this->m_possiblePatternFiles.push_back(entry.path().filename().string()); @@ -289,8 +289,8 @@ namespace hex { } - void ViewPattern::loadPatternFile(std::string path) { - FILE *file = fopen(path.c_str(), "rb"); + void ViewPattern::loadPatternFile(std::string_view path) { + FILE *file = fopen(path.data(), "rb"); if (file != nullptr) { char *buffer; @@ -325,7 +325,7 @@ namespace hex { this->clearPatternData(); this->m_textEditor.SetErrorMarkers({ }); this->m_console.clear(); - this->postEvent(Events::PatternChanged); + View::postEvent(Events::PatternChanged); auto result = this->m_patternLanguageRuntime->executeString(SharedData::currentProvider, buffer); diff --git a/source/window.cpp b/source/window.cpp index 74d7750e3..1878c8368 100644 --- a/source/window.cpp +++ b/source/window.cpp @@ -552,7 +552,7 @@ namespace hex { } catch (std::runtime_error &e) { return; } for (const auto &plugin : PluginHandler::getPlugins()) { - plugin.initializePlugin(); + plugin->initializePlugin(); } }