From ca5c11603f3031b7658328747d4facceb7c6a2ca Mon Sep 17 00:00:00 2001 From: Pauli Date: Fri, 29 Jun 2018 00:23:55 +0300 Subject: [PATCH] Support dlsym loading from libgraphics vtables --- library/Core.cpp | 3 -- library/PlugLoad-posix.cpp | 1 + library/PlugLoad-windows.cpp | 2 ++ library/VersionInfoFactory.cpp | 25 ++++++++++++---- library/include/PluginManager.h | 2 ++ library/modules/Screen.cpp | 52 --------------------------------- 6 files changed, 24 insertions(+), 61 deletions(-) diff --git a/library/Core.cpp b/library/Core.cpp index 479eaea08..e9b729ff9 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1558,8 +1558,6 @@ std::string Core::getHackPath() #endif } -void init_screen_module(Core *); - bool Core::Init() { if(started) @@ -1706,7 +1704,6 @@ bool Core::Init() */ // initialize data defs virtual_identity::Init(this); - init_screen_module(this); // copy over default config files if necessary std::vector config_files; diff --git a/library/PlugLoad-posix.cpp b/library/PlugLoad-posix.cpp index e612ccb74..2eb1d5448 100644 --- a/library/PlugLoad-posix.cpp +++ b/library/PlugLoad-posix.cpp @@ -23,6 +23,7 @@ */ namespace DFHack { + DFLibrary* GLOBAL_NAMES = (DFLibrary*)RTLD_DEFAULT; DFLibrary * OpenPlugin (const char * filename) { dlerror(); diff --git a/library/PlugLoad-windows.cpp b/library/PlugLoad-windows.cpp index df8397f96..61fe9977f 100644 --- a/library/PlugLoad-windows.cpp +++ b/library/PlugLoad-windows.cpp @@ -41,6 +41,8 @@ distribution. */ namespace DFHack { + //! \todo What windows HMODULE matches RTLD_DEFAULT? + DFLibrary* GLOBAL_NAMES = 0; DFLibrary * OpenPlugin (const char * filename) { return (DFLibrary *) LoadLibrary(filename); diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp index 7033fd598..c895a1510 100644 --- a/library/VersionInfoFactory.cpp +++ b/library/VersionInfoFactory.cpp @@ -35,6 +35,7 @@ using namespace std; #include "VersionInfo.h" #include "Error.h" #include "Memory.h" +#include "PluginManager.h" using namespace DFHack; #include @@ -133,18 +134,30 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem) if(!cstr_key) throw Error::SymbolsXmlUnderspecifiedEntry(cstr_name); const char *cstr_value = pMemEntry->Attribute("value"); - if(!cstr_value) + const char *cstr_mangled = pMemEntry->Attribute("mangled"); + if(!cstr_value && !cstr_mangled) { cerr << "Dummy symbol table entry: " << cstr_key << endl; continue; } if ((is_vtable && no_vtables) || (!is_vtable && no_globals)) continue; -#ifdef DFHACK64 - uintptr_t addr = strtoull(cstr_value, 0, 0); -#else - uintptr_t addr = strtol(cstr_value, 0, 0); -#endif + uintptr_t addr; + if (cstr_value) { + if (sizeof(addr) == sizeof(unsigned long)) + addr = strtoul(cstr_value, 0, 0); + else + addr = strtoull(cstr_value, 0, 0); + } else { + addr = (uintptr_t)DFHack::LookupPlugin(DFHack::GLOBAL_NAMES, cstr_mangled); + if (!addr) + continue; + const char *cstr_offset = pMemEntry->Attribute("offset"); + if (cstr_offset) { + unsigned long offset = strtoul(cstr_offset, 0, 0); + addr += offset; + } + } if (is_vtable) mem->setVTable(cstr_key, addr); else diff --git a/library/include/PluginManager.h b/library/include/PluginManager.h index c8776d8ed..e473d7acb 100644 --- a/library/include/PluginManager.h +++ b/library/include/PluginManager.h @@ -67,6 +67,8 @@ namespace DFHack // anon type, pretty much struct DFLibrary; + // DFLibrary* that can be used to resolve global names + extern DFLibrary* GLOBAL_NAMES; // Open a plugin library DFHACK_EXPORT DFLibrary * OpenPlugin (const char * filename); // find a symbol inside plugin diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 733f8cb78..363ec1c6f 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -412,58 +412,6 @@ void Hide::merge(df::viewscreen* a) } } } -#ifdef _LINUX -class DFHACK_EXPORT renderer { - unsigned char *screen; - long *screentexpos; - char *screentexpos_addcolor; - unsigned char *screentexpos_grayscale; - unsigned char *screentexpos_cf; - unsigned char *screentexpos_cbr; - // For partial printing: - unsigned char *screen_old; - long *screentexpos_old; - char *screentexpos_addcolor_old; - unsigned char *screentexpos_grayscale_old; - unsigned char *screentexpos_cf_old; - unsigned char *screentexpos_cbr_old; -public: - virtual void update_tile(int x, int y) {}; - virtual void update_all() {}; - virtual void render() {}; - virtual void set_fullscreen(); - virtual void zoom(df::zoom_commands cmd); - virtual void resize(int w, int h) {}; - virtual void grid_resize(int w, int h) {}; - renderer() { - screen = NULL; - screentexpos = NULL; - screentexpos_addcolor = NULL; - screentexpos_grayscale = NULL; - screentexpos_cf = NULL; - screentexpos_cbr = NULL; - screen_old = NULL; - screentexpos_old = NULL; - screentexpos_addcolor_old = NULL; - screentexpos_grayscale_old = NULL; - screentexpos_cf_old = NULL; - screentexpos_cbr_old = NULL; - } - virtual ~renderer(); - virtual bool get_mouse_coords(int &x, int &y) { return false; } - virtual bool uses_opengl(); -}; -#endif - -void init_screen_module(Core *core) -{ -#ifdef _LINUX - renderer tmp; - if (!strict_virtual_cast((virtual_ptr)&tmp)) - cerr << "Could not fetch the renderer vtable." << std::endl; -#endif -} - string Screen::getKeyDisplay(df::interface_key key) { if (enabler)