summaryrefslogtreecommitdiff
path: root/src/lua-plugin.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua-plugin.cc')
-rw-r--r--src/lua-plugin.cc120
1 files changed, 114 insertions, 6 deletions
diff --git a/src/lua-plugin.cc b/src/lua-plugin.cc
index e80f0f8..fe4b0b5 100644
--- a/src/lua-plugin.cc
+++ b/src/lua-plugin.cc
@@ -1,4 +1,5 @@
#include <lua-plugin.h>
+#include <Input.h>
#if defined(_WIN32)
#define SHARED_EXT "dll"
@@ -12,6 +13,7 @@ typedef void(*init_ptr_t)(Lua *);
#if defined(_WIN32)
#include <windows.h>
+#include "MemoryModule.h"
void LuaLoadPlugin(const String & _fname, Lua * L) throw (GeneralException) {
HMODULE handle;
@@ -20,40 +22,146 @@ void LuaLoadPlugin(const String & _fname, Lua * L) throw (GeneralException) {
Base::printm(M_INFO, "Loading library " + fname + "\n");
if (!(handle = LoadLibraryEx(fname.to_charp(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) &&
- !(handle = LoadLibraryEx(fname.to_charp(), NULL, NULL))) {
- throw GeneralException("File not found or error loading shared object file: " + fname + "; Error #" + String((int) GetLastError()));
+ !(handle = LoadLibraryEx(fname.to_charp(), NULL, NULL))) {
+ LuaLoadPlugin(&Input(fname), L);
+ return;
}
init_ptr_t init_ptr = (init_ptr_t) GetProcAddress(handle, "init_plugin");
if (!init_ptr) {
- throw GeneralException("No init pointer on plugin " + fname);
+ FreeLibrary(handle);
+ throw GeneralException("No init pointer on plugin " + fname);
}
Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr);
init_ptr(L);
}
+
+void LuaLoadPlugin(Handle * h, Lua * L) throw (GeneralException) {
+ Byte * buffer;
+
+ buffer = (Byte *) malloc(h->GetSize());
+ h->read(buffer, h->GetSize());
+
+ HMEMORYMODULE module;
+
+ if (!(module = ModuleLoadMemory(buffer)))
+ throw("Can't load library " + h->GetName() + " from memory.");
+
+ init_ptr_t init_ptr = (init_ptr_t) MemoryGetProcAddress(module, "init_plugin");
+
+ if (!init_ptr) {
+ MemoryFreeLibrary(module);
+ throw GeneralException("No init pointer on plugin " + h->GetName());
+ }
+
+ Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr);
+
+ init_ptr(L);
+
+ free(buffer);
+}
+
#else
#include <dlfcn.h>
void LuaLoadPlugin(const String & fname, Lua * L) throw (GeneralException) {
- void * handle = dlopen(("./" + fname + "." SHARED_EXT).to_charp(), RTLD_NOW | RTLD_GLOBAL);
+ String full_fname = "./" + fname + "." SHARED_EXT;
+ void * handle = dlopen(full_fname.to_charp(), RTLD_NOW | RTLD_GLOBAL);
Base::printm(M_INFO, "Loading library " + fname + "\n");
if (!handle) {
- throw GeneralException("File not found or error loading shared object file: " + fname + "; " + dlerror());
+ LuaLoadPlugin(&Input(full_fname), L);
+ return;
}
init_ptr_t init_ptr = (init_ptr_t) dlsym(handle, "init_plugin");
if (!init_ptr) {
- throw GeneralException("No init pointer on plugin " + fname);
+ dlclose(handle);
+ throw GeneralException("No init pointer on plugin " + fname);
}
Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr);
init_ptr(L);
}
+
+#if defined(__APPLE__)
+void LuaLoadPlugin(Handle * h, Lua * L) throw (GeneralException) {
+ Byte * buffer;
+ NSObjectFileImage image;
+
+ kern_return_t result = vm_allocate(mach_task_self(), (vm_address_t *) &buffer, h->GetSize(), VM_FLAGS_ANYWHERE);
+ h->read(buffer, h->GetSize());
+
+ if (NSCreateObjectFileImageFromMemory(buffer, h->GetSize(), &image) != NSObjectFileImageSuccess)
+ throw("Can't load library " + h->GetName() + " from memory.");
+
+ if (!NSLinkModule(image, h->GetName().get_charp(), NSLINKMODULE_OPTION_PRIVATE))
+ throw("Can't link library " + h->GetName() + " from memory.");
+
+ NSSymbol symbol = NSLookupSymbolInModule(module, "init_plugin");
+ init_ptr_t init_ptr = (init_ptr_t) NSAddressOfSymbol(symbol);
+
+ if (!init_ptr) {
+ NSDestroyObjectFileImage(image);
+ throw GeneralException("No init pointer on plugin " + fname);
+ }
+
+ Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr);
+
+ init_ptr(L);
+
+}
+#else
+
+#include <unistd.h>
+
+// I don't know of any good way of doing this under linux except this one... *shrug*
+void LuaLoadPlugin(Handle * h, Lua * L) throw (GeneralException) {
+ char ftemplate[] = "/tmp/luaplugin.so.XXXXXX");
+ int h;
+
+ if ((h = mkstemp(ftemplate)) == -1)
+ throw GeneralException("Can't create temporary file to load plugin " + h->Getname());
+
+ Byte * buffer;
+ buffer = (Byte *) malloc(h->GetSize());
+ h->read(buffer, h->GetSize());
+
+ if (write(h, buffer, h->GetSize()) != h->GetSize()) {
+ free(buffer);
+ close(h);
+ unlink(ftemplate);
+ throw GeneralException("Couldn't write to temporary file.");
+ }
+
+ free(buffer);
+ void * handle = dlopen(ftemplate, RTLD_NOW | RTLD_GLOBAL);
+ unlink(ftemplate);
+ close(h);
+
+ Base::printm(M_INFO, "Loading library " + fname + "\n");
+
+ if (!handle)
+ throw("Can't load library " + h->GetName() + " from memory.");
+
+ init_ptr_t init_ptr = (init_ptr_t) dlsym(handle, "init_plugin");
+
+ if (!init_ptr) {
+ dlclose(handle);
+ throw GeneralException("No init pointer on plugin " + h->GetName());
+ }
+
+ Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr);
+
+ init_ptr(L);
+}
+
+#endif
+
#endif