diff options
author | peter <peter@FreeBSD.org> | 1998-10-09 23:15:39 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1998-10-09 23:15:39 +0000 |
commit | 1ee0daa7acf1e30ee9c3c8c7fa15e960a150cea9 (patch) | |
tree | 883212480342fb98bba37da767630e154fc81473 /sys/boot/common/load_aout.c | |
parent | 2316c4c4791be32937c133b59c9f99f1dbb5a080 (diff) | |
download | FreeBSD-src-1ee0daa7acf1e30ee9c3c8c7fa15e960a150cea9.zip FreeBSD-src-1ee0daa7acf1e30ee9c3c8c7fa15e960a150cea9.tar.gz |
Preload support for a.out KLD not implemented yet. (almost)
KLD modules are *not* PIC. (Shared libs are pic to avoid relocations
causing copy-on-write, that's irrelevant here).
setenv kernelname when we load it.
Use MODINFO_SSYM/ESYM for each symbol section when (if) there are
more than one being loaded.
Diffstat (limited to 'sys/boot/common/load_aout.c')
-rw-r--r-- | sys/boot/common/load_aout.c | 156 |
1 files changed, 25 insertions, 131 deletions
diff --git a/sys/boot/common/load_aout.c b/sys/boot/common/load_aout.c index 335adeb..b99ea92 100644 --- a/sys/boot/common/load_aout.c +++ b/sys/boot/common/load_aout.c @@ -23,13 +23,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: load_aout.c,v 1.7 1998/09/30 19:26:23 peter Exp $ + * $Id: load_aout.c,v 1.8 1998/10/02 16:22:26 msmith Exp $ */ #include <sys/param.h> #include <sys/exec.h> #include <sys/imgact_aout.h> #include <sys/reboot.h> +#include <sys/linker.h> #include <string.h> #include <machine/bootinfo.h> #include <stand.h> @@ -39,9 +40,12 @@ #include "bootstrap.h" -static int aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel); +static int aout_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel); + +#if 0 static vm_offset_t aout_findkldident(struct loaded_module *mp, struct exec *ehdr); static int aout_fixupkldmod(struct loaded_module *mp, struct exec *ehdr); +#endif char *aout_kerneltype = "a.out kernel"; char *aout_moduletype = "a.out module"; @@ -60,6 +64,7 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) vm_offset_t addr; int err, kernel; u_int pad; + char *s; mp = NULL; @@ -85,7 +90,7 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) * XXX should check N_GETMID() */ kmp = mod_findmodule(NULL, NULL); - if (N_GETFLAG(ehdr) == (EX_DYNAMIC | EX_PIC)) { + if ((N_GETFLAG(ehdr)) & EX_DYNAMIC) { /* Looks like a kld module */ if (kmp == NULL) { printf("aout_loadmodule: can't load module before kernel\n"); @@ -128,7 +133,12 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) */ mp = mod_allocmodule(); if (kernel) - mp->m_name = strdup(filename); /* XXX should we prune the name? */ + setenv("kernelname", filename, 1); + s = strrchr(filename, '/'); + if (s) + mp->m_name = strdup(s + 1); + else + mp->m_name = strdup(filename); mp->m_type = strdup(kernel ? aout_kerneltype : aout_moduletype); /* Page-align the load address */ @@ -141,13 +151,15 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) mp->m_addr = addr; /* save the aligned load address */ printf("%s at %p\n", filename, (void *) addr); - mp->m_size = aout_loadimage(fd, addr, &ehdr, kernel); + mp->m_size = aout_loadimage(mp, fd, addr, &ehdr, kernel); if (mp->m_size == 0) goto ioerr; +#if 0 /* Handle KLD module data */ if (!kernel && ((err = aout_fixupkldmod(mp, &ehdr)) != 0)) goto oerr; +#endif /* save exec header as metadata */ mod_addmetadata(mp, MODINFOMD_AOUTEXEC, sizeof(struct exec), &ehdr); @@ -175,11 +187,12 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) * align the symbol table. */ static int -aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel) +aout_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel) { u_int pad; vm_offset_t addr; int ss; + vm_offset_t ssym, esym; addr = loadaddr; lseek(fd, N_TXTOFF(*ehdr), SEEK_SET); @@ -208,6 +221,7 @@ aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel) addr += ehdr->a_bss; /* symbol table size */ + ssym = addr; archsw.arch_copyin(&ehdr->a_syms, addr, sizeof(ehdr->a_syms)); addr += sizeof(ehdr->a_syms); @@ -227,11 +241,16 @@ aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel) return(0); printf(" \n"); addr += ss; + esym = addr; + + mod_addmetadata(mp, MODINFOMD_SSYM, sizeof(ssym), &ssym); + mod_addmetadata(mp, MODINFOMD_ESYM, sizeof(esym), &esym); return(addr - loadaddr); } +#if 0 #define AOUT_RELOC(mp, off) ((mp)->m_addr + (vm_offset_t)(off)) /* @@ -332,129 +351,4 @@ aout_fixupkldmod(struct loaded_module *mp, struct exec *ehdr) } return(0); } - -#if 0 -/************************************************************/ -/* XXX Arbitrary symbol lookup - unused at this point XXX */ -/* */ -/* Code heavily borrowed from kern/link_aout.c (c) DFR */ -/************************************************************/ - -static long -symbol_hash_value(struct _dynamic *dynamic, 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(dynamic); -} - -/* - * Locate the symbol (name) in the a.out object associated with (mp), - * return a vm_offset_t containing the value of the symbol. - */ -static vm_offset_t -aout_findsym(char *name, struct loaded_module *mp) -{ - struct module_metadata *md; - struct exec *ehdr; - struct _dynamic dynamic; - struct section_dispatch_table sdt; - vm_offset_t hashbase, symbolbase, stringbase, hp, np, cp; - struct rrs_hash hash; - struct nzlist nzl; - char *symbol, *asymbol; /* XXX symbol name limit? */ - long hashval; - vm_offset_t result; - - - symbol = NULL; - asymbol = NULL; - result = 0; - - /* Find the exec header */ - if ((md = mod_findmetadata(mp, MODINFOMD_AOUTEXEC)) == NULL) - goto out; - ehdr = (struct exec *)md->md_data; - - /* Get the _DYNAMIC object, which we assume is first in the data segment */ - archsw.arch_copyout(AOUT_RELOC(mp, ehdr->a_text), &dynamic, sizeof(dynamic)); - archsw.arch_copyout(AOUT_RELOC(mp, dynamic.d_un.d_sdt), &sdt, sizeof(struct section_dispatch_table)); - dynamic.d_un.d_sdt = &sdt; /* fix up SDT pointer */ - if ((dynamic.d_version != LD_VERSION_BSD) || - (LD_BUCKETS(&dynamic) == 0)) - goto out; - - hashbase = AOUT_RELOC(mp, LD_HASH(&dynamic)); - symbolbase = AOUT_RELOC(mp, LD_SYMBOL(&dynamic)); - stringbase = AOUT_RELOC(mp, LD_STRINGS(&dynamic)); - -restart: - hashval = symbol_hash_value(&dynamic, name); - hp = hashbase + (hashval * sizeof(struct rrs_hash)); - archsw.arch_copyout(hp, &hash, sizeof(struct rrs_hash)); - if (hash.rh_symbolnum == -1) - goto out; - - while (hp) { - np = symbolbase + (hash.rh_symbolnum * sizeof(struct nzlist)); - archsw.arch_copyout(np, &nzl, sizeof(struct nzlist)); - cp = stringbase + nzl.nz_strx; - if (symbol != NULL) - free(symbol); - symbol = strdupout(cp); - /* - * Note: we fake the leading '_' for C symbols. - */ - if (symbol[0] == '_' && !strcmp(symbol + 1, name)) - break; - - if (hash.rh_next == 0) { - hp = 0; - } else { - hp = hashbase + (hash.rh_next * sizeof(struct rrs_hash)); - archsw.arch_copyout(hp, &hash, sizeof(struct rrs_hash)); - } - } - /* Not found. */ - if (hp == 0) - goto out; - - /* - * Check for an aliased symbol, whatever that is. - */ - if (nzl.nz_type == N_INDR+N_EXT) { - np += sizeof(struct nzlist); - archsw.arch_copyout(np, &nzl, sizeof(struct nzlist)); - asymbol = strdupout(stringbase + nzl.nz_strx + 1); /* +1 for '_' */ - goto restart; - } - - /* - * Check this is an actual definition of the symbol. - */ - if (nzl.nz_value == 0) - goto out; - - if (nzl.nz_type == N_UNDF+N_EXT && nzl.nz_value != 0) - if (nzl.nz_other == AUX_FUNC) - /* weak function */ - goto out; - - /* Return a vm_offset_t pointing to the object itself */ - result = AOUT_RELOC(mp, nzl.nz_value); - - out: - if (symbol) - free(symbol); - if (asymbol) - free(asymbol); - return(result); - -} - #endif |