diff options
Diffstat (limited to 'backends/plugins')
-rw-r--r-- | backends/plugins/elf-provider.cpp | 94 | ||||
-rw-r--r-- | backends/plugins/elf-provider.h | 52 |
2 files changed, 78 insertions, 68 deletions
diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 226ac06469..4e1f277fb8 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -23,90 +23,48 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - #include "backends/plugins/elf-provider.h" #include "backends/plugins/dynamic-plugin.h" #include "common/fs.h" #include "backends/plugins/elf-loader.h" -class ELFPlugin : public DynamicPlugin { -protected: - DLObject *_dlHandle; - Common::String _filename; - - virtual VoidFunc findSymbol(const char *symbol) { - void *func; - bool handleNull; - if (_dlHandle == NULL) { - func = NULL; - handleNull = true; - } else { - func = _dlHandle->symbol(symbol); - } - if (!func) { - if (handleNull) { - warning("Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); - } else { - warning("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); - } - } +#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ - // standard and POSIX: ISO C++ disallows casting between function pointers - // and data pointers, but dlsym always returns a void pointer. For details, - // see e.g. <http://www.trilithium.com/johan/2004/12/problem-with-dlsym/>. - assert(sizeof(VoidFunc) == sizeof(func)); - VoidFunc tmp; - memcpy(&tmp, &func, sizeof(VoidFunc)); - return tmp; +bool ELFPlugin::loadPlugin() { + assert(!_dlHandle); + DLObject *obj = new DLObject(NULL); + if (obj->open(_filename.c_str())) { + _dlHandle = obj; + } else { + delete obj; + _dlHandle = NULL; } -public: - ELFPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} - - ~ELFPlugin() { - if (_dlHandle) - unloadPlugin(); + if (!_dlHandle) { + warning("Failed loading plugin '%s'", _filename.c_str()); + return false; } - bool loadPlugin() { - assert(!_dlHandle); - DLObject *obj = new DLObject(NULL); - if (obj->open(_filename.c_str())) { - _dlHandle = obj; - } else { - delete obj; - _dlHandle = NULL; - } + bool ret = DynamicPlugin::loadPlugin(); - if (!_dlHandle) { - warning("Failed loading plugin '%s'", _filename.c_str()); - return false; - } - - bool ret = DynamicPlugin::loadPlugin(); - - if (ret && _dlHandle) { - _dlHandle->discard_symtab(); - } - - return ret; + if (ret && _dlHandle) { + _dlHandle->discard_symtab(); } - void unloadPlugin() { - DynamicPlugin::unloadPlugin(); - if (_dlHandle) { - delete _dlHandle; - if (!_dlHandle->close()) { - warning("Failed unloading plugin '%s'", _filename.c_str()); - } - _dlHandle = 0; + return ret; +} + +void ELFPlugin::unloadPlugin() { + DynamicPlugin::unloadPlugin(); + if (_dlHandle) { + delete _dlHandle; + if (!_dlHandle->close()) { + warning("Failed unloading plugin '%s'", _filename.c_str()); } + _dlHandle = 0; } -}; +} Plugin* ELFPluginProvider::createPlugin(const Common::FSNode &node) const { diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index a6b55d97f3..981d0d0638 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -27,9 +27,61 @@ #define BACKENDS_PLUGINS_ELF_PROVIDER_H #include "base/plugins.h" +#include "backends/plugins/dynamic-plugin.h" +#include "common/fs.h" + +#include "backends/plugins/elf-loader.h" #if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) +class ELFPlugin : public DynamicPlugin { +protected: + DLObject *_dlHandle; + Common::String _filename; + + //FIXME: The code for this method should be in elf-provider.cpp, + // but VoidFunc isn't recognized if we do that as is. + virtual VoidFunc findSymbol(const char *symbol) { + void *func; + bool handleNull; + if (_dlHandle == NULL) { + func = NULL; + handleNull = true; + } else { + func = _dlHandle->symbol(symbol); + } + if (!func) { + if (handleNull) { + warning("Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); + } else { + warning("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); + } + } + + // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ + // standard and POSIX: ISO C++ disallows casting between function pointers + // and data pointers, but dlsym always returns a void pointer. For details, + // see e.g. <http://www.trilithium.com/johan/2004/12/problem-with-dlsym/>. + assert(sizeof(VoidFunc) == sizeof(func)); + VoidFunc tmp; + memcpy(&tmp, &func, sizeof(VoidFunc)); + return tmp;; + } + +public: + ELFPlugin(const Common::String &filename) + : _dlHandle(0), _filename(filename) {} + + ~ELFPlugin() { + if (_dlHandle) + unloadPlugin(); + } + + bool loadPlugin(); + void unloadPlugin(); + +}; + class ELFPluginProvider : public FilePluginProvider { protected: Plugin* createPlugin(const Common::FSNode &node) const; |