source: git/libpolys/polys/mod_raw.cc @ 801d2b

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