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