source: git/kernel/mod_raw.cc @ 27fc50

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