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