ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/src/dynlink.c
(Generate patch)

Comparing ircd-hybrid-7.2/src/dynlink.c (file contents):
Revision 911 by stu, Sun Nov 4 23:21:51 2007 UTC vs.
Revision 912 by michael, Wed Nov 7 22:47:44 2007 UTC

# Line 22 | Line 22
22   * $Id$
23   *
24   */
25 +
26 + #include "ltdl.h"
27 +
28   #include "stdinc.h"
29   #include "tools.h"
30   #include "irc_string.h"
# Line 30 | Line 33
33   #include "client.h"
34   #include "send.h"
35  
33 #ifndef RTLD_NOW
34 #define RTLD_NOW RTLD_LAZY /* openbsd deficiency */
35 #endif
36
37 #if defined(HAVE_DLINFO) && defined(HAVE_LINK_H)
38 # include <link.h>
39 #endif
40
41 #if USE_SHARED_MODULES
42
36   extern dlink_list mod_list;
37  
38   static char unknown_ver[] = "<unknown>";
# Line 48 | Line 41 | static char unknown_ver[] = "<unknown>";
41   * -TimeMr14C
42   */
43  
51 #if !defined(HAVE_SHL_LOAD) && !defined(HAVE_DLFUNC)
52 /*
53 * Fake dlfunc(3) if we don't have it, cause it's happy.
54 */
55 typedef void (*__function_p)(void);
56
57 static __function_p
58 dlfunc(void *myHandle, const char *functionName)
59 {
60  /* XXX This is not guaranteed to work, but with
61   * traditional dl*(3), it is the best we can do.
62   * -jmallett
63   */
64  void *symbolp;
65
66  symbolp = dlsym(myHandle, functionName);
67  return((__function_p)(uintptr_t)symbolp);
68 }
69 #endif
70
71 #ifdef HAVE_MACH_O_DYLD_H
72 /*
73 ** jmallett's dl*(3) shims for NSModule(3) systems.
74 */
75 #include <mach-o/dyld.h>
76
77 #ifndef HAVE_DLOPEN
78 #ifndef RTLD_LAZY
79 #define RTLD_LAZY 2185 /* built-in dl*(3) don't care */
80 #endif
81
82 void undefinedErrorHandler(const char *);
83 NSModule multipleErrorHandler(NSSymbol, NSModule, NSModule);
84 void linkEditErrorHandler(NSLinkEditErrors, int, const char *, const char *);
85 char *dlerror(void);
86 void *dlopen(char *, int);
87 int dlclose(void *);
88 void *dlsym(void *, char *);
89
90 static int firstLoad = TRUE;
91 static int myDlError;
92 static const char *myErrorTable[] =
93 {
94  "Loading file as object failed\n",
95  "Loading file as object succeeded\n",
96  "Not a valid shared object\n",
97  "Architecture of object invalid on this architecture\n",
98  "Invalid or corrupt image\n",
99  "Could not access object\n",
100  "NSCreateObjectFileImageFromFile failed\n",
101  NULL
102 };
103
104 void
105 undefinedErrorHandler(const char *symbolName)
106 {
107  sendto_realops_flags(UMODE_ALL, L_ALL, "Undefined symbol: %s", symbolName);
108  ilog(L_WARN, "Undefined symbol: %s", symbolName);
109  return;
110 }
111
112 NSModule
113 multipleErrorHandler(NSSymbol s, NSModule old, NSModule new)
114 {
115  /* XXX
116  ** This results in substantial leaking of memory... Should free one
117  ** module, maybe?
118  */
119  sendto_realops_flags(UMODE_ALL, L_ALL, "Symbol `%s' found in `%s' and `%s'",
120                       NSNameOfSymbol(s), NSNameOfModule(old), NSNameOfModule(new));
121  ilog(L_WARN, "Symbol `%s' found in `%s' and `%s'", NSNameOfSymbol(s),
122       NSNameOfModule(old), NSNameOfModule(new));
123  /* We return which module should be considered valid, I believe */
124  return(new);
125 }
126
44   void
45 < linkEditErrorHandler(NSLinkEditErrors errorClass, int errnum,
129 <                     const char *fileName, const char *errorString)
130 < {
131 <  sendto_realops_flags(UMODE_ALL, L_ALL, "Link editor error: %s for %s",
132 <                       errorString, fileName);
133 <  ilog(L_WARN, "Link editor error: %s for %s", errorString, fileName);
134 <  return;
135 < }
136 <
137 < char *
138 < dlerror(void)
139 < {
140 <  return(myDlError == NSObjectFileImageSuccess ? NULL : myErrorTable[myDlError % 7]);
141 < }
142 <
143 < void *
144 < dlopen(char *filename, int unused)
45 > dynlink_init(void)
46   {
47 <  NSObjectFileImage myImage;
48 <  NSModule myModule;
49 <
50 <  if (firstLoad)
150 <  {
151 <    /* If we are loading our first symbol (huzzah!) we should go ahead
152 <     * and install link editor error handling!
153 <     */
154 <    NSLinkEditErrorHandlers linkEditorErrorHandlers;
155 <
156 <    linkEditorErrorHandlers.undefined = undefinedErrorHandler;
157 <    linkEditorErrorHandlers.multiple  = multipleErrorHandler;
158 <    linkEditorErrorHandlers.linkEdit  = linkEditErrorHandler;
159 <    NSInstallLinkEditErrorHandlers(&linkEditorErrorHandlers);
160 <    firstLoad = FALSE;
47 >  if (lt_dlinit()) {
48 >    ilog(L_ERROR, "Couldn't initialize the libltdl run time dynamic"
49 >         " link library. Exiting.");
50 >    exit(0);
51    }
162
163  myDlError = NSCreateObjectFileImageFromFile(filename, &myImage);
164
165  if (myDlError != NSObjectFileImageSuccess)
166    return(NULL);
167
168  myModule = NSLinkModule(myImage, filename, NSLINKMODULE_OPTION_PRIVATE);
169  return((void *)myModule);
52   }
53  
54   int
55 < dlclose(void *myModule)
55 > modules_valid_suffix(const char *name)
56   {
57 <  NSUnLinkModule(myModule, FALSE);
176 <  return(0);
57 >  return ((name = strrchr(name, '.'))) && !strcmp(name, ".la");
58   }
59  
179 void *
180 dlsym(void *myModule, char *mySymbolName)
181 {
182  NSSymbol mySymbol;
183
184  mySymbol = NSLookupSymbolInModule((NSModule)myModule, mySymbolName);
185  return NSAddressOfSymbol(mySymbol);
186 }
187 #endif
188 #endif
189
60   /* unload_one_module()
61   *
62   * inputs       - name of module to unload
# Line 206 | Line 76 | unload_one_module(char *name, int warn)
76    modp = ptr->data;
77  
78    if (modp->modremove)
79 <    (*modp->modremove)();
79 >   modp->modremove();
80 >
81 >  lt_dlclose(modp->handle);
82  
211 #ifdef HAVE_SHL_LOAD
212    /* shl_* and friends have a slightly different format than dl*. But it does not
213     * require creation of a totally new modules.c, instead proper usage of
214     * defines solve this case. -TimeMr14C
215     */
216  shl_unload((shl_t) & (modp->handle));
217 #else
218  /* We use FreeBSD's dlfunc(3) interface, or fake it as we
219   * used to here if it isn't there.  The interface should
220   * be standardised some day, and so it eventually will be
221   * providing something guaranteed to do the right thing here.
222   *          -jmallett
223   */
224  dlclose(modp->handle);
225 #endif
83    assert(dlink_list_length(&mod_list) > 0);
84    dlinkDelete(ptr, &mod_list);
85    MyFree(modp->name);
# Line 246 | Line 103 | unload_one_module(char *name, int warn)
103   int
104   load_a_module(char *path, int warn, int core)
105   {
106 < #ifdef HAVE_DLINFO
250 <  struct link_map *map;
251 < #endif
252 < #ifdef HAVE_SHL_LOAD
253 <  shl_t tmpptr;
254 < #else
255 <  void *tmpptr = NULL;
256 < #endif
257 <  void *addr = NULL;
106 >  lt_dlhandle tmpptr = NULL;
107    char *mod_basename;
259  void (*initfunc)(void) = NULL;
260  void (*mod_deinit)(void) = NULL;
108    char **verp;
109    char *ver;
110    struct module *modp;
111 +  void (*mod_init)(void) = NULL;
112 +  void (*mod_deinit)(void) = NULL;
113  
114    mod_basename = basename(path);
115  
116    if (findmodule_byname(mod_basename) != NULL)
117 <    return(1);
117 >    return 1;
118  
119 < #ifdef HAVE_SHL_LOAD
120 <  tmpptr = shl_load(path, BIND_IMMEDIATE, NULL);
272 < #else
273 <  tmpptr = dlopen(path, RTLD_NOW);
274 < #endif
119 >  if (!(tmpptr = lt_dlopen(path))) {
120 >    const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
121  
276  if (tmpptr == NULL)
277  {
278 #ifdef HAVE_SHL_LOAD
279    const char *err = strerror(errno);
280 #else
281    const char *err = dlerror();
282 #endif
122      sendto_realops_flags(UMODE_ALL, L_ALL, "Error loading module %s: %s",
123                           mod_basename, err);
124      ilog(L_WARN, "Error loading module %s: %s", mod_basename, err);
125 <    
287 <    return(-1);
288 <  }
289 <
290 < #ifdef HAVE_SHL_LOAD
291 <  if (shl_findsym(&tmpptr, "_modinit", TYPE_UNDEFINED, (void *)&initfunc) == -1)
292 <  {
293 <    if (shl_findsym(&tmpptr, "__modinit", TYPE_UNDEFINED, (void *)&initfunc) == -1)
294 <    {
295 <      ilog(L_WARN, "Module %s has no _modinit() function", mod_basename);
296 <      sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s has no _modinit() function",
297 <                           mod_basename);
298 <      shl_unload(tmpptr);
299 <      return(-1);
300 <    }
301 <  }
302 <
303 <  if (shl_findsym(&tmpptr, "_moddeinit", TYPE_UNDEFINED, (void *)&mod_deinit) == -1)
304 <  {
305 <    if (shl_findsym(&tmpptr, "__moddeinit", TYPE_UNDEFINED, (void *)&mod_deinit) == -1)
306 <    {
307 <      ilog(L_WARN, "Module %s has no _moddeinit() function", mod_basename);
308 <      sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s has no _moddeinit() function",
309 <                           mod_basename);
310 <      /* this is a soft error.  we're allowed not to have one, i guess.
311 <       * (judging by the code in unload_one_module() */
312 <      mod_deinit = NULL;
313 <    }
125 >    return -1;
126    }
127  
128 <  if (shl_findsym(&tmpptr, "_version", TYPE_UNDEFINED, &verp) == -1)
317 <  {
318 <    if (shl_findsym(&tmpptr, "__version", TYPE_UNDEFINED, &verp) == -1)
319 <      ver = unknown_ver;
320 <    else
321 <      ver = *verp;
322 <  }
323 <  else
324 <    ver = *verp;
325 < #else
326 <  if ((initfunc = (void(*)(void))dlfunc(tmpptr, "_modinit")) == NULL &&
327 <      /* Only for compatibility, because some systems have underscore
328 <       * prepended symbol names */
329 <      (initfunc = (void(*)(void))dlfunc(tmpptr, "__modinit")) == NULL)
128 >  if ((mod_init = lt_dlsym(tmpptr, "_modinit")) == NULL)
129    {
130      sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s has no _modinit() function",
131                           mod_basename);
132      ilog(L_WARN, "Module %s has no _modinit() function", mod_basename);
133 <    dlclose(tmpptr);
134 <    return(-1);
133 >    lt_dlclose(tmpptr);
134 >    return -1;
135    }
136  
137 <  mod_deinit = (void(*)(void))dlfunc(tmpptr, "_moddeinit");
339 <
340 <  if (mod_deinit == NULL && (mod_deinit = (void(*)(void))dlfunc(tmpptr, "__moddeinit")) == NULL)
137 >  if ((mod_deinit = lt_dlsym(tmpptr, "_moddeinit")) == NULL)
138    {
139      sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s has no _moddeinit() function",
140                           mod_basename);
141      ilog(L_WARN, "Module %s has no _moddeinit() function", mod_basename);
142      /* blah blah soft error, see above. */
346    mod_deinit = NULL;
143    }
144  
145 <  verp = (char **)dlsym(tmpptr, "_version");
350 <
351 <  if (verp == NULL && (verp = (char **)dlsym(tmpptr, "__version")) == NULL)
145 >  if ((verp = lt_dlsym(tmpptr, "_version")) == NULL)
146      ver = unknown_ver;
147    else
148      ver = *verp;
355 #endif
149  
150    modp            = MyMalloc(sizeof(struct module));
358 #ifdef HAVE_DLINFO
359  dlinfo(tmpptr, RTLD_DI_LINKMAP, &map);
360  if (map != NULL)
361    addr = (void *)map->l_addr;
362  else
363 #endif
364    addr = tmpptr;
365
151    modp->handle    = tmpptr;
367  modp->address   = addr;
152    modp->version   = ver;
153    modp->core      = core;
154    modp->modremove = mod_deinit;
# Line 372 | Line 156 | load_a_module(char *path, int warn, int
156    DupString(modp->name, mod_basename);
157    dlinkAdd(modp, &modp->node, &mod_list);
158  
159 <  initfunc();
159 >  mod_init();
160  
161    if (warn == 1)
162    {
163      sendto_realops_flags(UMODE_ALL, L_ALL,
164 <                         "Module %s [version: %s] loaded at %p",
165 <                         mod_basename, ver, addr);
166 <    ilog(L_WARN, "Module %s [version: %s] loaded at %p",
167 <         mod_basename, ver, addr);
164 >                         "Module %s [version: %s handle: %p] loaded.",
165 >                         mod_basename, ver, tmpptr);
166 >    ilog(L_WARN, "Module %s [version: %s handle: %p] loaded.",
167 >         mod_basename, ver, tmpptr);
168    }
169  
170 <  return(0);
170 >  return 0;
171   }
388 #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines