From 1f08b0d18d9d1178cef1eac91f6ea97cb6b437eb Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 24 Mar 2021 20:13:55 +0900 Subject: [PATCH] Removed dln_a_out a.out format is considered extinct nowadays. --- configure.ac | 64 +-- dln.c | 1002 +------------------------------------------ dln.h | 5 - include/ruby/ruby.h | 5 - ruby.c | 9 - 5 files changed, 16 insertions(+), 1069 deletions(-) diff --git a/configure.ac b/configure.ac index a3641cb101..58aa35a9da 100644 --- a/configure.ac +++ b/configure.ac @@ -1092,7 +1092,6 @@ main() AC_LIBOBJ([langinfo]) ], [mingw*], [ LIBS="-lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi $LIBS" - ac_cv_header_a_out_h=no ac_cv_header_pwd_h=no ac_cv_header_utime_h=no ac_cv_header_sys_ioctl_h=no @@ -1212,7 +1211,6 @@ dnl AC_HEADER_STDC has been checked in AC_USE_SYSTEM_EXTENSIONS AC_HEADER_STDBOOL AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS(a.out.h) AC_CHECK_HEADERS(atomic.h) AC_CHECK_HEADERS(copyfile.h) AC_CHECK_HEADERS(direct.h) @@ -2710,16 +2708,13 @@ main(int argc, char *argv[]) : "runtime section" && { dnl wheather use dln_a_out or not AC_ARG_WITH(dln-a-out, - AS_HELP_STRING([--with-dln-a-out], [use dln_a_out if possible]), + AS_HELP_STRING([--with-dln-a-out], [dln_a_out is deprecated]), [ AS_CASE([$withval], [yes], [ - AS_IF([test "$enable_shared" = yes], [ - AC_MSG_ERROR(dln_a_out can not make shared library) - ]) - with_dln_a_out=yes], - [ - with_dln_a_out=no])], [with_dln_a_out=no]) + AC_MSG_ERROR(dln_a_out no longer supported) + ]) +]) AC_CACHE_CHECK(whether ELF binaries are produced, rb_cv_binary_elf, [AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[ @@ -2729,9 +2724,6 @@ rb_cv_binary_elf=no)]) AS_IF([test "$rb_cv_binary_elf" = yes], [ AC_DEFINE(USE_ELF) - AS_IF([test "$with_dln_a_out" = yes], [ - AC_MSG_ERROR(dln_a_out does not work with ELF) - ]) AC_CHECK_HEADERS([elf.h elf_abi.h]) AS_IF([test $ac_cv_header_elf_h = yes -o $ac_cv_header_elf_abi_h = yes], [ AC_LIBOBJ([addr2line]) @@ -2747,7 +2739,7 @@ AS_IF([test "$ac_cv_header_mach_o_loader_h" = yes], [ AS_CASE(["$target_os"], [linux* | gnu* | k*bsd*-gnu | bsdi* | kopensolaris*-gnu], [ AS_IF([test "$rb_cv_binary_elf" = no], [ - with_dln_a_out=yes + AC_MSG_ERROR(Not ELF) ], [ LDFLAGS="$LDFLAGS -rdynamic" ])]) @@ -2781,7 +2773,7 @@ AC_SUBST(ASMEXT, S)dnl STATIC= -AS_IF([test "$with_dln_a_out" != yes], [ +: "dlopen" && { rb_cv_dlopen=unknown AC_MSG_CHECKING(whether OS depend dynamic link works) AS_IF([test "$GCC" = yes], [ @@ -2806,8 +2798,9 @@ AS_IF([test "$with_dln_a_out" != yes], [ [esix*|uxpds*], [CCDLFLAGS="$CCDLFLAGS -KPIC"], [: ${CCDLFLAGS=""}]) ]) +} - +: "rpath" && { AC_ARG_ENABLE(rpath, AS_HELP_STRING([--enable-rpath], [embed run path into extension libraries. enabled by default on ELF platforms]), @@ -2933,7 +2926,8 @@ AS_IF([test "$with_dln_a_out" != yes], [ RPATHFLAG=" ${rpathflag}%1\$-s" ]) ]) -]) +} + AS_IF([test "${LDSHAREDXX}" = ""], [ AS_CASE(["${LDSHARED}"], [*'$(CC)'*], [ @@ -3063,33 +3057,7 @@ AC_ARG_WITH(valgrind, AS_IF([test x$with_valgrind != xno], [AC_CHECK_HEADERS(valgrind/memcheck.h)]) -dln_a_out_works=no -AS_IF([test "$ac_cv_header_a_out_h" = yes], [ - AS_IF([test "$with_dln_a_out" = yes || test "$rb_cv_dlopen" = unknown], [ - cat confdefs.h > config.h - AC_CACHE_CHECK(whether matz's dln works, rb_cv_dln_a_out, - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#define USE_DLN_A_OUT -#include "dln.c" -]], [[]])], - rb_cv_dln_a_out=yes, - rb_cv_dln_a_out=no)]) - AS_IF([test "$rb_cv_dln_a_out" = yes], [ - dln_a_out_works=yes - AC_DEFINE(USE_DLN_A_OUT) - ]) - ]) -]) - -AS_IF([test "$dln_a_out_works" = yes], [ - AS_IF([test "$GCC" = yes], [ - STATIC=-static - ], [ - STATIC=-Bstatic - ]) - DLEXT=so - CCDLFLAGS= -], [ +: "dlext & soext" && { AS_CASE(["$target_os"], [hpux*], [ DLEXT=sl], @@ -3102,9 +3070,10 @@ AS_IF([test "$dln_a_out_works" = yes], [ DLEXT=so], [ DLEXT=so]) -]) : ${SOEXT="${DLEXT}"} AC_SUBST(SOEXT) +} + AS_IF([test "$rb_cv_dlopen:$load_relative" = yes:yes], [ AS_IF([test "$ac_cv_func_dladdr" = yes], [ LOAD_RELATIVE=1 @@ -3124,9 +3093,7 @@ test ".$DLEXT" = "." || AC_DEFINE_UNQUOTED(DLEXT, ".$DLEXT") test ".$DLEXT2" = "." || AC_DEFINE_UNQUOTED(DLEXT2, ".$DLEXT2") AC_SUBST(DLEXT) -AS_IF([test "$with_dln_a_out" = yes], [ - STRIP=true -], [ +: "strip" && { AC_MSG_CHECKING([for $STRIP flags]) AC_LINK_IFELSE([AC_LANG_PROGRAM], [AS_IF( ["${STRIP}" -A -n conftest$ac_exeext 2>/dev/null], [ @@ -3140,8 +3107,7 @@ AS_IF([test "$with_dln_a_out" = yes], [ AC_MSG_RESULT([none needed]) ]) ]) -]) - +} AC_ARG_WITH(ext, AS_HELP_STRING([--with-ext=EXTS], diff --git a/dln.c b/dln.c index 48d40906b8..b0508989d4 100644 --- a/dln.c +++ b/dln.c @@ -28,10 +28,6 @@ static void dln_loaderror(const char *format, ...); # include #endif -#ifdef USE_DLN_A_OUT -char *dln_argv0; -#endif - #if defined(HAVE_ALLOCA_H) #include #endif @@ -98,7 +94,7 @@ dln_loaderror(const char *format, ...) } #endif -#if defined(HAVE_DLOPEN) && !defined(USE_DLN_A_OUT) && !defined(_AIX) && !defined(MACOSX_DYLD) && !defined(_UNICOSMP) +#if defined(HAVE_DLOPEN) && !defined(_AIX) && !defined(MACOSX_DYLD) && !defined(_UNICOSMP) /* dynamic load with dlopen() */ # define USE_DLN_DLOPEN #endif @@ -147,972 +143,6 @@ static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX *(buf) = tmp;\ } while (0) -#ifdef USE_DLN_A_OUT - -#ifndef LIBC_NAME -# define LIBC_NAME "libc.a" -#endif - -#ifndef DLN_DEFAULT_LIB_PATH -# define DLN_DEFAULT_LIB_PATH "/lib:/usr/lib:/usr/local/lib:." -#endif - -#include -#include -#include -#include - -static int dln_errno; - -#define DLN_ENOEXEC ENOEXEC /* Exec format error */ -#define DLN_ECONFL 1201 /* Symbol name conflict */ -#define DLN_ENOINIT 1202 /* No initializer given */ -#define DLN_EUNDEF 1203 /* Undefine symbol remains */ -#define DLN_ENOTLIB 1204 /* Not a library file */ -#define DLN_EBADLIB 1205 /* Malformed library file */ -#define DLN_EINIT 1206 /* Not initialized */ - -static int dln_init_p = 0; - -#include -#include -#ifndef N_COMM -# define N_COMM 0x12 -#endif -#ifndef N_MAGIC -# define N_MAGIC(x) (x).a_magic -#endif - -#define INVALID_OBJECT(h) (N_MAGIC(h) != OMAGIC) - -#include "ruby/util.h" -#include "ruby/st.h" - -static st_table *sym_tbl; -static st_table *undef_tbl; - -static int load_lib(const char *); - -static int -load_header(int fd, struct exec *hdrp, long disp) -{ - int size; - - lseek(fd, disp, 0); - size = read(fd, hdrp, sizeof(struct exec)); - if (size == -1) { - dln_errno = errno; - return -1; - } - if (size != sizeof(struct exec) || N_BADMAG(*hdrp)) { - dln_errno = DLN_ENOEXEC; - return -1; - } - return 0; -} - -#if defined(sequent) -#define RELOC_SYMBOL(r) ((r)->r_symbolnum) -#define RELOC_MEMORY_SUB_P(r) ((r)->r_bsr) -#define RELOC_PCREL_P(r) ((r)->r_pcrel || (r)->r_bsr) -#define RELOC_TARGET_SIZE(r) ((r)->r_length) -#endif - -/* Default macros */ -#ifndef RELOC_ADDRESS -#define RELOC_ADDRESS(r) ((r)->r_address) -#define RELOC_EXTERN_P(r) ((r)->r_extern) -#define RELOC_SYMBOL(r) ((r)->r_symbolnum) -#define RELOC_MEMORY_SUB_P(r) 0 -#define RELOC_PCREL_P(r) ((r)->r_pcrel) -#define RELOC_TARGET_SIZE(r) ((r)->r_length) -#endif - -#if defined(__sun) && defined(__sparc) -/* Sparc (Sun 4) macros */ -# undef relocation_info -# define relocation_info reloc_info_sparc -# define R_RIGHTSHIFT(r) (reloc_r_rightshift[(r)->r_type]) -# define R_BITSIZE(r) (reloc_r_bitsize[(r)->r_type]) -# define R_LENGTH(r) (reloc_r_length[(r)->r_type]) -static const int reloc_r_rightshift[] = { - 0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 0, 0, 0, -}; -static const int reloc_r_bitsize[] = { - 8, 16, 32, 8, 16, 32, 30, 22, 22, 22, 13, 10, 32, 32, 16, -}; -static const int reloc_r_length[] = { - 0, 1, 2, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -}; -# define R_PCREL(r) \ - ((r)->r_type >= RELOC_DISP8 && (r)->r_type <= RELOC_WDISP22) -# define R_SYMBOL(r) ((r)->r_index) -#endif - -#if defined(sequent) -#define R_SYMBOL(r) ((r)->r_symbolnum) -#define R_MEMORY_SUB(r) ((r)->r_bsr) -#define R_PCREL(r) ((r)->r_pcrel || (r)->r_bsr) -#define R_LENGTH(r) ((r)->r_length) -#endif - -#ifndef R_SYMBOL -# define R_SYMBOL(r) ((r)->r_symbolnum) -# define R_MEMORY_SUB(r) 0 -# define R_PCREL(r) ((r)->r_pcrel) -# define R_LENGTH(r) ((r)->r_length) -#endif - -static struct relocation_info * -load_reloc(int fd, struct exec *hdrp, long disp) -{ - struct relocation_info *reloc; - int size; - - lseek(fd, disp + N_TXTOFF(*hdrp) + hdrp->a_text + hdrp->a_data, 0); - size = hdrp->a_trsize + hdrp->a_drsize; - reloc = (struct relocation_info*)xmalloc(size); - if (reloc == NULL) { - dln_errno = errno; - return NULL; - } - - if (read(fd, reloc, size) != size) { - dln_errno = errno; - free(reloc); - return NULL; - } - - return reloc; -} - -static struct nlist * -load_sym(int fd, struct exec *hdrp, long disp) -{ - struct nlist * buffer; - struct nlist * sym; - struct nlist * end; - long displ; - int size; - - lseek(fd, N_SYMOFF(*hdrp) + hdrp->a_syms + disp, 0); - if (read(fd, &size, sizeof(int)) != sizeof(int)) { - goto err_noexec; - } - - buffer = (struct nlist*)xmalloc(hdrp->a_syms + size); - if (buffer == NULL) { - dln_errno = errno; - return NULL; - } - - lseek(fd, disp + N_SYMOFF(*hdrp), 0); - if (read(fd, buffer, hdrp->a_syms + size) != (ssize_t)(hdrp->a_syms + size)) { - free(buffer); - goto err_noexec; - } - - sym = buffer; - end = sym + hdrp->a_syms / sizeof(struct nlist); - displ = (long)buffer + (long)(hdrp->a_syms); - - while (sym < end) { - sym->n_un.n_name = (char*)sym->n_un.n_strx + displ; - sym++; - } - return buffer; - - err_noexec: - dln_errno = DLN_ENOEXEC; - return NULL; -} - -static st_table * -sym_hash(struct exec *hdrp, struct nlist *syms) -{ - st_table *tbl; - struct nlist *sym = syms; - struct nlist *end = syms + (hdrp->a_syms / sizeof(struct nlist)); - - tbl = st_init_strtable(); - if (tbl == NULL) { - dln_errno = errno; - return NULL; - } - - while (sym < end) { - st_insert(tbl, (st_data_t)sym->n_un.n_name, (st_data_t)sym); - sym++; - } - return tbl; -} - -static int -dln_init(const char *prog) -{ - char *file, fbuf[MAXPATHLEN]; - int fd; - struct exec hdr; - struct nlist *syms; - - if (dln_init_p == 1) return 0; - - file = dln_find_exe_r(prog, NULL, fbuf, sizeof(fbuf)); - if (file == NULL || (fd = open(file, O_RDONLY)) < 0) { - dln_errno = errno; - return -1; - } - - if (load_header(fd, &hdr, 0) == -1) return -1; - syms = load_sym(fd, &hdr, 0); - if (syms == NULL) { - close(fd); - return -1; - } - sym_tbl = sym_hash(&hdr, syms); - if (sym_tbl == NULL) { /* file may be start with #! */ - char c = '\0'; - char buf[MAXPATHLEN]; - char *p; - - free(syms); - lseek(fd, 0L, 0); - if (read(fd, &c, 1) == -1) { - dln_errno = errno; - return -1; - } - if (c != '#') goto err_noexec; - if (read(fd, &c, 1) == -1) { - dln_errno = errno; - return -1; - } - if (c != '!') goto err_noexec; - - p = buf; - /* skip forwarding spaces */ - while (read(fd, &c, 1) == 1) { - if (c == '\n') goto err_noexec; - if (c != '\t' && c != ' ') { - *p++ = c; - break; - } - } - /* read in command name */ - while (read(fd, p, 1) == 1) { - if (*p == '\n' || *p == '\t' || *p == ' ') break; - p++; - if (p-buf >= MAXPATHLEN) { - dln_errno = ENAMETOOLONG; - return -1; - } - } - *p = '\0'; - - return dln_init(buf); - } - dln_init_p = 1; - undef_tbl = st_init_strtable(); - close(fd); - return 0; - - err_noexec: - close(fd); - dln_errno = DLN_ENOEXEC; - return -1; -} - -static long -load_text_data(int fd, struct exec *hdrp, int bss, long disp) -{ - int size; - unsigned char* addr; - - lseek(fd, disp + N_TXTOFF(*hdrp), 0); - size = hdrp->a_text + hdrp->a_data; - - if (bss == -1) size += hdrp->a_bss; - else if (bss > 1) size += bss; - - addr = (unsigned char*)xmalloc(size); - if (addr == NULL) { - dln_errno = errno; - return 0; - } - - if (read(fd, addr, size) != size) { - dln_errno = errno; - free(addr); - return 0; - } - - if (bss == -1) { - memset(addr + hdrp->a_text + hdrp->a_data, 0, hdrp->a_bss); - } - else if (bss > 0) { - memset(addr + hdrp->a_text + hdrp->a_data, 0, bss); - } - - return (long)addr; -} - -static int -undef_print(st_data_t k, st_data_t v, st_data_t a) -{ - char *key = (char *)k; - fprintf(stderr, " %s\n", key); - return ST_CONTINUE; -} - -static void -dln_print_undef(void) -{ - fprintf(stderr, " Undefined symbols:\n"); - st_foreach(undef_tbl, undef_print, 0); -} - -static void -dln_undefined(void) -{ - if (undef_tbl->num_entries > 0) { - fprintf(stderr, "dln: Calling undefined function\n"); - dln_print_undef(); - dln_exit(1); - } -} - -struct undef { - char *name; - struct relocation_info reloc; - long base; - char *addr; - union { - char c; - short s; - long l; - } u; -}; - -static st_table *reloc_tbl = NULL; -static void -link_undef(const char *name, long base, struct relocation_info *reloc) -{ - static int u_no = 0; - struct undef *obj; - char *addr = (char*)(reloc->r_address + base); - - obj = (struct undef*)xmalloc(sizeof(struct undef)); - obj->name = strdup(name); - obj->reloc = *reloc; - obj->base = base; - switch (R_LENGTH(reloc)) { - case 0: /* byte */ - obj->u.c = *addr; - break; - case 1: /* word */ - obj->u.s = *(short*)addr; - break; - case 2: /* long */ - obj->u.l = *(long*)addr; - break; - } - if (reloc_tbl == NULL) { - reloc_tbl = st_init_numtable(); - } - st_insert(reloc_tbl, u_no++, (st_data_t)obj); -} - -struct reloc_arg { - const char *name; - long value; -}; - -static int -reloc_undef(st_data_t no, st_data_t v, st_data_t a) -{ - struct undef *undef = (void *)v; - struct reloc_arg *arg = (void *)a; - int datum; - char *address; -#if defined(__sun) && defined(__sparc) - unsigned int mask = 0; -#endif - - if (strcmp(arg->name, undef->name) != 0) return ST_CONTINUE; - address = (char*)(undef->base + undef->reloc.r_address); - datum = arg->value; - - if (R_PCREL(&(undef->reloc))) datum -= undef->base; -#if defined(__sun) && defined(__sparc) - datum += undef->reloc.r_addend; - datum >>= R_RIGHTSHIFT(&(undef->reloc)); - mask = (1 << R_BITSIZE(&(undef->reloc))) - 1; - mask |= mask -1; - datum &= mask; - switch (R_LENGTH(&(undef->reloc))) { - case 0: - *address = undef->u.c; - *address &= ~mask; - *address |= datum; - break; - case 1: - *(short *)address = undef->u.s; - *(short *)address &= ~mask; - *(short *)address |= datum; - break; - case 2: - *(long *)address = undef->u.l; - *(long *)address &= ~mask; - *(long *)address |= datum; - break; - } -#else - switch (R_LENGTH(&(undef->reloc))) { - case 0: /* byte */ - if (R_MEMORY_SUB(&(undef->reloc))) - *address = datum - *address; - else *address = undef->u.c + datum; - break; - case 1: /* word */ - if (R_MEMORY_SUB(&(undef->reloc))) - *(short*)address = datum - *(short*)address; - else *(short*)address = undef->u.s + datum; - break; - case 2: /* long */ - if (R_MEMORY_SUB(&(undef->reloc))) - *(long*)address = datum - *(long*)address; - else *(long*)address = undef->u.l + datum; - break; - } -#endif - free(undef->name); - free(undef); - return ST_DELETE; -} - -static void -unlink_undef(const char *name, long value) -{ - struct reloc_arg arg; - - arg.name = name; - arg.value = value; - st_foreach(reloc_tbl, reloc_undef, (st_data_t)&arg); -} - -#ifdef N_INDR -struct indr_data { - char *name0, *name1; -}; - -static int -reloc_repl(st_data_t no, st_data_t v, st_data_t a) -{ - struct undef *undef = (void *)v; - struct indr_data *data = (void *)a; - if (strcmp(data->name0, undef->name) == 0) { - free(undef->name); - undef->name = strdup(data->name1); - } - return ST_CONTINUE; -} -#endif - -static int -load_1(int fd, long disp, const char *need_init) -{ - static const char *libc = LIBC_NAME; - struct exec hdr; - struct relocation_info *reloc = NULL; - long block = 0; - long new_common = 0; /* Length of new common */ - struct nlist *syms = NULL; - struct nlist *sym; - struct nlist *end; - int init_p = 0; - - if (load_header(fd, &hdr, disp) == -1) return -1; - if (INVALID_OBJECT(hdr)) { - dln_errno = DLN_ENOEXEC; - return -1; - } - reloc = load_reloc(fd, &hdr, disp); - if (reloc == NULL) return -1; - - syms = load_sym(fd, &hdr, disp); - if (syms == NULL) { - free(reloc); - return -1; - } - - sym = syms; - end = syms + (hdr.a_syms / sizeof(struct nlist)); - while (sym < end) { - struct nlist *old_sym; - st_data_t old_data; - int value = sym->n_value; - -#ifdef N_INDR - if (sym->n_type == (N_INDR | N_EXT)) { - char *key = sym->n_un.n_name; - - if (st_lookup(sym_tbl, (st_data_t)sym[1].n_un.n_name, &old_data)) { - old_sym = (struct nlist *)old_data; - if (st_delete(undef_tbl, (st_data_t*)&key, NULL)) { - unlink_undef(key, old_sym->n_value); - free(key); - } - } - else { - struct indr_data data; - - data.name0 = sym->n_un.n_name; - data.name1 = sym[1].n_un.n_name; - st_foreach(reloc_tbl, reloc_repl, (st_data_t)&data); - - st_insert(undef_tbl, (st_data_t)strdup(sym[1].n_un.n_name), 0); - if (st_delete(undef_tbl, (st_data_t*)&key, NULL)) { - free(key); - } - } - sym += 2; - continue; - } -#endif - if (sym->n_type == (N_UNDF | N_EXT)) { - if (st_lookup(sym_tbl, (st_data_t)sym->n_un.n_name, &old_data) == 0) { - old_sym = NULL; - } - else { - old_sym = (struct nlist *)old_data; - } - - if (value) { - if (old_sym) { - sym->n_type = N_EXT | N_COMM; - sym->n_value = old_sym->n_value; - } - else { - int rnd = - value >= (int)sizeof(double) ? sizeof(double) - 1 - : value >= (int)sizeof(long) ? sizeof(long) - 1 - : sizeof(short) - 1; - - sym->n_type = N_COMM; - new_common += rnd; - new_common &= ~(long)rnd; - sym->n_value = new_common; - new_common += value; - } - } - else { - if (old_sym) { - sym->n_type = N_EXT | N_COMM; - sym->n_value = old_sym->n_value; - } - else { - sym->n_value = (unsigned long)dln_undefined; - st_insert(undef_tbl, (st_data_t)strdup(sym->n_un.n_name), 0); - } - } - } - sym++; - } - - block = load_text_data(fd, &hdr, hdr.a_bss + new_common, disp); - if (block == 0) goto err_exit; - - sym = syms; - while (sym < end) { - struct nlist *new_sym; - st_data_t new_data; - char *key; - - switch (sym->n_type) { - case N_COMM: - sym->n_value += hdr.a_text + hdr.a_data; - case N_TEXT|N_EXT: - case N_DATA|N_EXT: - - sym->n_value += block; - - if (st_lookup(sym_tbl, (st_data_t)sym->n_un.n_name, &new_data) != 0 - && (new_sym = (struct nlist *)new_data)->n_value != (unsigned long)dln_undefined) { - dln_errno = DLN_ECONFL; - goto err_exit; - } - - key = sym->n_un.n_name; - if (st_delete(undef_tbl, (st_data_t*)&key, NULL) != 0) { - unlink_undef(key, sym->n_value); - free(key); - } - - new_sym = (struct nlist*)xmalloc(sizeof(struct nlist)); - *new_sym = *sym; - new_sym->n_un.n_name = strdup(sym->n_un.n_name); - st_insert(sym_tbl, (st_data_t)new_sym->n_un.n_name, (st_data_t)new_sym); - break; - - case N_TEXT: - case N_DATA: - sym->n_value += block; - break; - } - sym++; - } - - /* - * First comes the text-relocation - */ - { - struct relocation_info * rel = reloc; - struct relocation_info * rel_beg = reloc + - (hdr.a_trsize/sizeof(struct relocation_info)); - struct relocation_info * rel_end = reloc + - (hdr.a_trsize+hdr.a_drsize)/sizeof(struct relocation_info); - - while (rel < rel_end) { - char *address = (char*)(rel->r_address + block); - long datum = 0; -#if defined(__sun) && defined(__sparc) - unsigned int mask = 0; -#endif - - if (rel >= rel_beg) - address += hdr.a_text; - - if (rel->r_extern) { /* Look it up in symbol-table */ - sym = &(syms[R_SYMBOL(rel)]); - switch (sym->n_type) { - case N_EXT|N_UNDF: - link_undef(sym->n_un.n_name, block, rel); - case N_EXT|N_COMM: - case N_COMM: - datum = sym->n_value; - break; - default: - goto err_exit; - } - } /* end.. look it up */ - else { /* is static */ - switch (R_SYMBOL(rel)) { - case N_TEXT: - case N_DATA: - datum = block; - break; - case N_BSS: - datum = block + new_common; - break; - case N_ABS: - break; - } - } /* end .. is static */ - if (R_PCREL(rel)) datum -= block; - -#if defined(__sun) && defined(__sparc) - datum += rel->r_addend; - datum >>= R_RIGHTSHIFT(rel); - mask = (1 << R_BITSIZE(rel)) - 1; - mask |= mask -1; - datum &= mask; - - switch (R_LENGTH(rel)) { - case 0: - *address &= ~mask; - *address |= datum; - break; - case 1: - *(short *)address &= ~mask; - *(short *)address |= datum; - break; - case 2: - *(long *)address &= ~mask; - *(long *)address |= datum; - break; - } -#else - switch (R_LENGTH(rel)) { - case 0: /* byte */ - if (datum < -128 || datum > 127) goto err_exit; - *address += datum; - break; - case 1: /* word */ - *(short *)address += datum; - break; - case 2: /* long */ - *(long *)address += datum; - break; - } -#endif - rel++; - } - } - - if (need_init) { - int len; - char **libs_to_be_linked = 0; - char *buf; - - if (undef_tbl->num_entries > 0) { - if (load_lib(libc) == -1) goto err_exit; - } - - init_funcname(&buf, need_init); - len = strlen(buf); - - for (sym = syms; symn_un.n_name; - if (name[0] == '_' && sym->n_value >= (unsigned long)block) { - if (strcmp(name+1, "dln_libs_to_be_linked") == 0) { - libs_to_be_linked = (char**)sym->n_value; - } - else if (strcmp(name+1, buf) == 0) { - init_p = 1; - ((int (*)())sym->n_value)(); - } - } - } - if (libs_to_be_linked && undef_tbl->num_entries > 0) { - while (*libs_to_be_linked) { - load_lib(*libs_to_be_linked); - libs_to_be_linked++; - } - } - } - free(reloc); - free(syms); - if (need_init) { - if (init_p == 0) { - dln_errno = DLN_ENOINIT; - return -1; - } - if (undef_tbl->num_entries > 0) { - if (load_lib(libc) == -1) goto err_exit; - if (undef_tbl->num_entries > 0) { - dln_errno = DLN_EUNDEF; - return -1; - } - } - } - return 0; - - err_exit: - if (syms) free(syms); - if (reloc) free(reloc); - if (block) free((char*)block); - return -1; -} - -struct search_undef_args { - st_table *lib_tbl; - int target_offset; -}; - -static int -search_undef(st_data_t key, st_data_t value, st_data_t a) -{ - struct search_undef_args *args = (void *)a; - st_table *lib_tbl = args->lib_tbl; - st_data_t offset; - - if (st_lookup(lib_tbl, key, &offset) == 0) return ST_CONTINUE; - args->target_offset = (int)offset; - return ST_STOP; -} - -static int -search_undef_target(struct st_table *undef_tbl, struct st_table *lib_tbl) -{ - struct search_undef_args args; - args.lib_tbl = lib_tbl; - args.target_offset = -1; - st_foreach(undef_tbl, search_undef, (st_data_t)&args); - return args.target_offset; -} - -struct symdef { - int rb_str_index; - int lib_offset; -}; - -const char dln_librrb_ary_path[] = DLN_DEFAULT_LIB_PATH; - -static int -load_lib(const char *lib) -{ - const char *path; - char *file, fbuf[MAXPATHLEN]; - char *envpath = 0; - char armagic[SARMAG]; - int fd, size; - struct ar_hdr ahdr; - st_table *lib_tbl = NULL; - int *data, nsym; - struct symdef *base; - char *name_base; - - if (dln_init_p == 0) { - dln_errno = DLN_ENOINIT; - return -1; - } - - if (undef_tbl->num_entries == 0) return 0; - dln_errno = DLN_EBADLIB; - - if (lib[0] == '-' && lib[1] == 'l') { - long len = strlen(lib) + 4; - char *p = alloca(len); - snprintf(p, len, "lib%s.a", lib+2); - lib = p; - } - - /* library search path: */ - /* look for environment variable DLN_LIBRARY_PATH first. */ - /* then variable dln_librrb_ary_path. */ - /* if path is still NULL, use "." for path. */ - path = getenv("DLN_LIBRARY_PATH"); - if (path == NULL) path = dln_librrb_ary_path; - else path = envpath = strdup(path); - - file = dln_find_file_r(lib, path, fbuf, sizeof(fbuf)); - if (envpath) free(envpath); - fd = open(file, O_RDONLY); - if (fd == -1) goto syserr; - size = read(fd, armagic, SARMAG); - if (size == -1) goto syserr; - - if (size != SARMAG) { - dln_errno = DLN_ENOTLIB; - goto badlib; - } - size = read(fd, &ahdr, sizeof(ahdr)); - if (size == -1) goto syserr; - if (size != sizeof(ahdr) || sscanf(ahdr.ar_size, "%d", &size) != 1) { - goto badlib; - } - - if (strncmp(ahdr.ar_name, "__.SYMDEF", 9) == 0) { - /* make hash table from __.SYMDEF */ - int target_offset; - - lib_tbl = st_init_strtable(); - data = (int*)xmalloc(size); - if (data == NULL) goto syserr; - size = read(fd, data, size); - nsym = *data / sizeof(struct symdef); - base = (struct symdef*)(data + 1); - name_base = (char*)(base + nsym) + sizeof(int); - while (nsym > 0) { - char *name = name_base + base->rb_str_index; - - st_insert(lib_tbl, (st_data_t)name, base->lib_offset + sizeof(ahdr)); - nsym--; - base++; - } - while ((target_offset = search_undef_target(undef_tbl, lib_tbl)) != -1) { - if (load_1(fd, target_offset, 0) == -1) { - st_free_table(lib_tbl); - free(data); - goto badlib; - } - if (undef_tbl->num_entries == 0) break; - } - free(data); - st_free_table(lib_tbl); - } - else { - /* linear library, need to scan (FUTURE) */ - - for (;;) { - int offset = SARMAG; - int found = 0; - struct exec hdr; - struct nlist *syms, *sym, *end; - - while (undef_tbl->num_entries > 0) { - found = 0; - lseek(fd, offset, 0); - size = read(fd, &ahdr, sizeof(ahdr)); - if (size == -1) goto syserr; - if (size == 0) break; - if (size != sizeof(ahdr) - || sscanf(ahdr.ar_size, "%d", &size) != 1) { - goto badlib; - } - offset += sizeof(ahdr); - if (load_header(fd, &hdr, offset) == -1) - goto badlib; - syms = load_sym(fd, &hdr, offset); - if (syms == NULL) goto badlib; - sym = syms; - end = syms + (hdr.a_syms / sizeof(struct nlist)); - while (sym < end) { - if (sym->n_type == (N_EXT|N_TEXT) - && st_lookup(undef_tbl, (st_data_t)sym->n_un.n_name, NULL)) { - break; - } - sym++; - } - if (sym < end) { - found++; - free(syms); - if (load_1(fd, offset, 0) == -1) { - goto badlib; - } - } - offset += size; - if (offset & 1) offset++; - } - if (found) break; - } - } - close(fd); - return 0; - - syserr: - dln_errno = errno; - badlib: - if (fd >= 0) close(fd); - return -1; -} - -static int -load(const char *file) -{ - int fd; - int result; - - if (dln_init_p == 0) { - if (dln_init(dln_argv0) == -1) return -1; - } - result = strlen(file); - if (file[result-1] == 'a') { - return load_lib(file); - } - - fd = open(file, O_RDONLY); - if (fd == -1) { - dln_errno = errno; - return -1; - } - result = load_1(fd, 0, file); - close(fd); - - return result; -} - -void* -dln_sym(const char *name) -{ - st_data_t sym; - - if (st_lookup(sym_tbl, (st_data_t)name, &sym)) - return (void*)((struct nlist *)sym)->n_value; - return NULL; -} - -#endif /* USE_DLN_A_OUT */ - #ifdef USE_DLN_DLOPEN # include #endif @@ -1173,27 +203,6 @@ dln_strerror(char *message, size_t size) static const char * dln_strerror(void) { -#ifdef USE_DLN_A_OUT - char *strerror(); - - switch (dln_errno) { - case DLN_ECONFL: - return "Symbol name conflict"; - case DLN_ENOINIT: - return "No initializer given"; - case DLN_EUNDEF: - return "Unresolved symbols"; - case DLN_ENOTLIB: - return "Not a library file"; - case DLN_EBADLIB: - return "Malformed library file"; - case DLN_EINIT: - return "Not initialized"; - default: - return strerror(dln_errno); - } -#endif - #ifdef USE_DLN_DLOPEN return (char*)dlerror(); #endif @@ -1340,14 +349,6 @@ dln_load(const char *file) (*init_fct)(); return handle; #else -#ifdef USE_DLN_A_OUT - if (load(file) == -1) { - error = dln_strerror(); - goto failed; - } - return 0; -#else - char *buf; /* Load the file as an object one */ init_funcname(&buf, file); @@ -1492,7 +493,6 @@ dln_load(const char *file) dln_notimplement(); #endif -#endif /* USE_DLN_A_OUT */ #endif #if !defined(_AIX) && !defined(NeXT) failed: diff --git a/dln.h b/dln.h index 99106fd22b..902f753450 100644 --- a/dln.h +++ b/dln.h @@ -24,11 +24,6 @@ RUBY_SYMBOL_EXPORT_BEGIN char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); - -#ifdef USE_DLN_A_OUT -extern char *dln_argv0; -#endif - void *dln_load(const char*); RUBY_SYMBOL_EXPORT_END diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index c68168d500..ce5f6c652d 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -100,11 +100,6 @@ VALUE rb_require(const char*); #include "ruby/intern.h" -#if defined(EXTLIB) && defined(USE_DLN_A_OUT) -/* hook for external modules */ -static char *dln_libs_to_be_linked[] = { EXTLIB, 0 }; -#endif - #define RUBY_VM 1 /* YARV */ #define HAVE_NATIVETHREAD int ruby_native_thread_p(void); diff --git a/ruby.c b/ruby.c index 4023177028..21c2daa977 100644 --- a/ruby.c +++ b/ruby.c @@ -2554,12 +2554,6 @@ ruby_set_argv(int argc, char **argv) int i; VALUE av = rb_argv; -#if defined(USE_DLN_A_OUT) - if (origarg.argc > 0 && origarg.argv) - dln_argv0 = origarg.argv[0]; - else if (argc > 0 && argv) - dln_argv0 = argv[0]; -#endif rb_ary_clear(av); for (i = 0; i < argc; i++) { VALUE arg = external_str_new_cstr(argv[i]); @@ -2638,9 +2632,6 @@ ruby_sysinit(int *argc, char ***argv) if (*argc >= 0 && *argv) { origarg.argc = *argc; origarg.argv = *argv; -#if defined(USE_DLN_A_OUT) - dln_argv0 = origarg.argv[0]; -#endif } fill_standard_fds(); }