mirror of
https://github.com/matrix-construct/construct
synced 2024-11-18 07:50:57 +01:00
modules: use libltdl to load the modules
This commit is contained in:
parent
bc38c72ced
commit
f272e7abc7
2 changed files with 19 additions and 167 deletions
|
@ -32,12 +32,7 @@
|
|||
|
||||
#define MAPI_RATBOX 1
|
||||
|
||||
#if defined(HAVE_SHL_LOAD)
|
||||
#include <dl.h>
|
||||
#endif
|
||||
#if !defined(STATIC_MODULES) && defined(HAVE_DLFCN_H)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include <ltdl.h>
|
||||
|
||||
#include "msg.h"
|
||||
#include "hook.h"
|
||||
|
@ -46,7 +41,7 @@ struct module
|
|||
{
|
||||
char *name;
|
||||
const char *version;
|
||||
void *address;
|
||||
lt_dlhandle address;
|
||||
int core;
|
||||
int mapi_version;
|
||||
void * mapi_header; /* actually struct mapi_mheader_av<mapi_version> */
|
||||
|
|
177
src/modules.c
177
src/modules.c
|
@ -42,6 +42,8 @@
|
|||
|
||||
#ifndef STATIC_MODULES
|
||||
|
||||
#include <ltdl.h>
|
||||
|
||||
struct module **modlist = NULL;
|
||||
|
||||
static const char *core_module_table[] = {
|
||||
|
@ -101,6 +103,12 @@ struct Message modrestart_msgtab = {
|
|||
void
|
||||
modules_init(void)
|
||||
{
|
||||
if(lt_dlinit())
|
||||
{
|
||||
ilog(L_MAIN, "lt_dlinit failed");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
mod_add_cmd(&modload_msgtab);
|
||||
mod_add_cmd(&modunload_msgtab);
|
||||
mod_add_cmd(&modreload_msgtab);
|
||||
|
@ -515,152 +523,6 @@ static void increase_modlist(void);
|
|||
|
||||
static char unknown_ver[] = "<unknown>";
|
||||
|
||||
/* This file contains the core functions to use dynamic libraries.
|
||||
* -TimeMr14C
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_MACH_O_DYLD_H
|
||||
/*
|
||||
** jmallett's dl*(3) shims for NSModule(3) systems.
|
||||
*/
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
#ifndef HAVE_DLOPEN
|
||||
#ifndef RTLD_LAZY
|
||||
#define RTLD_LAZY 2185 /* built-in dl*(3) don't care */
|
||||
#endif
|
||||
|
||||
void undefinedErrorHandler(const char *);
|
||||
NSModule multipleErrorHandler(NSSymbol, NSModule, NSModule);
|
||||
void linkEditErrorHandler(NSLinkEditErrors, int, const char *, const char *);
|
||||
char *dlerror(void);
|
||||
void *dlopen(char *, int);
|
||||
int dlclose(void *);
|
||||
void *dlsym(void *, char *);
|
||||
|
||||
static int firstLoad = TRUE;
|
||||
static int myDlError;
|
||||
static char *myErrorTable[] = { "Loading file as object failed\n",
|
||||
"Loading file as object succeeded\n",
|
||||
"Not a valid shared object\n",
|
||||
"Architecture of object invalid on this architecture\n",
|
||||
"Invalid or corrupt image\n",
|
||||
"Could not access object\n",
|
||||
"NSCreateObjectFileImageFromFile failed\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
undefinedErrorHandler(const char *symbolName)
|
||||
{
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Undefined symbol: %s", symbolName);
|
||||
ilog(L_MAIN, "Undefined symbol: %s", symbolName);
|
||||
return;
|
||||
}
|
||||
|
||||
NSModule
|
||||
multipleErrorHandler(NSSymbol s, NSModule old, NSModule new)
|
||||
{
|
||||
/* XXX
|
||||
** This results in substantial leaking of memory... Should free one
|
||||
** module, maybe?
|
||||
*/
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
"Symbol `%s' found in `%s' and `%s'",
|
||||
NSNameOfSymbol(s), NSNameOfModule(old), NSNameOfModule(new));
|
||||
ilog(L_MAIN, "Symbol `%s' found in `%s' and `%s'",
|
||||
NSNameOfSymbol(s), NSNameOfModule(old), NSNameOfModule(new));
|
||||
/* We return which module should be considered valid, I believe */
|
||||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
linkEditErrorHandler(NSLinkEditErrors errorClass, int errnum,
|
||||
const char *fileName, const char *errorString)
|
||||
{
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
"Link editor error: %s for %s", errorString, fileName);
|
||||
ilog(L_MAIN, "Link editor error: %s for %s", errorString, fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
char *
|
||||
dlerror(void)
|
||||
{
|
||||
return myDlError == NSObjectFileImageSuccess ? NULL : myErrorTable[myDlError % 7];
|
||||
}
|
||||
|
||||
void *
|
||||
dlopen(char *filename, int unused)
|
||||
{
|
||||
NSObjectFileImage myImage;
|
||||
NSModule myModule;
|
||||
|
||||
if(firstLoad)
|
||||
{
|
||||
/*
|
||||
** If we are loading our first symbol (huzzah!) we should go ahead
|
||||
** and install link editor error handling!
|
||||
*/
|
||||
NSLinkEditErrorHandlers linkEditorErrorHandlers;
|
||||
|
||||
linkEditorErrorHandlers.undefined = undefinedErrorHandler;
|
||||
linkEditorErrorHandlers.multiple = multipleErrorHandler;
|
||||
linkEditorErrorHandlers.linkEdit = linkEditErrorHandler;
|
||||
NSInstallLinkEditErrorHandlers(&linkEditorErrorHandlers);
|
||||
firstLoad = FALSE;
|
||||
}
|
||||
myDlError = NSCreateObjectFileImageFromFile(filename, &myImage);
|
||||
if(myDlError != NSObjectFileImageSuccess)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
myModule = NSLinkModule(myImage, filename, NSLINKMODULE_OPTION_PRIVATE);
|
||||
return (void *) myModule;
|
||||
}
|
||||
|
||||
int
|
||||
dlclose(void *myModule)
|
||||
{
|
||||
NSUnLinkModule(myModule, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
dlsym(void *myModule, char *mySymbolName)
|
||||
{
|
||||
NSSymbol mySymbol;
|
||||
|
||||
mySymbol = NSLookupSymbolInModule((NSModule) myModule, mySymbolName);
|
||||
return NSAddressOfSymbol(mySymbol);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* HPUX dl compat functions
|
||||
*/
|
||||
#if defined(HAVE_SHL_LOAD) && !defined(HAVE_DLOPEN)
|
||||
#define RTLD_LAZY BIND_DEFERRED
|
||||
#define RTLD_GLOBAL DYNAMIC_PATH
|
||||
#define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0)
|
||||
#define dlclose(handle) shl_unload((shl_t)(handle))
|
||||
#define dlsym(handle,name) hpux_dlsym(handle,name)
|
||||
#define dlerror() strerror(errno)
|
||||
|
||||
static void *
|
||||
hpux_dlsym(void *handle, char *name)
|
||||
{
|
||||
void *sym_addr;
|
||||
if(!shl_findsym((shl_t *) & handle, name, TYPE_UNDEFINED, &sym_addr))
|
||||
return sym_addr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* unload_one_module()
|
||||
*
|
||||
* inputs - name of module to unload
|
||||
|
@ -722,7 +584,7 @@ unload_one_module(const char *name, int warn)
|
|||
break;
|
||||
}
|
||||
|
||||
dlclose(modlist[modindex]->address);
|
||||
lt_dlclose(modlist[modindex]->address);
|
||||
|
||||
rb_free(modlist[modindex]->name);
|
||||
memmove(&modlist[modindex], &modlist[modindex + 1],
|
||||
|
@ -751,8 +613,7 @@ unload_one_module(const char *name, int warn)
|
|||
int
|
||||
load_a_module(const char *path, int warn, int core)
|
||||
{
|
||||
void *tmpptr = NULL;
|
||||
|
||||
lt_dlhandle tmpptr;
|
||||
char *mod_basename;
|
||||
const char *ver;
|
||||
|
||||
|
@ -760,15 +621,11 @@ load_a_module(const char *path, int warn, int core)
|
|||
|
||||
mod_basename = rb_basename(path);
|
||||
|
||||
#ifdef CHARYBDIS_PROFILE
|
||||
tmpptr = dlopen(path, RTLD_NOW | RTLD_LOCAL | RTLD_PROFILE);
|
||||
#else
|
||||
tmpptr = dlopen(path, RTLD_NOW | RTLD_LOCAL);
|
||||
#endif
|
||||
tmpptr = lt_dlopen(path);
|
||||
|
||||
if(tmpptr == NULL)
|
||||
{
|
||||
const char *err = dlerror();
|
||||
const char *err = lt_dlerror();
|
||||
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
"Error loading module %s: %s", mod_basename, err);
|
||||
|
@ -784,16 +641,16 @@ load_a_module(const char *path, int warn, int core)
|
|||
* as a single int in order to determine the API version.
|
||||
* -larne.
|
||||
*/
|
||||
mapi_version = (int *) (uintptr_t) dlsym(tmpptr, "_mheader");
|
||||
mapi_version = (int *) (uintptr_t) lt_dlsym(tmpptr, "_mheader");
|
||||
if((mapi_version == NULL
|
||||
&& (mapi_version = (int *) (uintptr_t) dlsym(tmpptr, "__mheader")) == NULL)
|
||||
&& (mapi_version = (int *) (uintptr_t) lt_dlsym(tmpptr, "__mheader")) == NULL)
|
||||
|| MAPI_MAGIC(*mapi_version) != MAPI_MAGIC_HDR)
|
||||
{
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
"Data format error: module %s has no MAPI header.",
|
||||
mod_basename);
|
||||
ilog(L_MAIN, "Data format error: module %s has no MAPI header.", mod_basename);
|
||||
(void) dlclose(tmpptr);
|
||||
(void) lt_dlclose(tmpptr);
|
||||
rb_free(mod_basename);
|
||||
return -1;
|
||||
}
|
||||
|
@ -810,7 +667,7 @@ load_a_module(const char *path, int warn, int core)
|
|||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
"Module %s indicated failure during load.",
|
||||
mod_basename);
|
||||
dlclose(tmpptr);
|
||||
lt_dlclose(tmpptr);
|
||||
rb_free(mod_basename);
|
||||
return -1;
|
||||
}
|
||||
|
@ -845,7 +702,7 @@ load_a_module(const char *path, int warn, int core)
|
|||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||
"Module %s has unknown/unsupported MAPI version %d.",
|
||||
mod_basename, *mapi_version);
|
||||
dlclose(tmpptr);
|
||||
lt_dlclose(tmpptr);
|
||||
rb_free(mod_basename);
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue