Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

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