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

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