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

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