modules: drop a.out module support
authorSimon Schubert <corecode@dragonflybsd.org>
Thu, 3 Sep 2009 20:29:02 +0000 (22:29 +0200)
committerSimon Schubert <corecode@dragonflybsd.org>
Thu, 3 Sep 2009 22:22:33 +0000 (00:22 +0200)
sys/conf/files
sys/kern/link_aout.c [deleted file]

index db260bd..ee563a0 100644 (file)
@@ -637,7 +637,6 @@ kern/kern_varsym.c  standard
 kern/kern_module.c     standard
 kern/kern_linker.c     standard
 kern/kern_uuid.c       standard
-kern/link_aout.c       standard
 kern/link_elf.c                standard
 kern/kern_acct.c       standard
 kern/kern_acl.c                standard
diff --git a/sys/kern/link_aout.c b/sys/kern/link_aout.c
deleted file mode 100644 (file)
index 69b0a82..0000000
+++ /dev/null
@@ -1,652 +0,0 @@
-/*-
- * Copyright (c) 1997 Doug Rabson
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/kern/link_aout.c,v 1.26 1999/12/24 15:33:36 bde Exp $
- * $DragonFly: src/sys/kern/link_aout.c,v 1.24 2008/02/06 22:37:46 nth Exp $
- */
-
-#define FREEBSD_AOUT   1
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/types.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <sys/nlookup.h>
-#include <sys/fcntl.h>
-#include <sys/vnode.h>
-#include <sys/linker.h>
-
-#include <vm/vm_zone.h>
-
-#ifndef __ELF__
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/vmparam.h>
-#endif
-
-#include <machine/exec.h>
-#include <sys/imgact_aout.h>
-#include <machine/reloc.h>
-#define _AOUT_INCLUDE_
-#include <sys/nlist_aout.h>
-#include <sys/link_aout.h>
-
-static int             link_aout_load_module(const char*, linker_file_t*,int);
-
-static int             link_aout_load_file(const char*, linker_file_t*,int);
-
-static int             link_aout_lookup_symbol(linker_file_t, const char*,
-                                               c_linker_sym_t*);
-static int             link_aout_symbol_values(linker_file_t file, c_linker_sym_t sym,
-                                               linker_symval_t* symval);
-static int             link_aout_search_symbol(linker_file_t lf, caddr_t value,
-                                               c_linker_sym_t* sym, long* diffp);
-static void            link_aout_unload_file(linker_file_t);
-static void            link_aout_unload_module(linker_file_t);
-static int             link_aout_lookup_set(linker_file_t lf, const char *name,
-                               void ***startp, void ***stopp, int *countp);
-
-static struct linker_class_ops link_aout_class_ops = {
-    link_aout_load_module,
-};
-
-static struct linker_file_ops link_aout_file_ops = {
-    link_aout_lookup_symbol,
-    link_aout_symbol_values,
-    link_aout_search_symbol,
-    link_aout_unload_file,
-    link_aout_lookup_set
-};
-static struct linker_file_ops link_aout_module_ops = {
-    link_aout_lookup_symbol,
-    link_aout_symbol_values,
-    link_aout_search_symbol,
-    link_aout_unload_module,
-    link_aout_lookup_set
-};
-
-typedef struct aout_file {
-    char*              address;        /* Load address */
-    struct _dynamic*   dynamic;        /* Symbol table etc. */
-} *aout_file_t;
-
-static int             load_dependancies(linker_file_t lf, int load_flags);
-static int             relocate_file(linker_file_t lf);
-
-/*
- * The kernel symbol table starts here.
- */
-extern struct _dynamic _DYNAMIC;
-
-static void
-link_aout_init(void* arg)
-{
-#ifndef __ELF__
-    struct _dynamic* dp = &_DYNAMIC;
-#endif
-
-    linker_add_class("a.out", NULL, &link_aout_class_ops);
-
-#ifndef __ELF__
-    if (dp) {
-       aout_file_t af;
-
-       af = kmalloc(sizeof(struct aout_file), M_LINKER, M_NOWAIT | M_ZERO);
-       if (af == NULL)
-           panic("link_aout_init: Can't create linker structures for kernel");
-
-       af->address = 0;
-       af->dynamic = dp;
-       linker_kernel_file =
-           linker_make_file(kernelname, af, &link_aout_file_ops);
-       if (linker_kernel_file == NULL)
-           panic("link_aout_init: Can't create linker structures for kernel");
-       linker_kernel_file->address = (caddr_t) KERNBASE;
-       linker_kernel_file->size = -(long)linker_kernel_file->address;
-       linker_current_file = linker_kernel_file;
-       linker_kernel_file->flags |= LINKER_FILE_LINKED;
-    }
-#endif
-}
-
-SYSINIT(link_aout, SI_BOOT2_KLD, SI_ORDER_THIRD, link_aout_init, 0);
-
-static int
-link_aout_load_module(const char *filename, linker_file_t *result,
-                     int load_flags)
-{
-    caddr_t            modptr, baseptr;
-    char               *type;
-    struct exec                *ehdr;
-    aout_file_t                af;
-    linker_file_t      lf;
-    int                        error;
-    
-    /* Look to see if we have the module preloaded. */
-    if ((modptr = preload_search_by_name(filename)) == NULL)
-       return(link_aout_load_file(filename, result, load_flags));
-
-    /* It's preloaded, check we can handle it and collect information. */
-    if (((type = (char *)preload_search_info(modptr, MODINFO_TYPE)) == NULL) ||
-       strcmp(type, "a.out module") ||
-       ((baseptr = preload_search_info(modptr, MODINFO_ADDR)) == NULL) ||
-       ((ehdr = (struct exec *)preload_search_info(modptr, MODINFO_METADATA | MODINFOMD_AOUTEXEC)) == NULL))
-       return(0);                      /* we can't handle this */
-
-    /* Looks like we can handle this one */
-    af = kmalloc(sizeof(struct aout_file), M_LINKER, M_WAITOK | M_ZERO);
-    af->address = baseptr;
-
-    /* Assume _DYNAMIC is the first data item. */
-    af->dynamic = (struct _dynamic*)(af->address + ehdr->a_text);
-    if (af->dynamic->d_version != LD_VERSION_BSD) {
-       kfree(af, M_LINKER);
-       return(0);                      /* we can't handle this */
-    }
-    af->dynamic->d_un.d_sdt = (struct section_dispatch_table *)
-       ((char *)af->dynamic->d_un.d_sdt + (vm_offset_t)af->address);
-
-    /* Register with kld */
-    lf = linker_make_file(filename, af, &link_aout_module_ops);
-    if (lf == NULL) {
-       kfree(af, M_LINKER);
-       return(ENOMEM);
-    }
-    lf->address = af->address;
-    lf->size = ehdr->a_text + ehdr->a_data + ehdr->a_bss;
-
-    /* Try to load dependancies */
-    if (((error = load_dependancies(lf, load_flags)) != 0) ||
-       ((error = relocate_file(lf)) != 0)) {
-       linker_file_unload(lf);
-       return(error);
-    }
-    lf->flags |= LINKER_FILE_LINKED;
-    *result = lf;
-    return(0);
-}
-
-static int
-link_aout_load_file(const char *filename, linker_file_t *result, int load_flags)
-{
-    struct nlookupdata nd;
-    struct thread *td = curthread;
-    struct proc *p = td->td_proc;
-    struct vnode *vp;
-    int error = 0;
-    int resid;
-    struct exec header;
-    aout_file_t af;
-    linker_file_t lf;
-    char *pathname;
-
-    KKASSERT(p != NULL);
-
-    if (p->p_ucred == NULL) {
-       kprintf("link_aout_load_file: cannot load '%s' from filesystem"
-               " this early\n", filename);
-       return ENOENT;
-    }
-
-    pathname = linker_search_path(filename);
-    if (pathname == NULL)
-       return ENOENT;
-    error = nlookup_init(&nd, pathname, UIO_SYSSPACE, NLC_FOLLOW|NLC_LOCKVP);
-    if (error == 0)
-       error = vn_open(&nd, NULL, FREAD, 0);
-    kfree(pathname, M_LINKER);
-    if (error) {
-       nlookup_done(&nd);
-       return error;
-    }
-    vp = nd.nl_open_vp;
-    nd.nl_open_vp = NULL;
-    nlookup_done(&nd);
-
-    /*
-     * Read the a.out header from the file.
-     */
-    error = vn_rdwr(UIO_READ, vp, (void*) &header, sizeof header, 0,
-                   UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid);
-    if (error)
-       goto out;
-
-    if (N_BADMAG(header) || !(N_GETFLAG(header) & EX_DYNAMIC))
-       goto out;
-
-    /*
-     * We have an a.out file, so make some space to read it in.
-     */
-    af = kmalloc(sizeof(struct aout_file), M_LINKER, M_WAITOK | M_ZERO);
-    af->address = kmalloc(header.a_text + header.a_data + header.a_bss,
-                        M_LINKER, M_WAITOK);
-    
-    /*
-     * Read the text and data sections and zero the bss.
-     */
-    error = vn_rdwr(UIO_READ, vp, (void*) af->address,
-                   header.a_text + header.a_data, 0,
-                   UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid);
-    if (error)
-       goto out;
-    bzero(af->address + header.a_text + header.a_data, header.a_bss);
-
-    /*
-     * Assume _DYNAMIC is the first data item.
-     */
-    af->dynamic = (struct _dynamic*) (af->address + header.a_text);
-    if (af->dynamic->d_version != LD_VERSION_BSD) {
-       kfree(af->address, M_LINKER);
-       kfree(af, M_LINKER);
-       goto out;
-    }
-    af->dynamic->d_un.d_sdt = (struct section_dispatch_table *)
-       ((char *)af->dynamic->d_un.d_sdt + (vm_offset_t)af->address);
-
-    lf = linker_make_file(filename, af, &link_aout_file_ops);
-    if (lf == NULL) {
-       kfree(af->address, M_LINKER);
-       kfree(af, M_LINKER);
-       error = ENOMEM;
-       goto out;
-    }
-    lf->address = af->address;
-    lf->size = header.a_text + header.a_data + header.a_bss;
-
-    if ((error = load_dependancies(lf, load_flags)) != 0
-       || (error = relocate_file(lf)) != 0) {
-       linker_file_unload(lf);
-       goto out;
-    }
-
-    lf->flags |= LINKER_FILE_LINKED;
-    *result = lf;
-
-out:
-    vn_unlock(vp);
-    vn_close(vp, FREAD);
-
-    return error;
-}
-
-static void
-link_aout_unload_file(linker_file_t file)
-{
-    aout_file_t af = file->priv;
-
-    if (af) {
-       if (af->address)
-           kfree(af->address, M_LINKER);
-       kfree(af, M_LINKER);
-    }
-}
-
-static void
-link_aout_unload_module(linker_file_t file)
-{
-    aout_file_t af = file->priv;
-
-    if (af)
-       kfree(af, M_LINKER);
-    if (file->filename)
-       preload_delete_name(file->filename);
-}
-
-#define AOUT_RELOC(af, type, off) (type*) ((af)->address + (off))
-
-static int
-load_dependancies(linker_file_t lf, int load_flags)
-{
-    aout_file_t af = lf->priv;
-    linker_file_t lfdep;
-    long off;
-    struct sod* sodp;
-    char* name;
-    char* filename = 0;
-    int error = 0;
-
-    /*
-     * All files are dependant on /kernel.
-     */
-    if (linker_kernel_file) {
-       linker_kernel_file->refs++;
-       linker_file_add_dependancy(lf, linker_kernel_file);
-    }
-
-    off = LD_NEED(af->dynamic);
-
-    /*
-     * Load the dependancies.
-     */
-    while (off != 0) {
-       sodp = AOUT_RELOC(af, struct sod, off);
-       name = AOUT_RELOC(af, char, sodp->sod_name);
-
-       error = linker_load_file(name, &lfdep, load_flags);
-       if (error)
-           goto out;
-       linker_file_add_dependancy(lf, lfdep);
-       off = sodp->sod_next;
-    }
-
-out:
-    if (filename)
-       kfree(filename, M_TEMP);
-    return error;
-}
-
-/*
- * XXX i386 dependant.
- */
-static long
-read_relocation(struct relocation_info* r, char* addr)
-{
-    int length = r->r_length;
-    if (length == 0)
-       return *(u_char*) addr;
-    else if (length == 1)
-       return *(u_short*) addr;
-    else if (length == 2)
-       return *(u_int*) addr;
-    else
-       kprintf("link_aout: unsupported relocation size %d\n", r->r_length);
-    return 0;
-}
-
-static void
-write_relocation(struct relocation_info* r, char* addr, long value)
-{
-    int length = r->r_length;
-    if (length == 0)
-       *(u_char*) addr = value;
-    else if (length == 1)
-       *(u_short*) addr = value;
-    else if (length == 2)
-       *(u_int*) addr = value;
-    else
-       kprintf("link_aout: unsupported relocation size %d\n", r->r_length);
-}
-
-static int
-relocate_file(linker_file_t lf)
-{
-    aout_file_t af = lf->priv;
-    struct relocation_info* rel;
-    struct relocation_info* erel;
-    struct relocation_info* r;
-    struct nzlist* symbolbase;
-    char* stringbase;
-    struct nzlist* np;
-    char* sym;
-    long relocation;
-
-    rel = AOUT_RELOC(af, struct relocation_info, LD_REL(af->dynamic));
-    erel = AOUT_RELOC(af, struct relocation_info,
-                     LD_REL(af->dynamic) + LD_RELSZ(af->dynamic));
-    symbolbase = AOUT_RELOC(af, struct nzlist, LD_SYMBOL(af->dynamic));
-    stringbase = AOUT_RELOC(af, char, LD_STRINGS(af->dynamic));
-
-    for (r = rel; r < erel; r++) {
-       char* addr;
-
-       if (r->r_address == 0)
-           break;
-
-       addr = AOUT_RELOC(af, char, r->r_address);
-       if (r->r_extern) {
-           np = &symbolbase[r->r_symbolnum];
-           sym = &stringbase[np->nz_strx];
-
-           if (sym[0] != '_') {
-               kprintf("link_aout: bad symbol name %s\n", sym);
-               kprintf("link_aout: symbol %s not found\n", sym);
-               return ENOENT;
-           } else {
-               if (linker_file_lookup_symbol(lf, sym + 1,
-                   (np->nz_type != (N_SETV+N_EXT)), (caddr_t *)&relocation)) {
-                       kprintf("link_aout: symbol %s not found\n", sym);
-                       return ENOENT;
-               }
-           }
-           
-           relocation += read_relocation(r, addr);
-
-           if (r->r_jmptable) {
-               kprintf("link_aout: can't cope with jump table relocations\n");
-               continue;
-           }
-
-           if (r->r_pcrel)
-               relocation -= (intptr_t) af->address;
-
-           if (r->r_copy) {
-               kprintf("link_aout: can't cope with copy relocations\n");
-               continue;
-           }
-           
-           write_relocation(r, addr, relocation);
-       } else {
-           write_relocation(r, addr,
-                            (intptr_t)(read_relocation(r, addr) + af->address));
-       }
-       
-    }
-
-    return 0;
-}
-
-static long
-symbol_hash_value(aout_file_t af, const char* name)
-{
-    long hashval;
-    const char* p;
-
-    hashval = '_';             /* fake a starting '_' for C symbols */
-    for (p = name; *p; p++)
-       hashval = (hashval << 1) + *p;
-
-    return (hashval & 0x7fffffff) % LD_BUCKETS(af->dynamic);
-}
-
-int
-link_aout_lookup_symbol(linker_file_t file, const char* name,
-                       c_linker_sym_t* sym)
-{
-    aout_file_t af = file->priv;
-    long hashval;
-    struct rrs_hash* hashbase;
-    struct nzlist* symbolbase;
-    char* stringbase;
-    struct rrs_hash* hp;
-    struct nzlist* np;
-    char* cp;
-
-    if (LD_BUCKETS(af->dynamic) == 0)
-       return 0;
-
-    hashbase = AOUT_RELOC(af, struct rrs_hash, LD_HASH(af->dynamic));
-    symbolbase = AOUT_RELOC(af, struct nzlist, LD_SYMBOL(af->dynamic));
-    stringbase = AOUT_RELOC(af, char, LD_STRINGS(af->dynamic));
-
-restart:
-    hashval = symbol_hash_value(af, name);
-    hp = &hashbase[hashval];
-    if (hp->rh_symbolnum == -1)
-       return ENOENT;
-
-    while (hp) {
-       np = (struct nzlist *) &symbolbase[hp->rh_symbolnum];
-       cp = stringbase + np->nz_strx;
-       /*
-        * Note: we fake the leading '_' for C symbols.
-        */
-       if (cp[0] == '_' && !strcmp(cp + 1, name))
-           break;
-
-       if (hp->rh_next == 0)
-           hp = NULL;
-       else
-           hp = &hashbase[hp->rh_next];
-    }
-
-    if (hp == NULL)
-       /*
-        * Not found.
-        */
-       return ENOENT;
-
-    /*
-     * Check for an aliased symbol, whatever that is.
-     */
-    if (np->nz_type == N_INDR+N_EXT) {
-       name = stringbase + (++np)->nz_strx + 1; /* +1 for '_' */
-       goto restart;
-    }
-
-    /*
-     * Check this is an actual definition of the symbol.
-     */
-    if (np->nz_value == 0)
-       return ENOENT;
-
-    if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
-       if (np->nz_other == AUX_FUNC)
-           /* weak function */
-           return ENOENT;
-    }
-
-    *sym = (linker_sym_t) np;
-
-    return 0;
-}
-
-
-static int
-link_aout_symbol_values(linker_file_t file, c_linker_sym_t sym,
-                       linker_symval_t* symval)
-{
-    aout_file_t af = file->priv;
-    const struct nzlist* np = (const struct nzlist*) sym;
-    char* stringbase;
-    long numsym = LD_STABSZ(af->dynamic) / sizeof(struct nzlist);
-    struct nzlist *symbase;
-
-    /* Is it one of ours?  It could be another module... */
-    symbase = AOUT_RELOC(af, struct nzlist, LD_SYMBOL(af->dynamic));
-    if (np < symbase)
-       return ENOENT;
-    if ((np - symbase) > numsym)
-       return ENOENT;
-
-    stringbase = AOUT_RELOC(af, char, LD_STRINGS(af->dynamic));
-
-    symval->name = stringbase + np->nz_strx + 1; /* +1 for '_' */
-    if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
-       symval->value = 0;
-       symval->size = np->nz_value;
-    } else {
-       symval->value = AOUT_RELOC(af, char, np->nz_value);
-       symval->size = np->nz_size;
-    }
-    return 0;
-}
-
-static int
-link_aout_search_symbol(linker_file_t lf, caddr_t value,
-                       c_linker_sym_t* sym, long* diffp)
-{
-       aout_file_t af = lf->priv;
-       u_long off = (uintptr_t) (void *) value;
-       u_long diff = off;
-       u_long sp_nz_value;
-       struct nzlist* sp;
-       struct nzlist* ep;
-       struct nzlist* best = 0;
-
-       for (sp = AOUT_RELOC(af, struct nzlist, LD_SYMBOL(af->dynamic)),
-                ep = (struct nzlist *) ((caddr_t) sp + LD_STABSZ(af->dynamic));
-            sp < ep; sp++) {
-               if (sp->nz_name == 0)
-                       continue;
-               sp_nz_value = sp->nz_value + (uintptr_t) (void *) af->address;
-               if (off >= sp_nz_value) {
-                       if (off - sp_nz_value < diff) {
-                               diff = off - sp_nz_value;
-                               best = sp;
-                               if (diff == 0)
-                                       break;
-                       } else if (off - sp_nz_value == diff) {
-                               best = sp;
-                       }
-               }
-       }
-       if (best == 0)
-               *diffp = off;
-       else
-               *diffp = diff;
-       *sym = (linker_sym_t) best;
-
-       return 0;
-}
-
-/*
- * Look up a linker set on an a.out + gnu LD system.
- */
-
-struct generic_linker_set {
-       int     ls_length;
-       void    *ls_items[1];
-};
-
-static int
-link_aout_lookup_set(linker_file_t lf, const char *name,
-                   void ***startp, void ***stopp, int *countp)
-{
-       c_linker_sym_t sym;
-       linker_symval_t symval;
-       void **start, **stop;
-       int error, count;
-       struct generic_linker_set *setp;
-
-       error = link_aout_lookup_symbol(lf, name, &sym);
-       if (error)
-              return error;
-       link_aout_symbol_values(lf, sym, &symval);
-       if (symval.value == 0)
-              return ESRCH;
-       setp = (struct generic_linker_set *)symval.value;
-       count = setp->ls_length;
-       start = &setp->ls_items[0];
-       stop = &setp->ls_items[count];
-       if (startp)
-              *startp = start;
-       if (stopp)
-              *stopp = stop;
-       if (countp)
-              *countp = count;
-       return 0;
-}