From 70eee1c9363092cae6ef68466a44ad68fa22e183 Mon Sep 17 00:00:00 2001 From: Simon Schubert Date: Thu, 3 Sep 2009 22:29:02 +0200 Subject: [PATCH] modules: drop a.out module support --- sys/conf/files | 1 - sys/kern/link_aout.c | 652 --------------------------------------------------- 2 files changed, 653 deletions(-) delete mode 100644 sys/kern/link_aout.c diff --git a/sys/conf/files b/sys/conf/files index db260bdeb8..ee563a0489 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -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 index 69b0a82991..0000000000 --- a/sys/kern/link_aout.c +++ /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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifndef __ELF__ -#include -#include -#include -#endif - -#include -#include -#include -#define _AOUT_INCLUDE_ -#include -#include - -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; -} -- 2.11.4.GIT