modules: use libltdl to load the modules

This commit is contained in:
William Pitcock 2016-01-05 21:39:09 -06:00
parent bc38c72ced
commit f272e7abc7
2 changed files with 19 additions and 167 deletions

View File

@ -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> */

View File

@ -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;
}