Ruby  2.1.10p492(2016-04-01revision54464)
dln.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  dln.c -
4 
5  $Author: usa $
6  created at: Tue Jan 18 17:05:06 JST 1994
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 #ifdef RUBY_EXPORT
13 #include "ruby/ruby.h"
14 #define dln_notimplement rb_notimplement
15 #define dln_memerror rb_memerror
16 #define dln_exit rb_exit
17 #define dln_loaderror rb_loaderror
18 #else
19 #define dln_notimplement --->>> dln not implemented <<<---
20 #define dln_memerror abort
21 #define dln_exit exit
22 static void dln_loaderror(const char *format, ...);
23 #endif
24 #include "dln.h"
25 
26 #ifdef HAVE_STDLIB_H
27 # include <stdlib.h>
28 #endif
29 
30 #ifdef USE_DLN_A_OUT
31 char *dln_argv0;
32 #endif
33 
34 #if defined(HAVE_ALLOCA_H)
35 #include <alloca.h>
36 #endif
37 
38 #ifdef HAVE_STRING_H
39 # include <string.h>
40 #else
41 # include <strings.h>
42 #endif
43 
44 #ifndef xmalloc
45 void *xmalloc();
46 void *xcalloc();
47 void *xrealloc();
48 #endif
49 
50 #define free(x) xfree(x)
51 
52 #include <stdio.h>
53 #if defined(_WIN32)
54 #include "missing/file.h"
55 #endif
56 #include <sys/types.h>
57 #include <sys/stat.h>
58 
59 #ifndef S_ISDIR
60 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
61 #endif
62 
63 #ifdef HAVE_SYS_PARAM_H
64 # include <sys/param.h>
65 #endif
66 #ifndef MAXPATHLEN
67 # define MAXPATHLEN 1024
68 #endif
69 
70 #ifdef HAVE_UNISTD_H
71 # include <unistd.h>
72 #endif
73 
74 #ifndef _WIN32
75 char *getenv();
76 #endif
77 
78 #ifdef __APPLE__
79 # if defined(HAVE_DLOPEN)
80  /* Mac OS X with dlopen (10.3 or later) */
81 # define MACOSX_DLOPEN
82 # else
83 # define MACOSX_DYLD
84 # endif
85 #endif
86 
87 #if defined(__BEOS__) || defined(__HAIKU__)
88 # include <image.h>
89 #endif
90 
91 #ifndef dln_loaderror
92 static void
93 dln_loaderror(const char *format, ...)
94 {
95  va_list ap;
96  va_start(ap, format);
97  vfprintf(stderr, format, ap);
98  va_end(ap);
99  abort();
100 }
101 #endif
102 
103 #if defined(HAVE_DLOPEN) && !defined(USE_DLN_A_OUT) && !defined(_AIX) && !defined(MACOSX_DYLD) && !defined(_UNICOSMP)
104 /* dynamic load with dlopen() */
105 # define USE_DLN_DLOPEN
106 #endif
107 
108 #ifndef FUNCNAME_PATTERN
109 # if defined(__hp9000s300) || ((defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && !defined(__ELF__)) || defined(__BORLANDC__) || defined(NeXT) || defined(__WATCOMC__) || defined(MACOSX_DYLD)
110 # define EXTERNAL_PREFIX "_"
111 # else
112 # define EXTERNAL_PREFIX ""
113 # endif
114 # define FUNCNAME_PREFIX EXTERNAL_PREFIX"Init_"
115 #endif
116 
117 #if defined __CYGWIN__ || defined DOSISH
118 #define isdirsep(x) ((x) == '/' || (x) == '\\')
119 #else
120 #define isdirsep(x) ((x) == '/')
121 #endif
122 
123 static size_t
124 init_funcname_len(const char **file)
125 {
126  const char *p = *file, *base, *dot = NULL;
127 
128  /* Load the file as an object one */
129  for (base = p; *p; p++) { /* Find position of last '/' */
130  if (*p == '.' && !dot) dot = p;
131  if (isdirsep(*p)) base = p+1, dot = NULL;
132  }
133  *file = base;
134  /* Delete suffix if it exists */
135  return (dot ? dot : p) - base;
136 }
137 
138 static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX;
139 
140 #define init_funcname(buf, file) do {\
141  const char *base = (file);\
142  const size_t flen = init_funcname_len(&base);\
143  const size_t plen = sizeof(funcname_prefix);\
144  char *const tmp = ALLOCA_N(char, plen+flen+1);\
145  if (!tmp) {\
146  dln_memerror();\
147  }\
148  memcpy(tmp, funcname_prefix, plen);\
149  memcpy(tmp+plen, base, flen);\
150  tmp[plen+flen] = '\0';\
151  *(buf) = tmp;\
152 } while (0)
153 
154 #ifdef USE_DLN_A_OUT
155 
156 #ifndef LIBC_NAME
157 # define LIBC_NAME "libc.a"
158 #endif
159 
160 #ifndef DLN_DEFAULT_LIB_PATH
161 # define DLN_DEFAULT_LIB_PATH "/lib:/usr/lib:/usr/local/lib:."
162 #endif
163 
164 #include <errno.h>
165 
166 static int dln_errno;
167 
168 #define DLN_ENOEXEC ENOEXEC /* Exec format error */
169 #define DLN_ECONFL 1201 /* Symbol name conflict */
170 #define DLN_ENOINIT 1202 /* No initializer given */
171 #define DLN_EUNDEF 1203 /* Undefine symbol remains */
172 #define DLN_ENOTLIB 1204 /* Not a library file */
173 #define DLN_EBADLIB 1205 /* Malformed library file */
174 #define DLN_EINIT 1206 /* Not initialized */
175 
176 static int dln_init_p = 0;
177 
178 #include <ar.h>
179 #include <a.out.h>
180 #ifndef N_COMM
181 # define N_COMM 0x12
182 #endif
183 #ifndef N_MAGIC
184 # define N_MAGIC(x) (x).a_magic
185 #endif
186 
187 #define INVALID_OBJECT(h) (N_MAGIC(h) != OMAGIC)
188 
189 #include "ruby/util.h"
190 #include "ruby/st.h"
191 
192 static st_table *sym_tbl;
193 static st_table *undef_tbl;
194 
195 static int load_lib();
196 
197 static int
198 load_header(int fd, struct exec *hdrp, long disp)
199 {
200  int size;
201 
202  lseek(fd, disp, 0);
203  size = read(fd, hdrp, sizeof(struct exec));
204  if (size == -1) {
205  dln_errno = errno;
206  return -1;
207  }
208  if (size != sizeof(struct exec) || N_BADMAG(*hdrp)) {
209  dln_errno = DLN_ENOEXEC;
210  return -1;
211  }
212  return 0;
213 }
214 
215 #if defined(sequent)
216 #define RELOC_SYMBOL(r) ((r)->r_symbolnum)
217 #define RELOC_MEMORY_SUB_P(r) ((r)->r_bsr)
218 #define RELOC_PCREL_P(r) ((r)->r_pcrel || (r)->r_bsr)
219 #define RELOC_TARGET_SIZE(r) ((r)->r_length)
220 #endif
221 
222 /* Default macros */
223 #ifndef RELOC_ADDRESS
224 #define RELOC_ADDRESS(r) ((r)->r_address)
225 #define RELOC_EXTERN_P(r) ((r)->r_extern)
226 #define RELOC_SYMBOL(r) ((r)->r_symbolnum)
227 #define RELOC_MEMORY_SUB_P(r) 0
228 #define RELOC_PCREL_P(r) ((r)->r_pcrel)
229 #define RELOC_TARGET_SIZE(r) ((r)->r_length)
230 #endif
231 
232 #if defined(__sun) && defined(__sparc)
233 /* Sparc (Sun 4) macros */
234 # undef relocation_info
235 # define relocation_info reloc_info_sparc
236 # define R_RIGHTSHIFT(r) (reloc_r_rightshift[(r)->r_type])
237 # define R_BITSIZE(r) (reloc_r_bitsize[(r)->r_type])
238 # define R_LENGTH(r) (reloc_r_length[(r)->r_type])
239 static int reloc_r_rightshift[] = {
240  0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 0, 0, 0,
241 };
242 static int reloc_r_bitsize[] = {
243  8, 16, 32, 8, 16, 32, 30, 22, 22, 22, 13, 10, 32, 32, 16,
244 };
245 static int reloc_r_length[] = {
246  0, 1, 2, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
247 };
248 # define R_PCREL(r) \
249  ((r)->r_type >= RELOC_DISP8 && (r)->r_type <= RELOC_WDISP22)
250 # define R_SYMBOL(r) ((r)->r_index)
251 #endif
252 
253 #if defined(sequent)
254 #define R_SYMBOL(r) ((r)->r_symbolnum)
255 #define R_MEMORY_SUB(r) ((r)->r_bsr)
256 #define R_PCREL(r) ((r)->r_pcrel || (r)->r_bsr)
257 #define R_LENGTH(r) ((r)->r_length)
258 #endif
259 
260 #ifndef R_SYMBOL
261 # define R_SYMBOL(r) ((r)->r_symbolnum)
262 # define R_MEMORY_SUB(r) 0
263 # define R_PCREL(r) ((r)->r_pcrel)
264 # define R_LENGTH(r) ((r)->r_length)
265 #endif
266 
267 static struct relocation_info *
268 load_reloc(int fd, struct exec *hdrp, long disp)
269 {
270  struct relocation_info *reloc;
271  int size;
272 
273  lseek(fd, disp + N_TXTOFF(*hdrp) + hdrp->a_text + hdrp->a_data, 0);
274  size = hdrp->a_trsize + hdrp->a_drsize;
275  reloc = (struct relocation_info*)xmalloc(size);
276  if (reloc == NULL) {
277  dln_errno = errno;
278  return NULL;
279  }
280 
281  if (read(fd, reloc, size) != size) {
282  dln_errno = errno;
283  free(reloc);
284  return NULL;
285  }
286 
287  return reloc;
288 }
289 
290 static struct nlist *
291 load_sym(int fd, struct exec *hdrp, long disp)
292 {
293  struct nlist * buffer;
294  struct nlist * sym;
295  struct nlist * end;
296  long displ;
297  int size;
298 
299  lseek(fd, N_SYMOFF(*hdrp) + hdrp->a_syms + disp, 0);
300  if (read(fd, &size, sizeof(int)) != sizeof(int)) {
301  goto err_noexec;
302  }
303 
304  buffer = (struct nlist*)xmalloc(hdrp->a_syms + size);
305  if (buffer == NULL) {
306  dln_errno = errno;
307  return NULL;
308  }
309 
310  lseek(fd, disp + N_SYMOFF(*hdrp), 0);
311  if (read(fd, buffer, hdrp->a_syms + size) != hdrp->a_syms + size) {
312  free(buffer);
313  goto err_noexec;
314  }
315 
316  sym = buffer;
317  end = sym + hdrp->a_syms / sizeof(struct nlist);
318  displ = (long)buffer + (long)(hdrp->a_syms);
319 
320  while (sym < end) {
321  sym->n_un.n_name = (char*)sym->n_un.n_strx + displ;
322  sym++;
323  }
324  return buffer;
325 
326  err_noexec:
327  dln_errno = DLN_ENOEXEC;
328  return NULL;
329 }
330 
331 static st_table *
332 sym_hash(struct exec *hdrp, struct nlist *syms)
333 {
334  st_table *tbl;
335  struct nlist *sym = syms;
336  struct nlist *end = syms + (hdrp->a_syms / sizeof(struct nlist));
337 
338  tbl = st_init_strtable();
339  if (tbl == NULL) {
340  dln_errno = errno;
341  return NULL;
342  }
343 
344  while (sym < end) {
345  st_insert(tbl, sym->n_un.n_name, sym);
346  sym++;
347  }
348  return tbl;
349 }
350 
351 static int
352 dln_init(const char *prog)
353 {
354  char *file, fbuf[MAXPATHLEN];
355  int fd;
356  struct exec hdr;
357  struct nlist *syms;
358 
359  if (dln_init_p == 1) return 0;
360 
361  file = dln_find_exe_r(prog, NULL, fbuf, sizeof(fbuf));
362  if (file == NULL || (fd = open(file, O_RDONLY)) < 0) {
363  dln_errno = errno;
364  return -1;
365  }
366 
367  if (load_header(fd, &hdr, 0) == -1) return -1;
368  syms = load_sym(fd, &hdr, 0);
369  if (syms == NULL) {
370  close(fd);
371  return -1;
372  }
373  sym_tbl = sym_hash(&hdr, syms);
374  if (sym_tbl == NULL) { /* file may be start with #! */
375  char c = '\0';
376  char buf[MAXPATHLEN];
377  char *p;
378 
379  free(syms);
380  lseek(fd, 0L, 0);
381  if (read(fd, &c, 1) == -1) {
382  dln_errno = errno;
383  return -1;
384  }
385  if (c != '#') goto err_noexec;
386  if (read(fd, &c, 1) == -1) {
387  dln_errno = errno;
388  return -1;
389  }
390  if (c != '!') goto err_noexec;
391 
392  p = buf;
393  /* skip forwarding spaces */
394  while (read(fd, &c, 1) == 1) {
395  if (c == '\n') goto err_noexec;
396  if (c != '\t' && c != ' ') {
397  *p++ = c;
398  break;
399  }
400  }
401  /* read in command name */
402  while (read(fd, p, 1) == 1) {
403  if (*p == '\n' || *p == '\t' || *p == ' ') break;
404  p++;
405  if (p-buf >= MAXPATHLEN) {
406  dln_errno = ENAMETOOLONG;
407  return -1;
408  }
409  }
410  *p = '\0';
411 
412  return dln_init(buf);
413  }
414  dln_init_p = 1;
415  undef_tbl = st_init_strtable();
416  close(fd);
417  return 0;
418 
419  err_noexec:
420  close(fd);
421  dln_errno = DLN_ENOEXEC;
422  return -1;
423 }
424 
425 static long
426 load_text_data(int fd, struct exec *hdrp, int bss, long disp)
427 {
428  int size;
429  unsigned char* addr;
430 
431  lseek(fd, disp + N_TXTOFF(*hdrp), 0);
432  size = hdrp->a_text + hdrp->a_data;
433 
434  if (bss == -1) size += hdrp->a_bss;
435  else if (bss > 1) size += bss;
436 
437  addr = (unsigned char*)xmalloc(size);
438  if (addr == NULL) {
439  dln_errno = errno;
440  return 0;
441  }
442 
443  if (read(fd, addr, size) != size) {
444  dln_errno = errno;
445  free(addr);
446  return 0;
447  }
448 
449  if (bss == -1) {
450  memset(addr + hdrp->a_text + hdrp->a_data, 0, hdrp->a_bss);
451  }
452  else if (bss > 0) {
453  memset(addr + hdrp->a_text + hdrp->a_data, 0, bss);
454  }
455 
456  return (long)addr;
457 }
458 
459 static int
460 undef_print(char *key, char *value)
461 {
462  fprintf(stderr, " %s\n", key);
463  return ST_CONTINUE;
464 }
465 
466 static void
467 dln_print_undef(void)
468 {
469  fprintf(stderr, " Undefined symbols:\n");
470  st_foreach(undef_tbl, undef_print, NULL);
471 }
472 
473 static void
474 dln_undefined(void)
475 {
476  if (undef_tbl->num_entries > 0) {
477  fprintf(stderr, "dln: Calling undefined function\n");
478  dln_print_undef();
479  dln_exit(1);
480  }
481 }
482 
483 struct undef {
484  char *name;
485  struct relocation_info reloc;
486  long base;
487  char *addr;
488  union {
489  char c;
490  short s;
491  long l;
492  } u;
493 };
494 
495 static st_table *reloc_tbl = NULL;
496 static void
497 link_undef(const char *name, long base, struct relocation_info *reloc)
498 {
499  static int u_no = 0;
500  struct undef *obj;
501  char *addr = (char*)(reloc->r_address + base);
502 
503  obj = (struct undef*)xmalloc(sizeof(struct undef));
504  obj->name = strdup(name);
505  obj->reloc = *reloc;
506  obj->base = base;
507  switch (R_LENGTH(reloc)) {
508  case 0: /* byte */
509  obj->u.c = *addr;
510  break;
511  case 1: /* word */
512  obj->u.s = *(short*)addr;
513  break;
514  case 2: /* long */
515  obj->u.l = *(long*)addr;
516  break;
517  }
518  if (reloc_tbl == NULL) {
519  reloc_tbl = st_init_numtable();
520  }
521  st_insert(reloc_tbl, u_no++, obj);
522 }
523 
524 struct reloc_arg {
525  const char *name;
526  long value;
527 };
528 
529 static int
530 reloc_undef(int no, struct undef *undef, struct reloc_arg *arg)
531 {
532  int datum;
533  char *address;
534 #if defined(__sun) && defined(__sparc)
535  unsigned int mask = 0;
536 #endif
537 
538  if (strcmp(arg->name, undef->name) != 0) return ST_CONTINUE;
539  address = (char*)(undef->base + undef->reloc.r_address);
540  datum = arg->value;
541 
542  if (R_PCREL(&(undef->reloc))) datum -= undef->base;
543 #if defined(__sun) && defined(__sparc)
544  datum += undef->reloc.r_addend;
545  datum >>= R_RIGHTSHIFT(&(undef->reloc));
546  mask = (1 << R_BITSIZE(&(undef->reloc))) - 1;
547  mask |= mask -1;
548  datum &= mask;
549  switch (R_LENGTH(&(undef->reloc))) {
550  case 0:
551  *address = undef->u.c;
552  *address &= ~mask;
553  *address |= datum;
554  break;
555  case 1:
556  *(short *)address = undef->u.s;
557  *(short *)address &= ~mask;
558  *(short *)address |= datum;
559  break;
560  case 2:
561  *(long *)address = undef->u.l;
562  *(long *)address &= ~mask;
563  *(long *)address |= datum;
564  break;
565  }
566 #else
567  switch (R_LENGTH(&(undef->reloc))) {
568  case 0: /* byte */
569  if (R_MEMORY_SUB(&(undef->reloc)))
570  *address = datum - *address;
571  else *address = undef->u.c + datum;
572  break;
573  case 1: /* word */
574  if (R_MEMORY_SUB(&(undef->reloc)))
575  *(short*)address = datum - *(short*)address;
576  else *(short*)address = undef->u.s + datum;
577  break;
578  case 2: /* long */
579  if (R_MEMORY_SUB(&(undef->reloc)))
580  *(long*)address = datum - *(long*)address;
581  else *(long*)address = undef->u.l + datum;
582  break;
583  }
584 #endif
585  free(undef->name);
586  free(undef);
587  return ST_DELETE;
588 }
589 
590 static void
591 unlink_undef(const char *name, long value)
592 {
593  struct reloc_arg arg;
594 
595  arg.name = name;
596  arg.value = value;
597  st_foreach(reloc_tbl, reloc_undef, &arg);
598 }
599 
600 #ifdef N_INDR
601 struct indr_data {
602  char *name0, *name1;
603 };
604 
605 static int
606 reloc_repl(int no, struct undef *undef, struct indr_data *data)
607 {
608  if (strcmp(data->name0, undef->name) == 0) {
609  free(undef->name);
610  undef->name = strdup(data->name1);
611  }
612  return ST_CONTINUE;
613 }
614 #endif
615 
616 static int
617 load_1(int fd, long disp, const char *need_init)
618 {
619  static const char *libc = LIBC_NAME;
620  struct exec hdr;
621  struct relocation_info *reloc = NULL;
622  long block = 0;
623  long new_common = 0; /* Length of new common */
624  struct nlist *syms = NULL;
625  struct nlist *sym;
626  struct nlist *end;
627  int init_p = 0;
628 
629  if (load_header(fd, &hdr, disp) == -1) return -1;
630  if (INVALID_OBJECT(hdr)) {
631  dln_errno = DLN_ENOEXEC;
632  return -1;
633  }
634  reloc = load_reloc(fd, &hdr, disp);
635  if (reloc == NULL) return -1;
636 
637  syms = load_sym(fd, &hdr, disp);
638  if (syms == NULL) {
639  free(reloc);
640  return -1;
641  }
642 
643  sym = syms;
644  end = syms + (hdr.a_syms / sizeof(struct nlist));
645  while (sym < end) {
646  struct nlist *old_sym;
647  int value = sym->n_value;
648 
649 #ifdef N_INDR
650  if (sym->n_type == (N_INDR | N_EXT)) {
651  char *key = sym->n_un.n_name;
652 
653  if (st_lookup(sym_tbl, sym[1].n_un.n_name, &old_sym)) {
654  if (st_delete(undef_tbl, (st_data_t*)&key, NULL)) {
655  unlink_undef(key, old_sym->n_value);
656  free(key);
657  }
658  }
659  else {
660  struct indr_data data;
661 
662  data.name0 = sym->n_un.n_name;
663  data.name1 = sym[1].n_un.n_name;
664  st_foreach(reloc_tbl, reloc_repl, &data);
665 
666  st_insert(undef_tbl, strdup(sym[1].n_un.n_name), NULL);
667  if (st_delete(undef_tbl, (st_data_t*)&key, NULL)) {
668  free(key);
669  }
670  }
671  sym += 2;
672  continue;
673  }
674 #endif
675  if (sym->n_type == (N_UNDF | N_EXT)) {
676  if (st_lookup(sym_tbl, sym->n_un.n_name, &old_sym) == 0) {
677  old_sym = NULL;
678  }
679 
680  if (value) {
681  if (old_sym) {
682  sym->n_type = N_EXT | N_COMM;
683  sym->n_value = old_sym->n_value;
684  }
685  else {
686  int rnd =
687  value >= sizeof(double) ? sizeof(double) - 1
688  : value >= sizeof(long) ? sizeof(long) - 1
689  : sizeof(short) - 1;
690 
691  sym->n_type = N_COMM;
692  new_common += rnd;
693  new_common &= ~(long)rnd;
694  sym->n_value = new_common;
695  new_common += value;
696  }
697  }
698  else {
699  if (old_sym) {
700  sym->n_type = N_EXT | N_COMM;
701  sym->n_value = old_sym->n_value;
702  }
703  else {
704  sym->n_value = (long)dln_undefined;
705  st_insert(undef_tbl, strdup(sym->n_un.n_name), NULL);
706  }
707  }
708  }
709  sym++;
710  }
711 
712  block = load_text_data(fd, &hdr, hdr.a_bss + new_common, disp);
713  if (block == 0) goto err_exit;
714 
715  sym = syms;
716  while (sym < end) {
717  struct nlist *new_sym;
718  char *key;
719 
720  switch (sym->n_type) {
721  case N_COMM:
722  sym->n_value += hdr.a_text + hdr.a_data;
723  case N_TEXT|N_EXT:
724  case N_DATA|N_EXT:
725 
726  sym->n_value += block;
727 
728  if (st_lookup(sym_tbl, sym->n_un.n_name, &new_sym) != 0
729  && new_sym->n_value != (long)dln_undefined) {
730  dln_errno = DLN_ECONFL;
731  goto err_exit;
732  }
733 
734  key = sym->n_un.n_name;
735  if (st_delete(undef_tbl, (st_data_t*)&key, NULL) != 0) {
736  unlink_undef(key, sym->n_value);
737  free(key);
738  }
739 
740  new_sym = (struct nlist*)xmalloc(sizeof(struct nlist));
741  *new_sym = *sym;
742  new_sym->n_un.n_name = strdup(sym->n_un.n_name);
743  st_insert(sym_tbl, new_sym->n_un.n_name, new_sym);
744  break;
745 
746  case N_TEXT:
747  case N_DATA:
748  sym->n_value += block;
749  break;
750  }
751  sym++;
752  }
753 
754  /*
755  * First comes the text-relocation
756  */
757  {
758  struct relocation_info * rel = reloc;
759  struct relocation_info * rel_beg = reloc +
760  (hdr.a_trsize/sizeof(struct relocation_info));
761  struct relocation_info * rel_end = reloc +
762  (hdr.a_trsize+hdr.a_drsize)/sizeof(struct relocation_info);
763 
764  while (rel < rel_end) {
765  char *address = (char*)(rel->r_address + block);
766  long datum = 0;
767 #if defined(__sun) && defined(__sparc)
768  unsigned int mask = 0;
769 #endif
770 
771  if (rel >= rel_beg)
772  address += hdr.a_text;
773 
774  if (rel->r_extern) { /* Look it up in symbol-table */
775  sym = &(syms[R_SYMBOL(rel)]);
776  switch (sym->n_type) {
777  case N_EXT|N_UNDF:
778  link_undef(sym->n_un.n_name, block, rel);
779  case N_EXT|N_COMM:
780  case N_COMM:
781  datum = sym->n_value;
782  break;
783  default:
784  goto err_exit;
785  }
786  } /* end.. look it up */
787  else { /* is static */
788  switch (R_SYMBOL(rel)) {
789  case N_TEXT:
790  case N_DATA:
791  datum = block;
792  break;
793  case N_BSS:
794  datum = block + new_common;
795  break;
796  case N_ABS:
797  break;
798  }
799  } /* end .. is static */
800  if (R_PCREL(rel)) datum -= block;
801 
802 #if defined(__sun) && defined(__sparc)
803  datum += rel->r_addend;
804  datum >>= R_RIGHTSHIFT(rel);
805  mask = (1 << R_BITSIZE(rel)) - 1;
806  mask |= mask -1;
807  datum &= mask;
808 
809  switch (R_LENGTH(rel)) {
810  case 0:
811  *address &= ~mask;
812  *address |= datum;
813  break;
814  case 1:
815  *(short *)address &= ~mask;
816  *(short *)address |= datum;
817  break;
818  case 2:
819  *(long *)address &= ~mask;
820  *(long *)address |= datum;
821  break;
822  }
823 #else
824  switch (R_LENGTH(rel)) {
825  case 0: /* byte */
826  if (datum < -128 || datum > 127) goto err_exit;
827  *address += datum;
828  break;
829  case 1: /* word */
830  *(short *)address += datum;
831  break;
832  case 2: /* long */
833  *(long *)address += datum;
834  break;
835  }
836 #endif
837  rel++;
838  }
839  }
840 
841  if (need_init) {
842  int len;
843  char **libs_to_be_linked = 0;
844  char *buf;
845 
846  if (undef_tbl->num_entries > 0) {
847  if (load_lib(libc) == -1) goto err_exit;
848  }
849 
850  init_funcname(&buf, need_init);
851  len = strlen(buf);
852 
853  for (sym = syms; sym<end; sym++) {
854  char *name = sym->n_un.n_name;
855  if (name[0] == '_' && sym->n_value >= block) {
856  if (strcmp(name+1, "dln_libs_to_be_linked") == 0) {
857  libs_to_be_linked = (char**)sym->n_value;
858  }
859  else if (strcmp(name+1, buf) == 0) {
860  init_p = 1;
861  ((int (*)())sym->n_value)();
862  }
863  }
864  }
865  if (libs_to_be_linked && undef_tbl->num_entries > 0) {
866  while (*libs_to_be_linked) {
867  load_lib(*libs_to_be_linked);
868  libs_to_be_linked++;
869  }
870  }
871  }
872  free(reloc);
873  free(syms);
874  if (need_init) {
875  if (init_p == 0) {
876  dln_errno = DLN_ENOINIT;
877  return -1;
878  }
879  if (undef_tbl->num_entries > 0) {
880  if (load_lib(libc) == -1) goto err_exit;
881  if (undef_tbl->num_entries > 0) {
882  dln_errno = DLN_EUNDEF;
883  return -1;
884  }
885  }
886  }
887  return 0;
888 
889  err_exit:
890  if (syms) free(syms);
891  if (reloc) free(reloc);
892  if (block) free((char*)block);
893  return -1;
894 }
895 
896 static int target_offset;
897 static int
898 search_undef(const char *key, int value, st_table *lib_tbl)
899 {
900  long offset;
901 
902  if (st_lookup(lib_tbl, key, &offset) == 0) return ST_CONTINUE;
903  target_offset = offset;
904  return ST_STOP;
905 }
906 
907 struct symdef {
908  int rb_str_index;
909  int lib_offset;
910 };
911 
912 const char *dln_librrb_ary_path = DLN_DEFAULT_LIB_PATH;
913 
914 static int
915 load_lib(const char *lib)
916 {
917  char *path, *file, fbuf[MAXPATHLEN];
918  char *envpath = 0;
919  char armagic[SARMAG];
920  int fd, size;
921  struct ar_hdr ahdr;
922  st_table *lib_tbl = NULL;
923  int *data, nsym;
924  struct symdef *base;
925  char *name_base;
926 
927  if (dln_init_p == 0) {
928  dln_errno = DLN_ENOINIT;
929  return -1;
930  }
931 
932  if (undef_tbl->num_entries == 0) return 0;
933  dln_errno = DLN_EBADLIB;
934 
935  if (lib[0] == '-' && lib[1] == 'l') {
936  long len = strlen(lib) + 4;
937  char *p = alloca(len);
938  snprintf(p, len, "lib%s.a", lib+2);
939  lib = p;
940  }
941 
942  /* library search path: */
943  /* look for environment variable DLN_LIBRARY_PATH first. */
944  /* then variable dln_librrb_ary_path. */
945  /* if path is still NULL, use "." for path. */
946  path = getenv("DLN_LIBRARY_PATH");
947  if (path == NULL) path = dln_librrb_ary_path;
948  else path = envpath = strdup(path);
949 
950  file = dln_find_file_r(lib, path, fbuf, sizeof(fbuf));
951  if (envpath) free(envpath);
952  fd = open(file, O_RDONLY);
953  if (fd == -1) goto syserr;
954  size = read(fd, armagic, SARMAG);
955  if (size == -1) goto syserr;
956 
957  if (size != SARMAG) {
958  dln_errno = DLN_ENOTLIB;
959  goto badlib;
960  }
961  size = read(fd, &ahdr, sizeof(ahdr));
962  if (size == -1) goto syserr;
963  if (size != sizeof(ahdr) || sscanf(ahdr.ar_size, "%d", &size) != 1) {
964  goto badlib;
965  }
966 
967  if (strncmp(ahdr.ar_name, "__.SYMDEF", 9) == 0) {
968  /* make hash table from __.SYMDEF */
969 
970  lib_tbl = st_init_strtable();
971  data = (int*)xmalloc(size);
972  if (data == NULL) goto syserr;
973  size = read(fd, data, size);
974  nsym = *data / sizeof(struct symdef);
975  base = (struct symdef*)(data + 1);
976  name_base = (char*)(base + nsym) + sizeof(int);
977  while (nsym > 0) {
978  char *name = name_base + base->rb_str_index;
979 
980  st_insert(lib_tbl, name, base->lib_offset + sizeof(ahdr));
981  nsym--;
982  base++;
983  }
984  for (;;) {
985  target_offset = -1;
986  st_foreach(undef_tbl, search_undef, lib_tbl);
987  if (target_offset == -1) break;
988  if (load_1(fd, target_offset, 0) == -1) {
989  st_free_table(lib_tbl);
990  free(data);
991  goto badlib;
992  }
993  if (undef_tbl->num_entries == 0) break;
994  }
995  free(data);
996  st_free_table(lib_tbl);
997  }
998  else {
999  /* linear library, need to scan (FUTURE) */
1000 
1001  for (;;) {
1002  int offset = SARMAG;
1003  int found = 0;
1004  struct exec hdr;
1005  struct nlist *syms, *sym, *end;
1006 
1007  while (undef_tbl->num_entries > 0) {
1008  found = 0;
1009  lseek(fd, offset, 0);
1010  size = read(fd, &ahdr, sizeof(ahdr));
1011  if (size == -1) goto syserr;
1012  if (size == 0) break;
1013  if (size != sizeof(ahdr)
1014  || sscanf(ahdr.ar_size, "%d", &size) != 1) {
1015  goto badlib;
1016  }
1017  offset += sizeof(ahdr);
1018  if (load_header(fd, &hdr, offset) == -1)
1019  goto badlib;
1020  syms = load_sym(fd, &hdr, offset);
1021  if (syms == NULL) goto badlib;
1022  sym = syms;
1023  end = syms + (hdr.a_syms / sizeof(struct nlist));
1024  while (sym < end) {
1025  if (sym->n_type == N_EXT|N_TEXT
1026  && st_lookup(undef_tbl, sym->n_un.n_name, NULL)) {
1027  break;
1028  }
1029  sym++;
1030  }
1031  if (sym < end) {
1032  found++;
1033  free(syms);
1034  if (load_1(fd, offset, 0) == -1) {
1035  goto badlib;
1036  }
1037  }
1038  offset += size;
1039  if (offset & 1) offset++;
1040  }
1041  if (found) break;
1042  }
1043  }
1044  close(fd);
1045  return 0;
1046 
1047  syserr:
1048  dln_errno = errno;
1049  badlib:
1050  if (fd >= 0) close(fd);
1051  return -1;
1052 }
1053 
1054 static int
1055 load(const char *file)
1056 {
1057  int fd;
1058  int result;
1059 
1060  if (dln_init_p == 0) {
1061  if (dln_init(dln_argv0) == -1) return -1;
1062  }
1063  result = strlen(file);
1064  if (file[result-1] == 'a') {
1065  return load_lib(file);
1066  }
1067 
1068  fd = open(file, O_RDONLY);
1069  if (fd == -1) {
1070  dln_errno = errno;
1071  return -1;
1072  }
1073  result = load_1(fd, 0, file);
1074  close(fd);
1075 
1076  return result;
1077 }
1078 
1079 void*
1080 dln_sym(const char *name)
1081 {
1082  struct nlist *sym;
1083 
1084  if (st_lookup(sym_tbl, name, &sym))
1085  return (void*)sym->n_value;
1086  return NULL;
1087 }
1088 
1089 #endif /* USE_DLN_A_OUT */
1090 
1091 #ifdef USE_DLN_DLOPEN
1092 # include <dlfcn.h>
1093 #endif
1094 
1095 #ifdef __hpux
1096 #include <errno.h>
1097 #include "dl.h"
1098 #endif
1099 
1100 #if defined(_AIX)
1101 #include <ctype.h> /* for isdigit() */
1102 #include <errno.h> /* for global errno */
1103 #include <sys/ldr.h>
1104 #endif
1105 
1106 #ifdef NeXT
1107 #if NS_TARGET_MAJOR < 4
1108 #include <mach-o/rld.h>
1109 #else
1110 #include <mach-o/dyld.h>
1111 #ifndef NSLINKMODULE_OPTION_BINDNOW
1112 #define NSLINKMODULE_OPTION_BINDNOW 1
1113 #endif
1114 #endif
1115 #else
1116 #ifdef MACOSX_DYLD
1117 #include <mach-o/dyld.h>
1118 #endif
1119 #endif
1120 
1121 #if defined _WIN32 && !defined __CYGWIN__
1122 #include <windows.h>
1123 #include <imagehlp.h>
1124 #endif
1125 
1126 #if defined _WIN32 && !defined __CYGWIN__
1127 static const char *
1128 dln_strerror(char *message, size_t size)
1129 {
1130  int error = GetLastError();
1131  char *p = message;
1132  size_t len = snprintf(message, size, "%d: ", error);
1133 
1134 #define format_message(sublang) FormatMessage(\
1135  FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, \
1136  NULL, error, MAKELANGID(LANG_NEUTRAL, (sublang)), \
1137  message + len, size - len, NULL)
1138  if (format_message(SUBLANG_ENGLISH_US) == 0)
1139  format_message(SUBLANG_DEFAULT);
1140  for (p = message + len; *p; p++) {
1141  if (*p == '\n' || *p == '\r')
1142  *p = ' ';
1143  }
1144  return message;
1145 }
1146 #define dln_strerror() dln_strerror(message, sizeof message)
1147 #elif ! defined _AIX
1148 static const char *
1150 {
1151 #ifdef USE_DLN_A_OUT
1152  char *strerror();
1153 
1154  switch (dln_errno) {
1155  case DLN_ECONFL:
1156  return "Symbol name conflict";
1157  case DLN_ENOINIT:
1158  return "No initializer given";
1159  case DLN_EUNDEF:
1160  return "Unresolved symbols";
1161  case DLN_ENOTLIB:
1162  return "Not a library file";
1163  case DLN_EBADLIB:
1164  return "Malformed library file";
1165  case DLN_EINIT:
1166  return "Not initialized";
1167  default:
1168  return strerror(dln_errno);
1169  }
1170 #endif
1171 
1172 #ifdef USE_DLN_DLOPEN
1173  return (char*)dlerror();
1174 #endif
1175 }
1176 #endif
1177 
1178 #if defined(_AIX) && ! defined(_IA64)
1179 static void
1180 aix_loaderror(const char *pathname)
1181 {
1182  char *message[1024], errbuf[1024];
1183  int i;
1184 #define ERRBUF_APPEND(s) strncat(errbuf, (s), sizeof(errbuf)-strlen(errbuf)-1)
1185  snprintf(errbuf, sizeof(errbuf), "load failed - %s. ", pathname);
1186 
1187  if (loadquery(L_GETMESSAGES, &message[0], sizeof(message)) != -1) {
1188  ERRBUF_APPEND("Please issue below command for detailed reasons:\n\t");
1189  ERRBUF_APPEND("/usr/sbin/execerror ruby ");
1190  for (i=0; message[i]; i++) {
1191  ERRBUF_APPEND("\"");
1192  ERRBUF_APPEND(message[i]);
1193  ERRBUF_APPEND("\" ");
1194  }
1195  ERRBUF_APPEND("\n");
1196  } else {
1197  ERRBUF_APPEND(strerror(errno));
1198  ERRBUF_APPEND("[loadquery failed]");
1199  }
1200  dln_loaderror("%s", errbuf);
1201 }
1202 #endif
1203 
1204 #if defined _WIN32 && defined RUBY_EXPORT
1205 HANDLE rb_libruby_handle(void);
1206 
1207 static int
1208 rb_w32_check_imported(HMODULE ext, HMODULE mine)
1209 {
1210  ULONG size;
1211  const IMAGE_IMPORT_DESCRIPTOR *desc;
1212 
1213  desc = ImageDirectoryEntryToData(ext, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
1214  if (!desc) return 0;
1215  while (desc->Name) {
1216  PIMAGE_THUNK_DATA pint = (PIMAGE_THUNK_DATA)((char *)ext + desc->Characteristics);
1217  PIMAGE_THUNK_DATA piat = (PIMAGE_THUNK_DATA)((char *)ext + desc->FirstThunk);
1218  for (; piat->u1.Function; piat++, pint++) {
1219  static const char prefix[] = "rb_";
1220  PIMAGE_IMPORT_BY_NAME pii;
1221  const char *name;
1222 
1223  if (IMAGE_SNAP_BY_ORDINAL(pint->u1.Ordinal)) continue;
1224  pii = (PIMAGE_IMPORT_BY_NAME)((char *)ext + (size_t)pint->u1.AddressOfData);
1225  name = (const char *)pii->Name;
1226  if (strncmp(name, prefix, sizeof(prefix) - 1) == 0) {
1227  FARPROC addr = GetProcAddress(mine, name);
1228  if (addr) return (FARPROC)piat->u1.Function == addr;
1229  }
1230  }
1231  desc++;
1232  }
1233  return 1;
1234 }
1235 #endif
1236 
1237 #if defined(DLN_NEEDS_ALT_SEPARATOR) && DLN_NEEDS_ALT_SEPARATOR
1238 #define translit_separator(src) do { \
1239  char *tmp = ALLOCA_N(char, strlen(src) + 1), *p = tmp, c; \
1240  do { \
1241  *p++ = ((c = *file++) == '/') ? DLN_NEEDS_ALT_SEPARATOR : c; \
1242  } while (c); \
1243  (src) = tmp; \
1244  } while (0)
1245 #else
1246 #define translit_separator(str) (void)(str)
1247 #endif
1248 
1249 void*
1250 dln_load(const char *file)
1251 {
1252 #if !defined(_AIX) && !defined(NeXT)
1253  const char *error = 0;
1254 #define DLN_ERROR() (error = dln_strerror(), strcpy(ALLOCA_N(char, strlen(error) + 1), error))
1255 #endif
1256 
1257 #if defined _WIN32 && !defined __CYGWIN__
1258  HINSTANCE handle;
1259  WCHAR *winfile;
1260  char message[1024];
1261  void (*init_fct)();
1262  char *buf;
1263 
1264  /* Load the file as an object one */
1265  init_funcname(&buf, file);
1266 
1267  /* Convert the file path to wide char */
1268  winfile = rb_w32_mbstr_to_wstr(CP_UTF8, file, -1, NULL);
1269  if (!winfile) {
1270  dln_memerror();
1271  }
1272 
1273  /* Load file */
1274  handle = LoadLibraryW(winfile);
1275  free(winfile);
1276 
1277  if (!handle) {
1278  error = dln_strerror();
1279  goto failed;
1280  }
1281 
1282 #if defined _WIN32 && defined RUBY_EXPORT
1283  if (!rb_w32_check_imported(handle, rb_libruby_handle())) {
1284  FreeLibrary(handle);
1285  error = "incompatible library version";
1286  goto failed;
1287  }
1288 #endif
1289 
1290  if ((init_fct = (void(*)())GetProcAddress(handle, buf)) == NULL) {
1291  dln_loaderror("%s - %s\n%s", dln_strerror(), buf, file);
1292  }
1293 
1294  /* Call the init code */
1295  (*init_fct)();
1296  return handle;
1297 #else
1298 #ifdef USE_DLN_A_OUT
1299  if (load(file) == -1) {
1300  error = dln_strerror();
1301  goto failed;
1302  }
1303  return 0;
1304 #else
1305 
1306  char *buf;
1307  /* Load the file as an object one */
1308  init_funcname(&buf, file);
1309  translit_separator(file);
1310 
1311 #ifdef USE_DLN_DLOPEN
1312 #define DLN_DEFINED
1313  {
1314  void *handle;
1315  void (*init_fct)();
1316 
1317 #ifndef RTLD_LAZY
1318 # define RTLD_LAZY 1
1319 #endif
1320 #ifdef __INTERIX
1321 # undef RTLD_GLOBAL
1322 #endif
1323 #ifndef RTLD_GLOBAL
1324 # define RTLD_GLOBAL 0
1325 #endif
1326 
1327 #ifdef __native_client__
1328  char* p, *orig;
1329  if (file[0] == '.' && file[1] == '/') file+=2;
1330  orig = strdup(file);
1331  for (p = file; *p; ++p) {
1332  if (*p == '/') *p = '_';
1333  }
1334 #endif
1335  /* Load file */
1336  if ((handle = (void*)dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
1337 #ifdef __native_client__
1338  free(orig);
1339 #endif
1340  error = dln_strerror();
1341  goto failed;
1342  }
1343 
1344 # if defined RUBY_EXPORT
1345  {
1346  static const char incompatible[] = "incompatible library version";
1347  void *ex = dlsym(handle, EXTERNAL_PREFIX"ruby_xmalloc");
1348  if (ex && ex != ruby_xmalloc) {
1349 
1350 # if defined __APPLE__
1351  /* dlclose() segfaults */
1352  rb_fatal("%s - %s", incompatible, file);
1353 # else
1354  dlclose(handle);
1355  error = incompatible;
1356  goto failed;
1357 # endif
1358  }
1359  }
1360 # endif
1361 
1362  init_fct = (void(*)())(VALUE)dlsym(handle, buf);
1363 #ifdef __native_client__
1364  strcpy(file, orig);
1365  free(orig);
1366 #endif
1367 #if defined __SYMBIAN32__
1368  if (init_fct == NULL) {
1369  init_fct = (void(*)())dlsym(handle, "1"); /* Some Symbian versions do not support symbol table in DLL, ordinal numbers only */
1370  }
1371 #endif
1372  if (init_fct == NULL) {
1373  error = DLN_ERROR();
1374  dlclose(handle);
1375  goto failed;
1376  }
1377  /* Call the init code */
1378  (*init_fct)();
1379 
1380  return handle;
1381  }
1382 #endif /* USE_DLN_DLOPEN */
1383 
1384 #ifdef __hpux
1385 #define DLN_DEFINED
1386  {
1387  shl_t lib = NULL;
1388  int flags;
1389  void (*init_fct)();
1390 
1391  flags = BIND_DEFERRED;
1392  lib = shl_load(file, flags, 0);
1393  if (lib == NULL) {
1394  extern int errno;
1395  dln_loaderror("%s - %s", strerror(errno), file);
1396  }
1397  shl_findsym(&lib, buf, TYPE_PROCEDURE, (void*)&init_fct);
1398  if (init_fct == NULL) {
1399  shl_findsym(&lib, buf, TYPE_UNDEFINED, (void*)&init_fct);
1400  if (init_fct == NULL) {
1401  errno = ENOSYM;
1402  dln_loaderror("%s - %s", strerror(ENOSYM), file);
1403  }
1404  }
1405  (*init_fct)();
1406  return (void*)lib;
1407  }
1408 #endif /* hpux */
1409 
1410 #if defined(_AIX) && ! defined(_IA64)
1411 #define DLN_DEFINED
1412  {
1413  void (*init_fct)();
1414 
1415  init_fct = (void(*)())load((char*)file, 1, 0);
1416  if (init_fct == NULL) {
1417  aix_loaderror(file);
1418  }
1419  if (loadbind(0, (void*)dln_load, (void*)init_fct) == -1) {
1420  aix_loaderror(file);
1421  }
1422  (*init_fct)();
1423  return (void*)init_fct;
1424  }
1425 #endif /* _AIX */
1426 
1427 #if defined(MACOSX_DYLD)
1428 #define DLN_DEFINED
1429 /*----------------------------------------------------
1430  By SHIROYAMA Takayuki Psi@fortune.nest.or.jp
1431 
1432  Special Thanks...
1433  Yu tomoak-i@is.aist-nara.ac.jp,
1434  Mi hisho@tasihara.nest.or.jp,
1435  sunshine@sunshineco.com,
1436  and... Miss ARAI Akino(^^;)
1437  ----------------------------------------------------*/
1438  {
1439  int dyld_result;
1440  NSObjectFileImage obj_file; /* handle, but not use it */
1441  /* "file" is module file name .
1442  "buf" is pointer to initial function name with "_" . */
1443 
1444  void (*init_fct)();
1445 
1446 
1447  dyld_result = NSCreateObjectFileImageFromFile(file, &obj_file);
1448 
1449  if (dyld_result != NSObjectFileImageSuccess) {
1450  dln_loaderror("Failed to load %.200s", file);
1451  }
1452 
1453  NSLinkModule(obj_file, file, NSLINKMODULE_OPTION_BINDNOW);
1454 
1455  /* lookup the initial function */
1456  if (!NSIsSymbolNameDefined(buf)) {
1457  dln_loaderror("Failed to lookup Init function %.200s",file);
1458  }
1459  init_fct = NSAddressOfSymbol(NSLookupAndBindSymbol(buf));
1460  (*init_fct)();
1461 
1462  return (void*)init_fct;
1463  }
1464 #endif
1465 
1466 #if defined(__BEOS__) || defined(__HAIKU__)
1467 # define DLN_DEFINED
1468  {
1469  status_t err_stat; /* BeOS error status code */
1470  image_id img_id; /* extension module unique id */
1471  void (*init_fct)(); /* initialize function for extension module */
1472 
1473  /* load extension module */
1474  img_id = load_add_on(file);
1475  if (img_id <= 0) {
1476  dln_loaderror("Failed to load add_on %.200s error_code=%x",
1477  file, img_id);
1478  }
1479 
1480  /* find symbol for module initialize function. */
1481  /* The Be Book KernelKit Images section described to use
1482  B_SYMBOL_TYPE_TEXT for symbol of function, not
1483  B_SYMBOL_TYPE_CODE. Why ? */
1484  /* strcat(init_fct_symname, "__Fv"); */ /* parameter nothing. */
1485  /* "__Fv" dont need! The Be Book Bug ? */
1486  err_stat = get_image_symbol(img_id, buf,
1487  B_SYMBOL_TYPE_TEXT, (void **)&init_fct);
1488 
1489  if (err_stat != B_NO_ERROR) {
1490  char real_name[MAXPATHLEN];
1491 
1492  strlcpy(real_name, buf, MAXPATHLEN);
1493  strlcat(real_name, "__Fv", MAXPATHLEN);
1494  err_stat = get_image_symbol(img_id, real_name,
1495  B_SYMBOL_TYPE_TEXT, (void **)&init_fct);
1496  }
1497 
1498  if ((B_BAD_IMAGE_ID == err_stat) || (B_BAD_INDEX == err_stat)) {
1499  unload_add_on(img_id);
1500  dln_loaderror("Failed to lookup Init function %.200s", file);
1501  }
1502  else if (B_NO_ERROR != err_stat) {
1503  char errmsg[] = "Internal of BeOS version. %.200s (symbol_name = %s)";
1504  unload_add_on(img_id);
1505  dln_loaderror(errmsg, strerror(err_stat), buf);
1506  }
1507 
1508  /* call module initialize function. */
1509  (*init_fct)();
1510  return (void*)img_id;
1511  }
1512 #endif /* __BEOS__ || __HAIKU__ */
1513 
1514 #ifndef DLN_DEFINED
1515  dln_notimplement();
1516 #endif
1517 
1518 #endif /* USE_DLN_A_OUT */
1519 #endif
1520 #if !defined(_AIX) && !defined(NeXT)
1521  failed:
1522  dln_loaderror("%s - %s", error, file);
1523 #endif
1524 
1525  return 0; /* dummy return */
1526 }
#define dln_exit
Definition: dln.c:21
VALUE data
Definition: tcltklib.c:3360
static void dln_loaderror(const char *format,...)
Definition: dln.c:93
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: ripper.y:20
RUBY_SYMBOL_EXPORT_BEGIN void * alloca()
int register char * block
Definition: crypt.c:949
VALUE sym
Definition: tkutil.c:1299
VP_EXPORT int
Definition: bigdecimal.c:5172
memo u1 value
Definition: enum.c:587
size_t strlen(const char *)
switch(f)
Definition: bigdecimal.c:5877
#define dln_memerror
Definition: dln.c:20
int st_lookup(st_table *, st_data_t, st_data_t *)
#define MAXPATHLEN
Definition: dln.c:67
st_table * st_init_numtable(void)
Definition: st.c:272
static const char funcname_prefix[sizeof(FUNCNAME_PREFIX)-1]
Definition: dln.c:138
gz path
Definition: zlib.c:2279
#define dln_find_file_r
Definition: win32.c:76
st_table * st_init_strtable(void)
Definition: st.c:284
int size
Definition: encoding.c:49
if(args--[1]==0)
Definition: array.c:3187
VALUE tbl
Definition: tkutil.c:1280
i
Definition: enum.c:446
RUBY_EXTERN size_t strlcpy(char *, const char *, size_t)
#define dln_notimplement
Definition: dln.c:19
int st_delete(st_table *, st_data_t *, st_data_t *)
strcpy(cmd2, cmd)
RUBY_EXTERN size_t strlcat(char *, const char *, size_t)
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
Definition: sdbm.h:50
int flags
Definition: tcltklib.c:3015
va_end(args)
static VALUE VALUE obj
Definition: tcltklib.c:3150
#define xmalloc
#define xrealloc
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
#define isdirsep(x)
Definition: dln.c:120
static int VALUE key
Definition: tkutil.c:265
int len
Definition: enumerator.c:1332
VALUE arg
Definition: enum.c:2427
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
Definition: st.c:1034
int errno
#define TRUE
Definition: nkf.h:175
void rb_fatal(const char *fmt,...)
Definition: error.c:1911
char * name1
Definition: tcltklib.c:4199
register char * s
Definition: os2.c:56
VP_EXPORT void
Definition: bigdecimal.c:5207
#define strdup(s)
Definition: util.h:67
#define init_funcname(buf, file)
Definition: dln.c:140
ssize_t ex
Definition: bigdecimal.c:5211
#define EXTERNAL_PREFIX
Definition: dln.c:112
#define free(x)
Definition: dln.c:50
void * dln_load(const char *file)
Definition: dln.c:1250
VpDivd * c
Definition: bigdecimal.c:1223
static const char * dln_strerror(void)
Definition: dln.c:1149
RUBY_EXTERN char * strerror(int)
Definition: strerror.c:11
#define getenv(name)
Definition: win32.c:66
gz end
Definition: zlib.c:2272
void * ruby_xmalloc(size_t size)
Definition: gc.c:6159
static size_t init_funcname_len(const char **file)
Definition: dln.c:124
VALUE name
Definition: enum.c:572
#define DLN_ERROR()
static long rb_str_index(VALUE str, VALUE sub, long offset)
Definition: string.c:2685
#define FUNCNAME_PREFIX
Definition: dln.c:114
int st_insert(st_table *, st_data_t, st_data_t)
WCHAR * rb_w32_mbstr_to_wstr(UINT, const char *, int, long *)
Definition: win32.c:1976
register C_block * p
Definition: crypt.c:309
#define translit_separator(str)
Definition: dln.c:1246
#define xcalloc
unsigned long VALUE
Definition: ripper.y:88
#define snprintf
#define NULL
Definition: _sdbm.c:102
st_index_t num_entries
Definition: ripper.y:85
volatile VALUE result
Definition: enum.c:1989
static ULONG(STDMETHODCALLTYPE AddRef)(IDispatch __RPC_FAR *This)
Definition: win32ole.c:615
void st_free_table(st_table *)
Definition: st.c:334
#define dln_find_exe_r
Definition: win32.c:75