mod_raw.cc
Go to the documentation of this file.
1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /*
5  * ABSTRACT: machine depend code for dynamic modules
6  *
7  * Provides: dynl_check_opened()
8  * 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 #include <errno.h>
19 #include <unistd.h>
20 
21 #include "misc/auxiliary.h"
22 #include "reporter/reporter.h"
23 #include "resources/feResource.h"
24 #include "omalloc/omalloc.h"
25 #include "mod_raw.h"
26 
27 #ifdef HAVE_STATIC
28 #undef HAVE_DL
29 #endif
30 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
31 #if defined(HAVE_DL)
32 
33 /*****************************************************************************
34  *
35  * General section
36  * These are just wrappers around the repsective dynl_* calls
37  * which look for the binary in the bin_dir of Singular and ommit warnings if
38  * somethings goes wrong
39  *
40  *****************************************************************************/
43 #ifndef DL_TAIL
44 #define DL_TAIL ".so"
45 //#define DL_TAIL "_g.so"
46 #endif
47 
48 void* dynl_open_binary_warn(const char* binary_name, const char* msg)
49 {
50  void* handle = NULL;
51  char* binary_name_so=NULL;
53 
54  // try P_PROCS_DIR (%P)
55  char* proc_path = feGetResource('P');
56  if (proc_path != NULL)
57  {
58  char *p;
59  char *q;
60  p=proc_path;
61  int binary_name_so_length = 3 + strlen(DL_TAIL) + strlen(binary_name) + strlen(DIR_SEPP) + strlen(proc_path);
62  binary_name_so = (char *)omAlloc0( binary_name_so_length * sizeof(char) );
63  while((p!=NULL)&&(*p!='\0'))
64  {
65  q=strchr(p,fePathSep);
66  if (q!=NULL) *q='\0';
67  strcpy(binary_name_so,p);
68  if (q!=NULL) *q=fePathSep;
69  strcat(binary_name_so,DIR_SEPP);
70  strcat(binary_name_so,binary_name);
71  strcat(binary_name_so,DL_TAIL);
72  if(!access(binary_name_so, R_OK)) { found=TRUE; break; }
73  if (q!=NULL) p=q+1; else p=NULL;
74  }
75  if (found) handle = dynl_open(binary_name_so);
76  }
77 
78  if (handle == NULL && ! warn_handle)
79  {
80  Warn("Could not find dynamic library: %s%s (path %s)",
81  binary_name, DL_TAIL,proc_path);
82  if (found) Warn("Error message from system: %s", dynl_error());
83  if (msg != NULL) Warn("%s", msg);
84  WarnS("See the INSTALL section in the Singular manual for details.");
85  warn_handle = TRUE;
86  }
87  omfree((ADDRESS)binary_name_so );
88 
89  return handle;
90 }
91 
92 void* dynl_sym_warn(void* handle, const char* proc, const char* msg)
93 {
94  void *proc_ptr = NULL;
95  if (handle != NULL)
96  {
97  proc_ptr = dynl_sym(handle, proc);
98  if (proc_ptr == NULL && ! warn_proc)
99  {
100  WarnS("Could load a procedure from a dynamic library");
101  Warn("Error message from system: %s", dynl_error());
102  if (msg != NULL) Warn("%s", msg);
103  WarnS("See the INSTALL section in the Singular manual for details.");
104  warn_proc = TRUE;
105  }
106  }
107  return proc_ptr;
108 }
109 
110 #ifdef __cplusplus
111 extern "C" {
112 #endif
113 
114 /*****************************************************************************
115  * SECTION generic ELF: ix86-linux / alpha-linux / IA64-linux /x86_64_Linux *
116  * SunOS-5 / IRIX-6 / ppcMac-Darwin / FreeeBSD *
117  *****************************************************************************/
118 // relying on gcc to define __ELF__, check with cpp -dM /dev/null
119 #if defined(__ELF__)
120 #define HAVE_ELF_SYSTEM
121 #endif
122 
123 // Mac OsX is an ELF system, but does not define __ELF__
124 #if (defined(__APPLE__) && defined(__MACH__)) && (!defined(HAVE_ELF_SYSTEM))
125 #define HAVE_ELF_SYSTEM
126 #endif
127 
128 // Solaris is an ELF system, but does not define __ELF__
129 #if defined(__sun) && defined(__SVR4)
130 #define HAVE_ELF_SYSTEM
131 #endif
132 
133 #if defined(HAVE_ELF_SYSTEM)
134 #include <dlfcn.h>
135 #define DL_IMPLEMENTED
136 
139  char *filename /* I: filename to check */
140  )
141 {
142  return dlopen(filename,RTLD_NOW|RTLD_NOLOAD) != NULL;
143 }
144 
145 void *dynl_open(
146  char *filename /* I: filename to load */
147  )
148 {
149  return dlopen(filename, RTLD_NOW|RTLD_GLOBAL);
150 #if 0
151 // glibc 2.2:
152  if ((filename==NULL) || (dlopen(filename,RTLD_NOW|RTLD_NOLOAD)==NULL))
153  return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
154  else
155  Werror("module %s already loaded",filename);
156  return NULL;
157 // alternative
158 // return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
159 #endif
160 }
161 
162 void *dynl_sym(void *handle, const char *symbol)
163 {
164  if (handle == DYNL_KERNEL_HANDLE)
165  {
166  if (kernel_handle == NULL)
167  kernel_handle = dynl_open(NULL);
168  handle = kernel_handle;
169  }
170  return(dlsym(handle, symbol));
171 }
172 
173 int dynl_close (void *handle)
174 {
175  return(dlclose (handle));
176 }
177 
178 const char *dynl_error()
179 {
180  return(dlerror());
181 }
182 #endif /* ELF_SYSTEM */
183 
184 /*****************************************************************************
185  * SECTION HPUX-9/10 *
186  *****************************************************************************/
187 #if defined(HPUX_9) || defined(HPUX_10)
188 #define DL_IMPLEMENTED
189 #include <dl.h>
190 
191 typedef char *((*func_ptr) ());
192 
193 int dynl_check_opened( /* NOTE: untested */
194  char *filename /* I: filename to check */
195  )
196 {
197  struct shl_descriptor *desc;
198  for (int idx = 0; shl_get(idx, &desc) != -1; ++idx)
199  {
200  if (strcmp(filename, desc->filename) == 0) return TRUE;
201  }
202  return FALSE;
203 }
204 
205 void *dynl_open(char *filename)
206 {
207  shl_t handle = shl_load(filename, BIND_DEFERRED, 0);
208 
209  return ((void *) handle);
210 }
211 
212 void *dynl_sym(void *handle, const char *symbol)
213 {
214  func_ptr f;
215 
216  if (handle == DYNL_KERNEL_HANDLE)
217  handle = PROG_HANDLE;
218 
219  if (shl_findsym((shl_t *) & handle, symbol, TYPE_PROCEDURE, &f) == -1)
220  {
221  if (shl_findsym((shl_t *) & handle, symbol, TYPE_UNDEFINED, &f) == -1)
222  {
223  f = (func_ptr) NULL;
224  }
225  }
226  return ((void *)f);
227 }
228 
229 int dynl_close (void *handle)
230 {
231  shl_unload((shl_t) handle);
232  return(0);
233 }
234 
235 const char *dynl_error()
236 {
237  STATIC_VAR char errmsg[] = "shl_load failed";
238 
239  return errmsg;
240 }
241 #endif /* HPUX_9 or HPUX_10 */
242 
243 /*****************************************************************************
244  * SECTION generic: dynamic madules not available
245  *****************************************************************************/
246 #ifndef DL_IMPLEMENTED
247 
248 int dynl_check_opened(char *filename)
249 {
250  return FALSE;
251 }
252 
253 void *dynl_open(char *filename)
254 {
255  return(NULL);
256 }
257 
258 void *dynl_sym(void *handle, const char *symbol)
259 {
260  return(NULL);
261 }
262 
263 int dynl_close (void *handle)
264 {
265  return(0);
266 }
267 
268 const char *dynl_error()
269 {
270  STATIC_VAR char errmsg[] = "support for dynamic loading not implemented";
271  return errmsg;
272 }
273 #endif
274 
275 #ifdef __cplusplus
276 }
277 #endif
278 
279 #endif /* HAVE_DL */
unsigned char * proc[NUM_PROC]
Definition: checklibs.c:16
#define DL_TAIL
Definition: mod_raw.cc:44
void * dynl_open_binary_warn(const char *binary_name, const char *msg)
Definition: mod_raw.cc:48
#define FALSE
Definition: auxiliary.h:96
#define TRUE
Definition: auxiliary.h:100
void * ADDRESS
Definition: auxiliary.h:135
void * dynl_sym(void *handle, const char *symbol)
Definition: mod_raw.cc:162
const char fePathSep
Definition: feResource.h:58
#define WarnS
Definition: emacs.cc:78
STATIC_VAR BOOLEAN warn_handle
Definition: mod_raw.cc:41
void * dynl_open(char *filename)
Definition: mod_raw.cc:145
void * dynl_sym_warn(void *handle, const char *proc, const char *msg)
Definition: mod_raw.cc:92
bool found
Definition: facFactorize.cc:56
int dynl_check_opened(char *filename)
Definition: mod_raw.cc:138
char * feGetResource(const char id, int warn)
Definition: feResource.cc:155
#define omfree(addr)
Definition: omAllocDecl.h:237
STATIC_VAR void * kernel_handle
Definition: mod_raw.cc:137
All the auxiliary stuff.
#define STATIC_VAR
Definition: globaldefs.h:7
#define DIR_SEPP
Definition: feResource.h:7
FILE * f
Definition: checklibs.c:9
int dynl_close(void *handle)
Definition: mod_raw.cc:173
#define NULL
Definition: omList.c:12
STATIC_VAR BOOLEAN warn_proc
Definition: mod_raw.cc:42
#define DYNL_KERNEL_HANDLE
Definition: mod_raw.h:32
int p
Definition: cfModGcd.cc:4019
int BOOLEAN
Definition: auxiliary.h:87
void Werror(const char *fmt,...)
Definition: reporter.cc:189
#define omAlloc0(size)
Definition: omAllocDecl.h:211
const char * dynl_error()
Definition: mod_raw.cc:178
#define Warn
Definition: emacs.cc:77