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

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