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