source: git/libpolys/polys/mod_raw.cc @ f4399e

spielwiese
Last change on this file since f4399e was f4399e, checked in by Alexander Dreyer <adreyer@…>, 11 years ago
fix: reloading of modules (multiply calling LIB("file.so")) is ignored add: dynl_check_opened newly introduced
  • Property mode set to 100644
File size: 9.1 KB
RevLine 
[35aab3]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5 * ABSTRACT: machine depend code for dynamic modules
6 *
[f4399e]7 * Provides: dynl_check_opened()
8 *           dynl_open()
[35aab3]9 *           dynl_sym()
10 *           dynl_error()
[4c7d73]11 *           dynl_close()
[35aab3]12*/
13
14#include <stdio.h>
[9ed245]15#include <string.h>
16#include <ctype.h>
17#include <sys/stat.h>
18
[35aab3]19
[8c9912]20#include "config.h"
21#include <misc/auxiliary.h>
[35aab3]22
[f9dc520]23#include <omalloc/omalloc.h>
[8c9912]24
25#include <reporter/reporter.h>
26
[f323dd1]27#include <findexec/feResource.h>
[8c9912]28
[fad7c58]29#include "mod_raw.h"
[35aab3]30
[abaf13]31#ifdef HAVE_STATIC
32#undef HAVE_DL
33#endif
[9ed245]34/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
35#define BYTES_TO_CHECK 7
36
[57dcd6]37#define SI_BUILTIN_LIBSTR(name) (char*) #name ".so",
38
39char* si_bultin_libs[]={ SI_FOREACH_BUILTIN(SI_BUILTIN_LIBSTR)  NULL };
40
41#undef SI_BUILTIN_LIBSTR
[801d2b]42
[9ed245]43lib_types type_of_LIB(char *newlib, char *libnamebuf)
44{
[7dce2d7]45  const unsigned char mach_o[]={0xfe,0xed,0xfa,0xce,0};
[05b917]46  const unsigned char mach_O[]={0xce,0xfa,0xed,0xfe,0};
[6e81fc]47   
48  const unsigned char mach_o64[]={0xfe,0xed,0xfa,0xcf,0};
49  const unsigned char mach_O64[]={0xcf,0xfa,0xed,0xfe,0};
50   
[801d2b]51  int i=0;
52  while(si_bultin_libs[i]!=NULL)
53  {
54    if (strcmp(newlib,si_bultin_libs[i])==0)
55    {
56      if(libnamebuf!=NULL) strcpy(libnamebuf,newlib);
57      return LT_BUILTIN;
58    }
59    i++;
60  }
[9ed245]61  char        buf[BYTES_TO_CHECK+1];        /* one extra for terminating '\0' */
62  struct stat sb;
63  int nbytes = 0;
64  int ret;
65  lib_types LT=LT_NONE;
66
67  FILE * fp = feFopen( newlib, "r", libnamebuf, FALSE );
68  ret = stat(libnamebuf, &sb);
69
70  if (fp==NULL)
71  {
72    return LT_NOTFOUND;
73  }
74  if((sb.st_mode & S_IFMT) != S_IFREG)
75  {
76    goto lib_type_end;
77  }
78  if ((nbytes = fread((char *)buf, sizeof(char), BYTES_TO_CHECK, fp)) == -1)
79  {
80    goto lib_type_end;
81    /*NOTREACHED*/
82  }
83  if (nbytes == 0)
84    goto lib_type_end;
85  else
86  {
87    buf[nbytes++] = '\0';        /* null-terminate it */
88  }
89  if( (strncmp(buf, "\177ELF", 4)==0)) /* generic ELF */
90  {
91    LT = LT_ELF;
92    //omFree(newlib);
93    //newlib = omStrDup(libnamebuf);
94    goto lib_type_end;
95  }
[1ea9a7]96
[05b917]97  if( (strncmp(buf, (const char *)mach_o, 4)==0) || (strncmp(buf, (const char *)mach_O, 4)==0)) /* generic Mach-O module */
[1ea9a7]98  {
99    LT = LT_MACH_O;
100    //omFree(newlib);
101    //newlib = omStrDup(libnamebuf);
102    goto lib_type_end;
103  }
[27fc50]104
[6e81fc]105  if( (strncmp(buf, (const char *)mach_o64, 4)==0) || (strncmp(buf, (const char *)mach_O64, 4)==0)) /* generic Mach-O 64-bit module */
[27fc50]106  {
107    LT = LT_MACH_O;
108    //omFree(newlib);
109    //newlib = omStrDup(libnamebuf);
110    goto lib_type_end;
111  }
[801d2b]112
113
[9ed245]114  if( (strncmp(buf, "\02\020\01\016\05\022@", 7)==0))
115  {
116    LT = LT_HPUX;
117    //omFree(newlib);
118    //newlib = omStrDup(libnamebuf);
119    goto lib_type_end;
120  }
121  if(isprint(buf[0]) || buf[0]=='\n')
122  { LT = LT_SINGULAR; goto lib_type_end; }
123
124  lib_type_end:
125  fclose(fp);
126  return LT;
127}
128/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
129#if defined(HAVE_DL)
130
[35aab3]131/*****************************************************************************
132 *
133 * General section
[abaf13]134 * These are just wrappers around the repsective dynl_* calls
[35aab3]135 * which look for the binary in the bin_dir of Singular and ommit warnings if
136 * somethings goes wrong
137 *
138 *****************************************************************************/
139static BOOLEAN warn_handle = FALSE;
140static BOOLEAN warn_proc = FALSE;
141#ifndef DL_TAIL
[e71b67]142#ifdef NDEBUG
143#define DL_TAIL ".so"
144#else
145#define DL_TAIL "_g.so"
146#endif
[35aab3]147#endif
148
[9ef9d0]149void* dynl_open_binary_warn(const char* binary_name, const char* msg)
[35aab3]150{
151  void* handle = NULL;
152  const char* bin_dir = feGetResource('b');
153  if (bin_dir != NULL)
154  {
[f9dc520]155    const int binary_name_so_length = 3 + strlen(DL_TAIL) + strlen(binary_name) + strlen(DIR_SEPP) + strlen(bin_dir);
156    char* binary_name_so = (char *)omAlloc0( binary_name_so_length * sizeof(char) );
[e71b67]157    snprintf(binary_name_so, binary_name_so_length, "%s%s%s%s", bin_dir, DIR_SEPP, binary_name, DL_TAIL);
[f9dc520]158    handle = dynl_open(binary_name_so);
159    omFreeSize((ADDRESS)binary_name_so, binary_name_so_length * sizeof(char) );
160  }
161
162  if (handle == NULL )
163  {
164    const int binary_name_so_length = 3 + strlen(DL_TAIL) + strlen(binary_name);
165    char* binary_name_so = (char *)omAlloc0( binary_name_so_length * sizeof(char) );
[e71b67]166    snprintf(binary_name_so, binary_name_so_length, "%s%s", binary_name, DL_TAIL);
[f9dc520]167
168    char* pp = (char *)omAlloc0( MAXPATHLEN * sizeof(char) );
169    lib_types type = type_of_LIB( binary_name_so, pp );
170    omFreeSize((ADDRESS)binary_name_so, binary_name_so_length * sizeof(char) );
171
[05b917]172    if( type != LT_SINGULAR && type != LT_NONE && type != LT_NOTFOUND )
[f9dc520]173      handle = dynl_open(pp);
174
175    omFreeSize((ADDRESS)pp, MAXPATHLEN * sizeof(char) );
176  }
177
178  if (handle == NULL && ! warn_handle)
179  {
[e71b67]180      Warn("Could not find dynamic library: %s%s", binary_name, DL_TAIL);
[35aab3]181      Warn("Error message from system: %s", dynl_error());
182      if (msg != NULL) Warn("%s", msg);
183      Warn("See the INSTALL section in the Singular manual for details.");
184      warn_handle = TRUE;
185  }
[f9dc520]186
[35aab3]187  return  handle;
188}
189
[85e68dd]190void* dynl_sym_warn(void* handle, const char* proc, const char* msg)
[35aab3]191{
192  void *proc_ptr = NULL;
193  if (handle != NULL)
194  {
195    proc_ptr = dynl_sym(handle, proc);
196    if (proc_ptr == NULL && ! warn_proc)
197    {
198      Warn("Could load a procedure from a dynamic library");
199      Warn("Error message from system: %s", dynl_error());
200      if (msg != NULL) Warn("%s", msg);
201      Warn("See the INSTALL section in the Singular manual for details.");
202      warn_proc = TRUE;
203    }
204  }
205  return proc_ptr;
206}
207
208#ifdef __cplusplus
209extern "C" {
210#endif
211
212/*****************************************************************************
[fc300f]213 * SECTION generic ELF: ix86-linux / alpha-linux / IA64-linux /x86_64_Linux  *
[4287a0]214 *                      SunOS-5 / IRIX-6 / ppcMac-Darwin / FreeeBSD          *
[35aab3]215 *****************************************************************************/
[f02645b]216// relying on gcc to define __ELF__, check with cpp -dM /dev/null
[9b3de5]217// Mac OsX is an ELF system, but does not define __ELF__
[c3ab214]218// Solaris is an ELF system, but does not define __ELF__
[d44ced]219#if defined(__ELF__)
[fde597]220#define HAVE_ELF_SYSTEM
[9b3de5]221#endif
222
[0fd6d8]223#if defined(ppcMac_darwin)
224#define HAVE_ELF_SYSTEM
225#endif
226
[801d2b]227#if defined(ix86Mac_darwin)
228#define HAVE_ELF_SYSTEM
229#endif
230
231#if defined(x86_64Mac_darwin)
[d142260]232#define HAVE_ELF_SYSTEM
233#endif
[01d9463]234
[c3ab214]235#if defined(SunOS_5)
236#define HAVE_ELF_SYSTEM
[fde597]237#endif
238
[35aab3]239#if defined(HAVE_ELF_SYSTEM)
240#include <dlfcn.h>
[3dbe0bf]241#define DL_IMPLEMENTED
[35aab3]242
243static void* kernel_handle = NULL;
[f4399e]244int dynl_check_opened(
245  char *filename    /* I: filename to check */
246  )
247{
248  return dlopen(filename,RTLD_NOW|RTLD_NOLOAD) != NULL;
249}
250
[35aab3]251void *dynl_open(
252  char *filename    /* I: filename to load */
253  )
254{
[a513d10]255// glibc 2.2:
[a11e71]256  if ((filename==NULL) || (dlopen(filename,RTLD_NOW|RTLD_NOLOAD)==NULL))
[a513d10]257    return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
258  else
259    Werror("module %s already loaded",filename);
260  return NULL;
[3dbe0bf]261// alternative
[a513d10]262//    return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
[35aab3]263}
264
[85e68dd]265void *dynl_sym(void *handle, const char *symbol)
[35aab3]266{
267  if (handle == DYNL_KERNEL_HANDLE)
268  {
269    if (kernel_handle == NULL)
270      kernel_handle = dynl_open(NULL);
271    handle = kernel_handle;
272  }
273  return(dlsym(handle, symbol));
274}
275
276int dynl_close (void *handle)
277{
278  return(dlclose (handle));
279}
280
281const char *dynl_error()
282{
283  return(dlerror());
284}
[fc300f]285#endif /* ELF_SYSTEM */
[35aab3]286
287/*****************************************************************************
288 * SECTION HPUX-9/10                                                         *
289 *****************************************************************************/
290#if defined(HPUX_9) || defined(HPUX_10)
[3dbe0bf]291#define DL_IMPLEMENTED
[35aab3]292#include <dl.h>
293
294typedef char *((*func_ptr) ());
295
[f4399e]296int dynl_check_opened(    /* NOTE: untested */
297  char *filename    /* I: filename to check */
298  )
299{
300  struct shl_descriptor *desc;
301  for (int idx = 0; shl_get(idx, &desc) != -1; ++idx)
302  {
303    if (strcmp(filename, desc->filename) == 0) return TRUE;
304  }
305  return FALSE;
306}
307
[35aab3]308void *dynl_open(char *filename)
309{
310  shl_t           handle = shl_load(filename, BIND_DEFERRED, 0);
311
312  return ((void *) handle);
313}
314
[85e68dd]315void *dynl_sym(void *handle, const char *symbol)
[35aab3]316{
317  func_ptr        f;
[abaf13]318
[35aab3]319  if (handle == DYNL_KERNEL_HANDLE)
320    handle = PROG_HANDLE;
[abaf13]321
[35aab3]322  if (shl_findsym((shl_t *) & handle, symbol, TYPE_PROCEDURE, &f) == -1)
323  {
324    if (shl_findsym((shl_t *) & handle, symbol, TYPE_UNDEFINED, &f) == -1)
325    {
326      f = (func_ptr) NULL;
327    }
328  }
329  return ((void *)f);
330}
331
332int dynl_close (void *handle)
333{
334  shl_unload((shl_t) handle);
335  return(0);
336}
337
338const char *dynl_error()
339{
340  static char errmsg[] = "shl_load failed";
341
342  return errmsg;
343}
344#endif /* HPUX_9  or HPUX_10 */
345
346/*****************************************************************************
[fc300f]347 * SECTION generic: dynamic madules not available
[35aab3]348 *****************************************************************************/
[3dbe0bf]349#ifndef DL_IMPLEMENTED
[35aab3]350
[f4399e]351int dynl_check_opened(char *filename)
352{
353  return FALSE;
354}
355
[35aab3]356void *dynl_open(char *filename)
357{
358  return(NULL);
359}
360
[85e68dd]361void *dynl_sym(void *handle, const char *symbol)
[35aab3]362{
363  return(NULL);
364}
365
366int dynl_close (void *handle)
367{
368  return(0);
369}
370
371const char *dynl_error()
372{
373  static char errmsg[] = "support for dynamic loading not implemented";
374  return errmsg;
375}
[fc300f]376#endif
[35aab3]377
378#ifdef __cplusplus
379}
380#endif
381
382#endif /* HAVE_DL */
Note: See TracBrowser for help on using the repository browser.