Update loader logic to distinguish modules vs. files.

Add support for module metadata. The old way of dependancy
handling will be supported for a while.

Reviewed by:	peter
This commit is contained in:
bp 2000-05-01 17:41:25 +00:00
parent f1711d4db1
commit 93440aad9b
22 changed files with 745 additions and 495 deletions

View File

@ -81,9 +81,9 @@ struct netif_driver *netif_drivers[] = {
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct module_format alpha_elf;
extern struct file_format alpha_elf;
struct module_format *module_formats[] = {
struct file_format *file_formats[] = {
&alpha_elf,
NULL
};

View File

@ -125,19 +125,19 @@ bi_copyenv(vm_offset_t addr)
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct loaded_module *mp;
struct module_metadata *md;
struct preloaded_file *fp;
struct file_metadata *md;
/* start with the first module on the list, should be the kernel */
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
MOD_NAME(addr, mp->m_name); /* this field must come first */
MOD_TYPE(addr, mp->m_type);
if (mp->m_args)
MOD_ARGS(addr, mp->m_args);
MOD_ADDR(addr, mp->m_addr);
MOD_SIZE(addr, mp->m_size);
for (md = mp->m_metadata; md != NULL; md = md->md_next)
MOD_NAME(addr, fp->f_name); /* this field must come first */
MOD_TYPE(addr, fp->f_type);
if (fp->f_args)
MOD_ARGS(addr, fp->f_args);
MOD_ADDR(addr, fp->f_addr);
MOD_SIZE(addr, fp->f_size);
for (md = fp->f_metadata; md != NULL; md = md->md_next)
if (!(md->md_type & MODINFOMD_NOCOPY))
MOD_METADATA(addr, md);
}
@ -153,15 +153,15 @@ bi_copymodules(vm_offset_t addr)
*/
int
bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save,
struct loaded_module *mp)
struct preloaded_file *fp)
{
char *rootdevname;
struct alpha_devdesc *rootdev;
struct loaded_module *xp;
struct preloaded_file *xp;
vm_offset_t addr, bootinfo_addr;
u_int pad;
vm_offset_t ssym, esym;
struct module_metadata *md;
struct file_metadata *md;
/*
* Allow the environment variable 'rootdev' to override the supplied device
@ -180,9 +180,9 @@ bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save,
free(rootdev);
ssym = esym = 0;
if ((md = mod_findmetadata(mp, MODINFOMD_SSYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL)
ssym = *((vm_offset_t *)&(md->md_data));
if ((md = mod_findmetadata(mp, MODINFOMD_ESYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL)
esym = *((vm_offset_t *)&(md->md_data));
if (ssym == 0 || esym == 0)
ssym = esym = 0; /* sanity */
@ -192,9 +192,9 @@ bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save,
/* find the last module in the chain */
addr = 0;
for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) {
if (addr < (xp->m_addr + xp->m_size))
addr = xp->m_addr + xp->m_size;
for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
if (addr < (xp->f_addr + xp->f_size))
addr = xp->f_addr + xp->f_size;
}
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;

View File

@ -90,37 +90,37 @@
#define _KERNEL
static int elf_exec(struct loaded_module *amp);
static int elf_exec(struct preloaded_file *afp);
int bi_load(struct bootinfo_v1 *, vm_offset_t *,
struct loaded_module *);
struct preloaded_file *);
struct module_format alpha_elf = { elf_loadmodule, elf_exec };
struct file_format alpha_elf = { elf_loadfile, elf_exec };
vm_offset_t ffp_save, ptbr_save;
static int
elf_exec(struct loaded_module *mp)
elf_exec(struct preloaded_file *fp)
{
static struct bootinfo_v1 bootinfo_v1;
struct module_metadata *md;
struct file_metadata *md;
Elf_Ehdr *hdr;
int err;
int flen;
if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE); /* XXX actually EFUCKUP */
hdr = (Elf_Ehdr *)&(md->md_data);
/* XXX ffp_save does not appear to be used in the kernel.. */
bzero(&bootinfo_v1, sizeof(bootinfo_v1));
err = bi_load(&bootinfo_v1, &ffp_save, mp);
err = bi_load(&bootinfo_v1, &ffp_save, fp);
if (err)
return(err);
/*
* Fill in the bootinfo for the kernel.
*/
strncpy(bootinfo_v1.booted_kernel, mp->m_name,
strncpy(bootinfo_v1.booted_kernel, fp->f_name,
sizeof(bootinfo_v1.booted_kernel));
flen = prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo_v1.boot_flags,
sizeof(bootinfo_v1.boot_flags));
@ -133,8 +133,8 @@ elf_exec(struct loaded_module *mp)
/*
* Append the boot command flags.
*/
if (mp->m_args != NULL && *mp->m_args != '\0') {
const char *p = mp->m_args;
if (fp->f_args != NULL && *fp->f_args != '\0') {
const char *p = fp->f_args;
do {
if (*p == '-') {
@ -150,7 +150,7 @@ elf_exec(struct loaded_module *mp)
bootinfo_v1.boot_flags[flen] = '\0';
}
printf("Entering %s at 0x%lx...\n", mp->m_name, hdr->e_entry);
printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry);
closeall();
alpha_pal_imb();
(*(void (*)())hdr->e_entry)(ffp_save, ptbr_save,

View File

@ -121,17 +121,17 @@ bi_copyenv(vm_offset_t addr)
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct loaded_module *mp;
struct module_metadata *md;
struct preloaded_file *fp;
struct file_metadata *md;
/* start with the first module on the list, should be the kernel */
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
MOD_NAME(addr, mp->m_name); /* this field must come first */
MOD_TYPE(addr, mp->m_type);
MOD_ADDR(addr, mp->m_addr);
MOD_SIZE(addr, mp->m_size);
for (md = mp->m_metadata; md != NULL; md = md->md_next)
MOD_NAME(addr, fp->f_name); /* this field must come first */
MOD_TYPE(addr, fp->f_type);
MOD_ADDR(addr, fp->f_addr);
MOD_SIZE(addr, fp->f_size);
for (md = fp->f_metadata; md != NULL; md = md->md_next)
if (!(md->md_type & MODINFOMD_NOCOPY))
MOD_METADATA(addr, md);
}
@ -147,18 +147,18 @@ bi_copymodules(vm_offset_t addr)
*/
int
bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save,
struct loaded_module *mp)
struct preloaded_file *fp)
{
struct loaded_module *xp;
struct preloaded_file *xp;
vm_offset_t addr, bootinfo_addr;
u_int pad;
vm_offset_t ssym, esym;
struct module_metadata *md;
struct file_metadata *md;
ssym = esym = 0;
if ((md = mod_findmetadata(mp, MODINFOMD_SSYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL)
ssym = *((vm_offset_t *)&(md->md_data));
if ((md = mod_findmetadata(mp, MODINFOMD_ESYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL)
esym = *((vm_offset_t *)&(md->md_data));
if (ssym == 0 || esym == 0)
ssym = esym = 0; /* sanity */
@ -168,9 +168,9 @@ bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save,
/* find the last module in the chain */
addr = 0;
for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) {
if (addr < (xp->m_addr + xp->m_size))
addr = xp->m_addr + xp->m_size;
for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
if (addr < (xp->f_addr + xp->f_size))
addr = xp->f_addr + xp->f_size;
}
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;

View File

@ -90,37 +90,37 @@
#define _KERNEL
static int elf_exec(struct loaded_module *amp);
static int elf_exec(struct preloaded_file *amp);
int bi_load(struct bootinfo_v1 *, vm_offset_t *,
struct loaded_module *);
struct preloaded_file *);
struct module_format alpha_elf = { elf_loadmodule, elf_exec };
struct file_format alpha_elf = { elf_loadfile, elf_exec };
vm_offset_t ffp_save, ptbr_save;
static int
elf_exec(struct loaded_module *mp)
elf_exec(struct preloaded_file *fp)
{
#if 0
static struct bootinfo_v1 bootinfo_v1;
struct module_metadata *md;
struct file_metadata *md;
Elf_Ehdr *hdr;
int err;
if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE); /* XXX actually EFUCKUP */
hdr = (Elf_Ehdr *)&(md->md_data);
/* XXX ffp_save does not appear to be used in the kernel.. */
bzero(&bootinfo_v1, sizeof(bootinfo_v1));
err = bi_load(&bootinfo_v1, &ffp_save, mp);
err = bi_load(&bootinfo_v1, &ffp_save, fp);
if (err)
return(err);
/*
* Fill in the bootinfo for the kernel.
*/
strncpy(bootinfo_v1.booted_kernel, mp->m_name,
strncpy(bootinfo_v1.booted_kernel, fp->f_name,
sizeof(bootinfo_v1.booted_kernel));
prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo_v1.boot_flags,
sizeof(bootinfo_v1.boot_flags));
@ -130,7 +130,7 @@ elf_exec(struct loaded_module *mp)
bootinfo_v1.cnputc = NULL;
bootinfo_v1.cnpollc = NULL;
printf("Entering %s at 0x%lx...\n", mp->m_name, hdr->e_entry);
printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry);
exit(0);
closeall();
alpha_pal_imb();

View File

@ -64,9 +64,9 @@ struct fs_ops *file_system[] = {
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct module_format alpha_elf;
extern struct file_format alpha_elf;
struct module_format *module_formats[] = {
struct file_format *file_formats[] = {
&alpha_elf,
NULL
};

View File

@ -50,7 +50,7 @@ COMMAND_SET(boot, "boot", "boot a file or loaded kernel", command_boot);
static int
command_boot(int argc, char *argv[])
{
struct loaded_module *km;
struct preloaded_file *fp;
char *cp;
int try;
int i;
@ -61,7 +61,7 @@ command_boot(int argc, char *argv[])
if ((argc > 1) && (argv[1][0] != '-')) {
/* XXX maybe we should discard everything and start again? */
if (mod_findmodule(NULL, NULL) != NULL) {
if (file_findfile(NULL, NULL) != NULL) {
sprintf(command_errbuf, "can't boot '%s', kernel module already loaded", argv[1]);
return(CMD_ERROR);
}
@ -76,7 +76,7 @@ command_boot(int argc, char *argv[])
/*
* See if there is a kernel module already loaded
*/
if (mod_findmodule(NULL, NULL) == NULL) {
if (file_findfile(NULL, NULL) == NULL) {
for (try = 0; (cp = getbootfile(try)) != NULL; try++) {
if (mod_load(cp, argc - 1, argv + 1) != 0) {
printf("can't load '%s'\n", cp);
@ -91,7 +91,7 @@ command_boot(int argc, char *argv[])
/*
* Loaded anything yet?
*/
if ((km = mod_findmodule(NULL, NULL)) == NULL) {
if ((fp = file_findfile(NULL, NULL)) == NULL) {
command_errmsg = "no bootable kernel";
return(CMD_ERROR);
}
@ -101,9 +101,9 @@ command_boot(int argc, char *argv[])
* XXX should we merge arguments? Hard to DWIM.
*/
if (argc > 1) {
if (km->m_args != NULL)
free(km->m_args);
km->m_args = unargv(argc - 1, argv + 1);
if (fp->f_args != NULL)
free(fp->f_args);
fp->f_args = unargv(argc - 1, argv + 1);
}
/* Hook for platform-specific autoloading of modules */
@ -116,7 +116,7 @@ command_boot(int argc, char *argv[])
(devsw[i]->dv_cleanup)();
/* Call the exec handler from the loader matching the kernel */
module_formats[km->m_loader]->l_exec(km);
file_formats[fp->f_loader]->l_exec(fp);
return(CMD_ERROR);
}

View File

@ -153,62 +153,79 @@ extern char *pnp_eisaformat(u_int8_t *data);
extern int isapnp_readport;
/*
* Module metadata header.
* Preloaded file metadata header.
*
* Metadata are allocated on our heap, and copied into kernel space
* before executing the kernel.
*/
struct module_metadata
struct file_metadata
{
size_t md_size;
u_int16_t md_type;
struct module_metadata *md_next;
struct file_metadata *md_next;
char md_data[0]; /* data are immediately appended */
};
struct preloaded_file;
struct kernel_module
{
char *m_name; /* module name */
/* char *m_args;*/ /* arguments for the module */
struct preloaded_file *m_fp;
struct kernel_module *m_next;
};
/*
* Loaded module information.
* Preloaded file information. Depending on type, file can contain
* additional units called 'modules'.
*
* At least one module (the kernel) must be loaded in order to boot.
* At least one file (the kernel) must be loaded in order to boot.
* The kernel is always loaded first.
*
* String fields (m_name, m_type) should be dynamically allocated.
*/
struct loaded_module
struct preloaded_file
{
char *m_name; /* module name */
char *m_type; /* verbose module type, eg 'ELF kernel', 'pnptable', etc. */
char *m_args; /* arguments for the module */
struct module_metadata *m_metadata; /* metadata that will be placed in the module directory */
int m_loader; /* index of the loader that read the file */
vm_offset_t m_addr; /* load address */
size_t m_size; /* module size */
struct loaded_module *m_next; /* next module */
char *f_name; /* file name */
char *f_type; /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */
char *f_args; /* arguments for the file */
struct file_metadata *f_metadata; /* metadata that will be placed in the module directory */
int f_loader; /* index of the loader that read the file */
vm_offset_t f_addr; /* load address */
size_t f_size; /* file size */
struct kernel_module *f_modules; /* list of modules if any */
struct preloaded_file *f_next; /* next file */
};
struct module_format
struct file_format
{
/* Load function must return EFTYPE if it can't handle the module supplied */
int (* l_load)(char *filename, vm_offset_t dest, struct loaded_module **result);
int (* l_load)(char *filename, vm_offset_t dest, struct preloaded_file **result);
/* Only a loader that will load a kernel (first module) should have an exec handler */
int (* l_exec)(struct loaded_module *mp);
int (* l_exec)(struct preloaded_file *mp);
};
extern struct module_format *module_formats[]; /* supplied by consumer */
extern struct loaded_module *loaded_modules;
extern struct file_format *file_formats[]; /* supplied by consumer */
extern struct preloaded_file *preloaded_files;
extern int mod_load(char *name, int argc, char *argv[]);
extern int mod_loadobj(char *type, char *name);
extern struct loaded_module *mod_findmodule(char *name, char *type);
extern void mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p);
extern struct module_metadata *mod_findmetadata(struct loaded_module *mp, int type);
extern void mod_discard(struct loaded_module *mp);
extern struct loaded_module *mod_allocmodule(void);
struct preloaded_file *file_alloc(void);
struct preloaded_file *file_findfile(char *name, char *type);
struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type);
void file_discard(struct preloaded_file *fp);
void file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p);
int file_addmodule(struct preloaded_file *fp, char *modname,
struct kernel_module **newmp);
/* MI module loaders */
extern int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
extern vm_offset_t aout_findsym(char *name, struct loaded_module *mp);
extern int aout_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result);
extern vm_offset_t aout_findsym(char *name, struct preloaded_file *fp);
extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
extern int elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result);
#ifndef NEW_LINKER_SET
#include <sys/linker_set.h>

View File

@ -40,11 +40,11 @@
#include "bootstrap.h"
static int aout_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel);
static int aout_loadimage(struct preloaded_file *fp, 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);
static vm_offset_t aout_findkldident(struct preloaded_file *fp, struct exec *ehdr);
static int aout_fixupkldmod(struct preloaded_file *fp, struct exec *ehdr);
#endif
char *aout_kerneltype = "a.out kernel";
@ -56,9 +56,9 @@ char *aout_moduletype = "a.out module";
* will be saved in (result).
*/
int
aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
aout_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result)
{
struct loaded_module *mp, *kmp;
struct preloaded_file *fp, *kfp;
struct exec ehdr;
int fd;
vm_offset_t addr;
@ -66,7 +66,7 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
u_int pad;
char *s;
mp = NULL;
fp = NULL;
/*
* Open the image, read and validate the a.out header
@ -89,16 +89,16 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
*
* XXX should check N_GETMID()
*/
kmp = mod_findmodule(NULL, NULL);
kfp = file_findfile(NULL, NULL);
if ((N_GETFLAG(ehdr)) & EX_DYNAMIC) {
/* Looks like a kld module */
if (kmp == NULL) {
printf("aout_loadmodule: can't load module before kernel\n");
if (kfp == NULL) {
printf("aout_loadfile: can't load module before kernel\n");
err = EPERM;
goto oerr;
}
if (strcmp(aout_kerneltype, kmp->m_type)) {
printf("aout_loadmodule: can't load module with kernel type '%s'\n", kmp->m_type);
if (strcmp(aout_kerneltype, kfp->f_type)) {
printf("aout_loadfile: can't load module with kernel type '%s'\n", kfp->f_type);
err = EPERM;
goto oerr;
}
@ -107,8 +107,8 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
} else if (N_GETFLAG(ehdr) == 0) {
/* Looks like a kernel */
if (kmp != NULL) {
printf("aout_loadmodule: kernel already loaded\n");
if (kfp != NULL) {
printf("aout_loadfile: kernel already loaded\n");
err = EPERM;
goto oerr;
}
@ -118,7 +118,7 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
*/
dest = ehdr.a_entry & 0x100000;
if (dest == 0) {
printf("aout_loadmodule: not a kernel (maybe static binary?)\n");
printf("aout_loadfile: not a kernel (maybe static binary?)\n");
err = EPERM;
goto oerr;
}
@ -131,15 +131,15 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
/*
* Ok, we think we should handle this.
*/
mp = mod_allocmodule();
fp = file_alloc();
if (kernel)
setenv("kernelname", filename, 1);
s = strrchr(filename, '/');
if (s)
mp->m_name = strdup(s + 1);
fp->f_name = strdup(s + 1);
else
mp->m_name = strdup(filename);
mp->m_type = strdup(kernel ? aout_kerneltype : aout_moduletype);
fp->f_name = strdup(filename);
fp->f_type = strdup(kernel ? aout_kerneltype : aout_moduletype);
/* Page-align the load address */
addr = dest;
@ -148,32 +148,32 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
pad = PAGE_SIZE - pad;
addr += pad;
}
mp->m_addr = addr; /* save the aligned load address */
fp->f_addr = addr; /* save the aligned load address */
if (kernel)
printf("%s at %p\n", filename, (void *) addr);
mp->m_size = aout_loadimage(mp, fd, addr, &ehdr, kernel);
if (mp->m_size == 0)
fp->f_size = aout_loadimage(fp, fd, addr, &ehdr, kernel);
if (fp->f_size == 0)
goto ioerr;
#if 0
/* Handle KLD module data */
if (!kernel && ((err = aout_fixupkldmod(mp, &ehdr)) != 0))
if (!kernel && ((err = aout_fixupkldmod(fp, &ehdr)) != 0))
goto oerr;
#endif
/* save exec header as metadata */
mod_addmetadata(mp, MODINFOMD_AOUTEXEC, sizeof(struct exec), &ehdr);
file_addmetadata(fp, MODINFOMD_AOUTEXEC, sizeof(struct exec), &ehdr);
/* Load OK, return module pointer */
*result = (struct loaded_module *)mp;
*result = fp;
err = 0;
goto out;
ioerr:
err = EIO;
oerr:
mod_discard(mp);
file_discard(fp);
out:
close(fd);
return(err);
@ -187,7 +187,7 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
* align the symbol table.
*/
static int
aout_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel)
aout_loadimage(struct preloaded_file *fp, int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel)
{
u_int pad;
vm_offset_t addr;
@ -227,7 +227,7 @@ aout_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, struct ex
addr += sizeof(ehdr->a_syms);
/* symbol table */
printf("symbols=[0x%lx+0x%lx", sizeof(ehdr->a_syms), ehdr->a_syms);
printf("symbols=[0x%x+0x%lx", sizeof(ehdr->a_syms), ehdr->a_syms);
if (archsw.arch_readin(fd, addr, ehdr->a_syms) != ehdr->a_syms)
return(0);
addr += ehdr->a_syms;
@ -237,14 +237,14 @@ aout_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, struct ex
archsw.arch_copyin(&ss, addr, sizeof(ss));
addr += sizeof(ss);
ss -= sizeof(ss);
printf("+0x%lx+0x%x]", sizeof(ss), ss);
printf("+0x%x+0x%x]", sizeof(ss), ss);
if (archsw.arch_readin(fd, addr, ss) != ss)
return(0);
addr += ss;
esym = addr;
mod_addmetadata(mp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
mod_addmetadata(mp, MODINFOMD_ESYM, sizeof(esym), &esym);
file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym);
} else {
printf("symbols=[none]");
}

View File

@ -31,6 +31,7 @@
#include <sys/exec.h>
#include <sys/reboot.h>
#include <sys/linker.h>
#include <sys/module.h>
#include <string.h>
#include <machine/bootinfo.h>
#include <machine/elf.h>
@ -40,7 +41,30 @@
#include "bootstrap.h"
static int elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, Elf_Ehdr *ehdr, int kernel, caddr_t firstpage, int firstlen);
#define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l)
typedef struct elf_file {
Elf_Phdr *ph;
Elf_Ehdr *ehdr;
Elf_Sym *symtab;
Elf_Off *hashtab;
Elf_Off nbuckets;
Elf_Off nchains;
Elf_Off* buckets;
Elf_Off* chains;
char *strtab;
size_t strsz;
int fd;
caddr_t firstpage;
int firstlen;
int kernel;
vm_offset_t off;
} *elf_file_t;
static int elf_loadimage(struct preloaded_file *mp, elf_file_t ef, vm_offset_t loadaddr);
static int elf_lookup_symbol(struct preloaded_file *mp, elf_file_t ef, const char* name, Elf_Sym* sym);
static int elf_parse_modmetadata(struct preloaded_file *mp, elf_file_t ef);
char *elf_kerneltype = "elf kernel";
char *elf_moduletype = "elf module";
@ -51,35 +75,36 @@ char *elf_moduletype = "elf module";
* will be saved in (result).
*/
int
elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result)
{
struct loaded_module *mp, *kmp;
Elf_Ehdr *ehdr;
int fd;
int err, kernel;
struct preloaded_file *fp, *kfp;
struct elf_file ef;
Elf_Ehdr *ehdr;
int err;
u_int pad;
char *s;
caddr_t firstpage;
int firstlen;
mp = NULL;
fp = NULL;
bzero(&ef, sizeof(struct elf_file));
/*
* Open the image, read and validate the ELF header
*/
if (filename == NULL) /* can't handle nameless */
return(EFTYPE);
if ((fd = open(filename, O_RDONLY)) == -1)
if ((ef.fd = open(filename, O_RDONLY)) == -1)
return(errno);
firstpage = malloc(PAGE_SIZE);
if (firstpage == NULL)
ef.firstpage = malloc(PAGE_SIZE);
if (ef.firstpage == NULL) {
close(ef.fd);
return(ENOMEM);
firstlen = read(fd, firstpage, PAGE_SIZE);
if (firstlen <= sizeof(ehdr)) {
}
ef.firstlen = read(ef.fd, ef.firstpage, PAGE_SIZE);
if (ef.firstlen <= sizeof(Elf_Ehdr)) {
err = EFTYPE; /* could be EIO, but may be small file */
goto oerr;
}
ehdr = (Elf_Ehdr *)firstpage;
ehdr = ef.ehdr = (Elf_Ehdr *)ef.firstpage;
/* Is it ELF? */
if (!IS_ELF(*ehdr)) {
@ -99,21 +124,21 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
/*
* Check to see what sort of module we are.
*/
kmp = mod_findmodule(NULL, NULL);
kfp = file_findfile(NULL, NULL);
if (ehdr->e_type == ET_DYN) {
/* Looks like a kld module */
if (kmp == NULL) {
printf("elf_loadmodule: can't load module before kernel\n");
if (kfp == NULL) {
printf("elf_loadfile: can't load module before kernel\n");
err = EPERM;
goto oerr;
}
if (strcmp(elf_kerneltype, kmp->m_type)) {
printf("elf_loadmodule: can't load module with kernel type '%s'\n", kmp->m_type);
if (strcmp(elf_kerneltype, kfp->f_type)) {
printf("elf_loadfile: can't load module with kernel type '%s'\n", kfp->f_type);
err = EPERM;
goto oerr;
}
/* Looks OK, got ahead */
kernel = 0;
ef.kernel = 0;
/* Page-align the load address */
pad = (u_int)dest & PAGE_MASK;
@ -123,8 +148,8 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
}
} else if (ehdr->e_type == ET_EXEC) {
/* Looks like a kernel */
if (kmp != NULL) {
printf("elf_loadmodule: kernel already loaded\n");
if (kfp != NULL) {
printf("elf_loadfile: kernel already loaded\n");
err = EPERM;
goto oerr;
}
@ -133,11 +158,11 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
*/
dest = (vm_offset_t) ehdr->e_entry;
if (dest == 0) {
printf("elf_loadmodule: not a kernel (maybe static binary?)\n");
printf("elf_loadfile: not a kernel (maybe static binary?)\n");
err = EPERM;
goto oerr;
}
kernel = 1;
ef.kernel = 1;
} else {
err = EFTYPE;
@ -147,48 +172,48 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
/*
* Ok, we think we should handle this.
*/
mp = mod_allocmodule();
if (mp == NULL) {
printf("elf_loadmodule: cannot allocate module info\n");
fp = file_alloc();
if (fp == NULL) {
printf("elf_loadfile: cannot allocate module info\n");
err = EPERM;
goto out;
}
if (kernel)
if (ef.kernel)
setenv("kernelname", filename, 1);
s = strrchr(filename, '/');
if (s)
mp->m_name = strdup(s + 1);
fp->f_name = strdup(s + 1);
else
mp->m_name = strdup(filename);
mp->m_type = strdup(kernel ? elf_kerneltype : elf_moduletype);
fp->f_name = strdup(filename);
fp->f_type = strdup(ef.kernel ? elf_kerneltype : elf_moduletype);
#ifdef ELF_VERBOSE
if (kernel)
if (ef.kernel)
printf("%s entry at %p\n", filename, (void *) dest);
#else
printf("%s ", filename);
#endif
mp->m_size = elf_loadimage(mp, fd, dest, ehdr, kernel, firstpage, firstlen);
if (mp->m_size == 0 || mp->m_addr == 0)
fp->f_size = elf_loadimage(fp, &ef, dest);
if (fp->f_size == 0 || fp->f_addr == 0)
goto ioerr;
/* save exec header as metadata */
mod_addmetadata(mp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr);
file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr);
/* Load OK, return module pointer */
*result = (struct loaded_module *)mp;
*result = (struct preloaded_file *)fp;
err = 0;
goto out;
ioerr:
err = EIO;
oerr:
mod_discard(mp);
file_discard(fp);
out:
if (firstpage)
free(firstpage);
close(fd);
if (ef.firstpage)
free(ef.firstpage);
close(ef.fd);
return(err);
}
@ -197,11 +222,11 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
* the Elf header, load the image at (off)
*/
static int
elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
Elf_Ehdr *ehdr, int kernel, caddr_t firstpage, int firstlen)
elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off)
{
int i, j;
Elf_Phdr *phdr;
Elf_Ehdr *ehdr;
Elf_Phdr *phdr, *php;
Elf_Shdr *shdr;
int ret;
vm_offset_t firstaddr;
@ -213,8 +238,6 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
Elf_Dyn *dp;
int ndp;
char *s;
char *strtab;
size_t strsz;
int symstrindex;
int symtabindex;
long size;
@ -224,19 +247,21 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
shdr = NULL;
ret = 0;
firstaddr = lastaddr = 0;
if (kernel) {
ehdr = ef->ehdr;
if (ef->kernel) {
#ifdef __i386__
off = - (off & 0xff000000u); /* i386 relocates after locore */
#else
off = 0; /* alpha is direct mapped for kernels */
#endif
}
ef->off = off;
if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > firstlen) {
if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > ef->firstlen) {
printf("elf_loadimage: program header not within first page\n");
goto out;
}
phdr = (Elf_Phdr *)(firstpage + ehdr->e_phoff);
phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff);
for (i = 0; i < ehdr->e_phnum; i++) {
/* We want to load PT_LOAD segments only.. */
@ -259,17 +284,17 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
}
#endif
fpcopy = 0;
if (firstlen > phdr[i].p_offset) {
fpcopy = firstlen - phdr[i].p_offset;
archsw.arch_copyin(firstpage + phdr[i].p_offset,
if (ef->firstlen > phdr[i].p_offset) {
fpcopy = ef->firstlen - phdr[i].p_offset;
archsw.arch_copyin(ef->firstpage + phdr[i].p_offset,
phdr[i].p_vaddr + off, fpcopy);
}
if (phdr[i].p_filesz > fpcopy) {
if (lseek(fd, phdr[i].p_offset + fpcopy, SEEK_SET) == -1) {
if (lseek(ef->fd, phdr[i].p_offset + fpcopy, SEEK_SET) == -1) {
printf("\nelf_loadexec: cannot seek\n");
goto out;
}
if (archsw.arch_readin(fd, phdr[i].p_vaddr + off + fpcopy,
if (archsw.arch_readin(ef->fd, phdr[i].p_vaddr + off + fpcopy,
phdr[i].p_filesz - fpcopy) != phdr[i].p_filesz - fpcopy) {
printf("\nelf_loadexec: archsw.readin failed\n");
goto out;
@ -285,6 +310,10 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
/* no archsw.arch_bzero */
buf = malloc(PAGE_SIZE);
if (buf == NULL) {
printf("\nelf_loadimage: malloc() failed\n");
goto out;
}
bzero(buf, PAGE_SIZE);
resid = phdr[i].p_memsz - phdr[i].p_filesz;
dest = phdr[i].p_vaddr + off + phdr[i].p_filesz;
@ -319,11 +348,11 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
shdr = malloc(chunk);
if (shdr == NULL)
goto nosyms;
if (lseek(fd, ehdr->e_shoff, SEEK_SET) == -1) {
if (lseek(ef->fd, ehdr->e_shoff, SEEK_SET) == -1) {
printf("\nelf_loadimage: cannot lseek() to section headers");
goto nosyms;
}
if (read(fd, shdr, chunk) != chunk) {
if (read(ef->fd, shdr, chunk) != chunk) {
printf("\nelf_loadimage: read section headers failed");
goto nosyms;
}
@ -388,13 +417,13 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
printf("0x%lx+0x%lx", (long)sizeof(size), size);
#endif
if (lseek(fd, shdr[i].sh_offset, SEEK_SET) == -1) {
if (lseek(ef->fd, shdr[i].sh_offset, SEEK_SET) == -1) {
printf("\nelf_loadimage: could not seek for symbols - skipped!");
lastaddr = ssym;
ssym = 0;
goto nosyms;
}
if (archsw.arch_readin(fd, lastaddr, shdr[i].sh_size) !=
if (archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size) !=
shdr[i].sh_size) {
printf("\nelf_loadimage: could not read symbols - skipped!");
lastaddr = ssym;
@ -414,66 +443,81 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
printf("]");
#endif
mod_addmetadata(mp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
mod_addmetadata(mp, MODINFOMD_ESYM, sizeof(esym), &esym);
file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym);
nosyms:
printf("\n");
ret = lastaddr - firstaddr;
mp->m_addr = firstaddr;
fp->f_addr = firstaddr;
php = NULL;
for (i = 0; i < ehdr->e_phnum; i++) {
if (phdr[i].p_type == PT_DYNAMIC) {
dp = (Elf_Dyn *)(phdr[i].p_vaddr);
mod_addmetadata(mp, MODINFOMD_DYNAMIC, sizeof(dp), &dp);
php = phdr + i;
dp = (Elf_Dyn *)(php->p_vaddr);
file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(dp), &dp);
dp = NULL;
break;
}
}
if (kernel) /* kernel must not depend on anything */
if (php == NULL) /* this is bad, we cannot get to symbols or _DYNAMIC */
goto out;
ndp = 0;
for (i = 0; i < ehdr->e_phnum; i++) {
if (phdr[i].p_type == PT_DYNAMIC) {
ndp = phdr[i].p_filesz / sizeof(Elf_Dyn);
dp = malloc(phdr[i].p_filesz);
archsw.arch_copyout(phdr[i].p_vaddr + off, dp, phdr[i].p_filesz);
}
}
if (dp == NULL || ndp == 0)
ndp = php->p_filesz / sizeof(Elf_Dyn);
if (ndp == 0)
goto out;
strtab = NULL;
strsz = 0;
dp = malloc(php->p_filesz);
if (dp == NULL)
goto out;
archsw.arch_copyout(php->p_vaddr + off, dp, php->p_filesz);
ef->strsz = 0;
for (i = 0; i < ndp; i++) {
if (dp[i].d_tag == NULL)
break;
switch (dp[i].d_tag) {
case DT_HASH:
ef->hashtab = (Elf_Off*)(dp[i].d_un.d_ptr + off);
break;
case DT_STRTAB:
strtab = (char *)(dp[i].d_un.d_ptr + off);
ef->strtab = (char *)(dp[i].d_un.d_ptr + off);
break;
case DT_STRSZ:
strsz = dp[i].d_un.d_val;
ef->strsz = dp[i].d_un.d_val;
break;
case DT_SYMTAB:
ef->symtab = (Elf_Sym*)(dp[i].d_un.d_ptr + off);
break;
default:
break;
}
}
if (strtab == NULL || strsz == 0)
if (ef->hashtab == NULL || ef->symtab == NULL ||
ef->strtab == NULL || ef->strsz == 0)
goto out;
COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets));
COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains));
ef->buckets = ef->hashtab + 2;
ef->chains = ef->buckets + ef->nbuckets;
if (elf_parse_modmetadata(fp, ef) == 0)
goto out;
if (ef->kernel) /* kernel must not depend on anything */
goto out;
for (i = 0; i < ndp; i++) {
if (dp[i].d_tag == NULL)
if (dp[i].d_tag == NULL)
break;
if (dp[i].d_tag != DT_NEEDED)
continue;
j = dp[i].d_un.d_ptr;
if (j < 1 || j > (strsz - 2))
continue; /* bad symbol name index */
s = strdupout((vm_offset_t)&strtab[j]);
mod_addmetadata(mp, MODINFOMD_DEPLIST, strlen(s) + 1, s);
if (j < 1 || j > ef->strsz - 2)
continue;
s = strdupout((vm_offset_t)&ef->strtab[j]);
file_addmetadata(fp, MODINFOMD_DEPLIST, strlen(s) + 1, s);
free(s);
}
@ -484,3 +528,131 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
free(shdr);
return ret;
}
static char invalid_name[] = "bad";
char *
fake_modname(char *name) {
char *sp, *ep;
int len;
sp = strrchr(name, '/');
if (sp)
sp++;
else
sp = name;
ep = strrchr(name, '.');
if (ep) {
if (ep == name) {
sp = invalid_name;
ep = invalid_name + sizeof(invalid_name) - 1;
}
} else
ep = name + strlen(name);
len = ep - sp;
ep = malloc(len + 1);
if (ep == NULL)
return NULL;
memcpy(ep, sp, len);
ep[len] = '\0';
return ep;
}
int
elf_parse_modmetadata(struct preloaded_file *fp, elf_file_t ef) {
struct mod_metadata md;
Elf_Sym sym;
void **p, *v;
char *s;
int entries, modcnt;
if (elf_lookup_symbol(fp, ef, "modmetadata_set", &sym) != 0)
return ENOENT;
COPYOUT(sym.st_value + ef->off, &entries, sizeof(entries));
modcnt = 0;
p = (void*)(sym.st_value + ef->off + sizeof(entries));
while (entries--) {
COPYOUT(p++, &v, sizeof(v));
COPYOUT(v + ef->off, &md, sizeof(md));
switch(md.md_type) {
case MDT_DEPEND:
if (ef->kernel) /* kernel must not depend on anything */
break;
s = strdupout((vm_offset_t)(md.md_cval + ef->off));
file_addmetadata(fp, MODINFOMD_DEPLIST, strlen(s) + 1, s);
free(s);
break;
case MDT_VERSION:
s = strdupout((vm_offset_t)(md.md_cval + ef->off));
file_addmodule(fp, s, NULL);
printf(" module: %s\n", s);
free(s);
modcnt++;
break;
}
}
if (modcnt == 0) {
s = fake_modname(fp->f_name);
file_addmodule(fp, s, NULL);
free(s);
}
return 0;
}
static unsigned long
elf_hash(const char *name)
{
const unsigned char *p = (const unsigned char *) name;
unsigned long h = 0;
unsigned long g;
while (*p != '\0') {
h = (h << 4) + *p++;
if ((g = h & 0xf0000000) != 0)
h ^= g >> 24;
h &= ~g;
}
return h;
}
static const char elf_bad_symtable[] = "elf_lookup_symbol: corrupt symbol table\n";
int
elf_lookup_symbol(struct preloaded_file *fp, elf_file_t ef, const char* name,
Elf_Sym *symp)
{
unsigned long symnum;
Elf_Sym sym;
char *strp;
unsigned long hash;
hash = elf_hash(name);
COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof(symnum));
while (symnum != STN_UNDEF) {
if (symnum >= ef->nchains) {
printf(elf_bad_symtable);
return ENOENT;
}
COPYOUT(ef->symtab + symnum, &sym, sizeof(sym));
if (sym.st_name == 0) {
printf(elf_bad_symtable);
return ENOENT;
}
strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name));
if (strcmp(name, strp) == 0) {
free(strp);
if (sym.st_shndx != SHN_UNDEF ||
(sym.st_value != 0 &&
ELF_ST_TYPE(sym.st_info) == STT_FUNC)) {
*symp = sym;
return 0;
}
return ENOENT;
}
free(strp);
COPYOUT(&ef->chains[symnum], &symnum, sizeof(symnum));
}
return ENOENT;
}

View File

@ -27,7 +27,7 @@
*/
/*
* module function dispatcher, support, etc.
* file/module function dispatcher, support, etc.
*/
#include <stand.h>
@ -37,19 +37,21 @@
#include "bootstrap.h"
static int mod_loadmodule(char *name, int argc, char *argv[], struct loaded_module **mpp);
static int file_load_dependancies(struct loaded_module *base_file);
static char *mod_searchfile(char *name);
static int file_load(char *filename, vm_offset_t dest, struct preloaded_file **result);
static int file_loadraw(char *type, char *name);
static int file_load_dependancies(struct preloaded_file *base_mod);
static char * file_search(char *name);
struct kernel_module * file_findmodule(struct preloaded_file *fp, char *modname);
static char *mod_searchmodule(char *name);
static void mod_append(struct loaded_module *mp);
static struct module_metadata *metadata_next(struct module_metadata *md, int type);
static void file_insert_tail(struct preloaded_file *mp);
struct file_metadata* metadata_next(struct file_metadata *base_mp, int type);
/* load address should be tweaked by first module loaded (kernel) */
static vm_offset_t loadaddr = 0;
static char *default_searchpath ="/;/boot;/modules";
struct loaded_module *loaded_modules = NULL;
struct preloaded_file *preloaded_files = NULL;
/*
* load an object, either a disk file or code module.
@ -102,7 +104,7 @@ command_load(int argc, char *argv[])
command_errmsg = "invalid load type";
return(CMD_ERROR);
}
return(mod_loadobj(typestr, argv[1]));
return(file_loadraw(typestr, argv[1]));
}
/*
@ -119,12 +121,12 @@ COMMAND_SET(unload, "unload", "unload all modules", command_unload);
static int
command_unload(int argc, char *argv[])
{
struct loaded_module *mp;
struct preloaded_file *fp;
while (loaded_modules != NULL) {
mp = loaded_modules;
loaded_modules = loaded_modules->m_next;
mod_discard(mp);
while (preloaded_files != NULL) {
fp = preloaded_files;
preloaded_files = preloaded_files->f_next;
file_discard(fp);
}
loadaddr = 0;
return(CMD_OK);
@ -135,8 +137,9 @@ COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod);
static int
command_lsmod(int argc, char *argv[])
{
struct loaded_module *am;
struct module_metadata *md;
struct preloaded_file *fp;
struct kernel_module *mp;
struct file_metadata *md;
char lbuf[80];
int ch, verbose;
@ -156,90 +159,115 @@ command_lsmod(int argc, char *argv[])
}
pager_open();
for (am = loaded_modules; (am != NULL); am = am->m_next) {
for (fp = preloaded_files; fp; fp = fp->f_next) {
sprintf(lbuf, " %p: %s (%s, 0x%lx)\n",
(void *) am->m_addr, am->m_name, am->m_type, (long) am->m_size);
(void *) fp->f_addr, fp->f_name, fp->f_type, (long) fp->f_size);
pager_output(lbuf);
if (am->m_args != NULL) {
if (fp->f_args != NULL) {
pager_output(" args: ");
pager_output(am->m_args);
pager_output(fp->f_args);
pager_output("\n");
}
if (verbose)
if (fp->f_modules) {
pager_output(" modules: ");
for (mp = fp->f_modules; mp; mp = mp->m_next) {
sprintf(lbuf, "%s ", mp->m_name);
pager_output(lbuf);
}
pager_output("\n");
}
if (verbose) {
/* XXX could add some formatting smarts here to display some better */
for (md = am->m_metadata; md != NULL; md = md->md_next) {
for (md = fp->f_metadata; md != NULL; md = md->md_next) {
sprintf(lbuf, " 0x%04x, 0x%lx\n", md->md_type, (long) md->md_size);
pager_output(lbuf);
}
}
}
pager_close();
return(CMD_OK);
}
/*
* We've been asked to load (name) and give it (argc),(argv).
* Start by trying to load it, and then attempt to load all of its
* dependancies. If we fail at any point, throw them all away and
* fail the entire load.
*
* XXX if a depended-on module requires arguments, it must be loaded
* explicitly first.
* File level interface, functions file_*
*/
int
mod_load(char *name, int argc, char *argv[])
file_load(char *filename, vm_offset_t dest, struct preloaded_file **result)
{
struct loaded_module *last_mod, *base_mod, *mp;
int error;
struct preloaded_file *fp;
int error;
int i;
/* remember previous last module on chain */
for (last_mod = loaded_modules;
(last_mod != NULL) && (last_mod->m_next != NULL);
last_mod = last_mod->m_next)
;
/*
* Load the first module; note that it's the only one that gets
* arguments explicitly.
*/
error = mod_loadmodule(name, argc, argv, &base_mod);
if (error)
return (error);
error = file_load_dependancies(base_mod);
if (!error)
return (0);
/* Load failed; discard everything */
last_mod->m_next = NULL;
loadaddr = last_mod->m_addr + last_mod->m_size;
while (base_mod != NULL) {
mp = base_mod;
base_mod = base_mod->m_next;
mod_discard(mp);
error = EFTYPE;
for (i = 0, fp = NULL; file_formats[i] && fp == NULL; i++) {
error = (file_formats[i]->l_load)(filename, loadaddr, &fp);
if (error == 0) {
fp->f_loader = i; /* remember the loader */
*result = fp;
break;
}
if (error == EFTYPE)
continue; /* Unknown to this handler? */
if (error) {
sprintf(command_errbuf, "can't load file '%s': %s",
filename, strerror(error));
break;
}
}
return (error);
}
static int
file_load_dependancies(struct preloaded_file *base_file) {
struct file_metadata *md;
struct preloaded_file *fp;
char *dmodname;
int error;
md = file_findmetadata(base_file, MODINFOMD_DEPLIST);
if (md == NULL)
return (0);
error = 0;
do {
dmodname = (char *)md->md_data;
if (file_findmodule(NULL, dmodname) == NULL) {
printf("loading required module '%s'\n", dmodname);
error = mod_load(dmodname, 0, NULL);
if (error)
break;
}
md = metadata_next(md, MODINFOMD_DEPLIST);
} while (md);
if (!error)
return (0);
/* Load failed; discard everything */
while (base_file != NULL) {
fp = base_file;
base_file = base_file->f_next;
file_discard(fp);
}
return (error);
}
/*
* We've been asked to load (name) as (type), so just suck it in,
* no arguments or anything.
*/
int
mod_loadobj(char *type, char *name)
file_loadraw(char *type, char *name)
{
struct loaded_module *mp;
struct preloaded_file *fp;
char *cp;
int fd, got;
vm_offset_t laddr;
/* We can't load first */
if ((mod_findmodule(NULL, NULL)) == NULL) {
if ((file_findfile(NULL, NULL)) == NULL) {
command_errmsg = "can't load file before kernel";
return(CMD_ERROR);
}
/* locate the file on the load path */
cp = mod_searchfile(name);
cp = file_search(name);
if (cp == NULL) {
sprintf(command_errbuf, "can't find '%s'", name);
return(CMD_ERROR);
@ -268,166 +296,168 @@ mod_loadobj(char *type, char *name)
}
/* Looks OK so far; create & populate control structure */
mp = malloc(sizeof(struct loaded_module));
mp->m_name = name;
mp->m_type = strdup(type);
mp->m_args = NULL;
mp->m_metadata = NULL;
mp->m_loader = -1;
mp->m_addr = loadaddr;
mp->m_size = laddr - loadaddr;
fp = file_alloc();
fp->f_name = name;
fp->f_type = strdup(type);
fp->f_args = NULL;
fp->f_metadata = NULL;
fp->f_loader = -1;
fp->f_addr = loadaddr;
fp->f_size = laddr - loadaddr;
/* recognise space consumption */
loadaddr = laddr;
/* Add to the list of loaded modules */
mod_append(mp);
/* Add to the list of loaded files */
file_insert_tail(fp);
close(fd);
return(CMD_OK);
}
/*
* Load the module (name), pass it (argc),(argv).
* Don't do any dependancy checking.
* Load the module (name), pass it (argc),(argv), add container file
* to the list of loaded files.
* If module is already loaded just assign new argc/argv.
*/
static int
mod_loadmodule(char *name, int argc, char *argv[], struct loaded_module **mpp)
int
mod_load(char *modname, int argc, char *argv[])
{
struct loaded_module *mp;
int i, err;
char *cp;
struct preloaded_file *fp, *last_file;
struct kernel_module *mp;
int err;
char *filename;
/* locate the module on the search path */
cp = mod_searchmodule(name);
if (cp == NULL) {
sprintf(command_errbuf, "can't find '%s'", name);
/* see if module is already loaded */
mp = file_findmodule(NULL, modname);
if (mp) {
#ifdef moduleargs
if (mp->m_args)
free(mp->m_args);
mp->m_args = unargv(argc, argv);
#endif
sprintf(command_errbuf, "warning: module '%s' already loaded", mp->m_name);
return (0);
}
/* locate file with the module on the search path */
filename = mod_searchmodule(modname);
if (filename == NULL) {
sprintf(command_errbuf, "can't find '%s'", modname);
return (ENOENT);
}
name = cp;
cp = strrchr(name, '/');
if (cp)
cp++;
else
cp = name;
/* see if module is already loaded */
mp = mod_findmodule(cp, NULL);
if (mp) {
*mpp = mp;
return (EEXIST);
}
err = 0;
for (i = 0, mp = NULL; (module_formats[i] != NULL) && (mp == NULL); i++) {
if ((err = (module_formats[i]->l_load)(name, loadaddr, &mp)) != 0) {
/* Unknown to this handler? */
if (err == EFTYPE)
continue;
/* Fatal error */
sprintf(command_errbuf, "can't load module '%s': %s", name, strerror(err));
free(name);
return (err);
} else {
/* Load was OK, set args */
mp->m_args = unargv(argc, argv);
/* where can we put the next one? */
loadaddr = mp->m_addr + mp->m_size;
/* remember the loader */
mp->m_loader = i;
/* Add to the list of loaded modules */
mod_append(mp);
*mpp = mp;
for (last_file = preloaded_files;
last_file != NULL && last_file->f_next != NULL;
last_file = last_file->f_next)
;
fp = NULL;
do {
err = file_load(filename, loadaddr, &fp);
if (err)
break;
#ifdef moduleargs
mp = file_findmodule(fp, modname);
if (mp == NULL) {
sprintf(command_errbuf, "module '%s' not found in the file '%s': %s",
modname, filename, strerror(err));
err = ENOENT;
break;
}
}
mp->m_args = unargv(argc, argv);
#else
fp->f_args = unargv(argc, argv);
#endif
loadaddr = fp->f_addr + fp->f_size;
file_insert_tail(fp); /* Add to the list of loaded files */
if (file_load_dependancies(fp) != 0) {
err = ENOENT;
last_file->f_next = NULL;
loadaddr = last_file->f_addr + last_file->f_size;
fp = NULL;
break;
}
} while(0);
if (err == EFTYPE)
sprintf(command_errbuf, "don't know how to load module '%s'", name);
free(name);
sprintf(command_errbuf, "don't know how to load module '%s'", filename);
if (err && fp)
file_discard(fp);
free(filename);
return (err);
}
static int
file_load_dependancies(struct loaded_module *base_file)
/*
* Find a file matching (name) and (type).
* NULL may be passed as a wildcard to either.
*/
struct preloaded_file *
file_findfile(char *name, char *type)
{
struct module_metadata *md;
char *dmodname;
int error;
struct preloaded_file *fp;
md = mod_findmetadata(base_file, MODINFOMD_DEPLIST);
if (md == NULL)
return (0);
error = 0;
do {
dmodname = (char *)md->md_data;
if (mod_findmodule(NULL, dmodname) == NULL) {
printf("loading required module '%s'\n", dmodname);
error = mod_load(dmodname, 0, NULL);
if (error && error != EEXIST)
break;
}
md = metadata_next(md, MODINFOMD_DEPLIST);
} while (md);
return (error);
for (fp = preloaded_files; fp != NULL; fp = fp->f_next) {
if (((name == NULL) || !strcmp(name, fp->f_name)) &&
((type == NULL) || !strcmp(type, fp->f_type)))
break;
}
return (fp);
}
/*
* Find a module matching (name) and (type).
* NULL may be passed as a wildcard to either.
* Find a module matching (name) inside of given file.
* NULL may be passed as a wildcard.
*/
struct loaded_module *
mod_findmodule(char *name, char *type)
struct kernel_module *
file_findmodule(struct preloaded_file *fp, char *modname)
{
struct loaded_module *mp;
for (mp = loaded_modules; mp != NULL; mp = mp->m_next) {
if (((name == NULL) || !strcmp(name, mp->m_name)) &&
((type == NULL) || !strcmp(type, mp->m_type)))
break;
}
return(mp);
}
struct kernel_module *mp;
if (fp == NULL) {
for (fp = preloaded_files; fp; fp = fp->f_next) {
for (mp = fp->f_modules; mp; mp = mp->m_next) {
if (strcmp(modname, mp->m_name) == 0)
return (mp);
}
}
return (NULL);
}
for (mp = fp->f_modules; mp; mp = mp->m_next) {
if (strcmp(modname, mp->m_name) == 0)
return (mp);
}
return (NULL);
}
/*
* Make a copy of (size) bytes of data from (p), and associate them as
* metadata of (type) to the module (mp).
*/
void
mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p)
file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p)
{
struct module_metadata *md;
struct file_metadata *md;
md = malloc(sizeof(struct module_metadata) + size);
md = malloc(sizeof(struct file_metadata) + size);
md->md_size = size;
md->md_type = type;
bcopy(p, md->md_data, size);
md->md_next = mp->m_metadata;
mp->m_metadata = md;
md->md_next = fp->f_metadata;
fp->f_metadata = md;
}
/*
* Find a metadata object of (type) associated with the module
* (mp)
* Find a metadata object of (type) associated with the file (fp)
*/
struct module_metadata *
mod_findmetadata(struct loaded_module *mp, int type)
struct file_metadata *
file_findmetadata(struct preloaded_file *fp, int type)
{
struct module_metadata *md;
struct file_metadata *md;
for (md = mp->m_metadata; md != NULL; md = md->md_next)
for (md = fp->f_metadata; md != NULL; md = md->md_next)
if (md->md_type == type)
break;
return(md);
}
struct module_metadata *
metadata_next(struct module_metadata *md, int type)
struct file_metadata *
metadata_next(struct file_metadata *md, int type)
{
if (md == NULL)
return (NULL);
@ -448,7 +478,7 @@ metadata_next(struct module_metadata *md, int type)
* it internally.
*/
static char *
mod_searchfile(char *name)
file_search(char *name)
{
char *result;
char *path, *sp;
@ -490,7 +520,6 @@ mod_searchfile(char *name)
if (cp[strlen(cp) - 1] != '/')
strcat(result, "/");
strcat(result, name);
/* printf("search '%s'\n", result); */
if ((stat(result, &sb) == 0) &&
S_ISREG(sb.st_mode))
break;
@ -513,71 +542,101 @@ mod_searchmodule(char *name)
tn = malloc(strlen(name) + 3 + 1);
strcpy(tn, name);
strcat(tn, ".ko");
result = mod_searchfile(tn);
result = file_search(tn);
free(tn);
/* Look for just (name) (useful for finding kernels) */
if (result == NULL)
result = mod_searchfile(name);
result = file_search(name);
return(result);
}
int
file_addmodule(struct preloaded_file *fp, char *modname,
struct kernel_module **newmp)
{
struct kernel_module *mp;
mp = file_findmodule(fp, modname);
if (mp)
return (EEXIST);
mp = malloc(sizeof(struct kernel_module));
if (mp == NULL)
return (ENOMEM);
bzero(mp, sizeof(struct kernel_module));
mp->m_name = strdup(modname);
mp->m_fp = fp;
mp->m_next = fp->f_modules;
fp->f_modules = mp;
if (newmp)
*newmp = mp;
return (0);
}
/*
* Throw a module away
* Throw a file away
*/
void
mod_discard(struct loaded_module *mp)
file_discard(struct preloaded_file *fp)
{
struct module_metadata *md;
if (mp != NULL) {
while (mp->m_metadata != NULL) {
md = mp->m_metadata;
mp->m_metadata = mp->m_metadata->md_next;
free(md);
}
if (mp->m_name != NULL)
free(mp->m_name);
if (mp->m_type != NULL)
free(mp->m_type);
if (mp->m_args != NULL)
free(mp->m_args);
free(mp);
struct file_metadata *md, *md1;
struct kernel_module *mp, *mp1;
if (fp == NULL)
return;
md = fp->f_metadata;
while (md) {
md1 = md;
md = md->md_next;
free(md1);
}
mp = fp->f_modules;
while (mp) {
if (mp->m_name)
free(mp->m_name);
mp1 = mp;
mp = mp->m_next;
free(mp1);
}
if (fp->f_name != NULL)
free(fp->f_name);
if (fp->f_type != NULL)
free(fp->f_type);
if (fp->f_args != NULL)
free(fp->f_args);
free(fp);
}
/*
* Allocate a new module; must be used instead of malloc()
* Allocate a new file; must be used instead of malloc()
* to ensure safe initialisation.
*/
struct loaded_module *
mod_allocmodule(void)
struct preloaded_file *
file_alloc(void)
{
struct loaded_module *mp;
struct preloaded_file *fp;
if ((mp = malloc(sizeof(struct loaded_module))) != NULL) {
bzero(mp, sizeof(struct loaded_module));
if ((fp = malloc(sizeof(struct preloaded_file))) != NULL) {
bzero(fp, sizeof(struct preloaded_file));
}
return(mp);
return (fp);
}
/*
* Add a module to the chain
*/
static void
mod_append(struct loaded_module *mp)
file_insert_tail(struct preloaded_file *fp)
{
struct loaded_module *cm;
struct preloaded_file *cm;
/* Append to list of loaded modules */
mp->m_next = NULL;
if (loaded_modules == NULL) {
loaded_modules = mp;
/* Append to list of loaded file */
fp->f_next = NULL;
if (preloaded_files == NULL) {
preloaded_files = fp;
} else {
for (cm = loaded_modules; cm->m_next != NULL; cm = cm->m_next)
for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next)
;
cm->m_next = mp;
cm->f_next = fp;
}
}

View File

@ -1,5 +1,7 @@
/*
* mjs copyright
*
* $FreeBSD$
*/
/*
* "Plug and Play" functionality.
@ -113,7 +115,7 @@ pnp_load(int argc, char *argv[])
/* try to load any modules that have been nominated */
for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) {
/* Already loaded? */
if ((pi->pi_module != NULL) && (mod_findmodule(pi->pi_module, NULL) == NULL)) {
if ((pi->pi_module != NULL) && (file_findfile(pi->pi_module, NULL) == NULL)) {
modfname = malloc(strlen(pi->pi_module) + 4);
sprintf(modfname, "%s.ko", pi->pi_module); /* XXX implicit knowledge of KLD module filenames */
if (mod_load(pi->pi_module, pi->pi_argc, pi->pi_argv))

View File

@ -39,9 +39,9 @@
#include "libi386.h"
#include "btxv86.h"
static int aout_exec(struct loaded_module *amp);
static int aout_exec(struct preloaded_file *fp);
struct module_format i386_aout = { aout_loadmodule, aout_exec };
struct file_format i386_aout = { aout_loadfile, aout_exec };
/*
* There is an a.out kernel and one or more a.out modules loaded.
@ -49,27 +49,27 @@ struct module_format i386_aout = { aout_loadmodule, aout_exec };
* preparations as are required, and do so.
*/
static int
aout_exec(struct loaded_module *mp)
aout_exec(struct preloaded_file *fp)
{
struct module_metadata *md;
struct file_metadata *md;
struct exec *ehdr;
vm_offset_t entry, bootinfop;
int boothowto, err, bootdev;
struct bootinfo *bi;
vm_offset_t ssym, esym;
if ((md = mod_findmetadata(mp, MODINFOMD_AOUTEXEC)) == NULL)
if ((md = file_findmetadata(fp, MODINFOMD_AOUTEXEC)) == NULL)
return(EFTYPE); /* XXX actually EFUCKUP */
ehdr = (struct exec *)&(md->md_data);
if ((err = bi_load(mp->m_args, &boothowto, &bootdev, &bootinfop)) != 0)
if ((err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop)) != 0)
return(err);
entry = ehdr->a_entry & 0xffffff;
ssym = esym = 0;
if ((md = mod_findmetadata(mp, MODINFOMD_SSYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL)
ssym = *((vm_offset_t *)&(md->md_data));
if ((md = mod_findmetadata(mp, MODINFOMD_ESYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL)
esym = *((vm_offset_t *)&(md->md_data));
if (ssym == 0 || esym == 0)
ssym = esym = 0; /* sanity */

View File

@ -203,19 +203,19 @@ bi_copyenv(vm_offset_t addr)
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct loaded_module *mp;
struct module_metadata *md;
struct preloaded_file *fp;
struct file_metadata *md;
/* start with the first module on the list, should be the kernel */
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
MOD_NAME(addr, mp->m_name); /* this field must come first */
MOD_TYPE(addr, mp->m_type);
if (mp->m_args)
MOD_ARGS(addr, mp->m_args);
MOD_ADDR(addr, mp->m_addr);
MOD_SIZE(addr, mp->m_size);
for (md = mp->m_metadata; md != NULL; md = md->md_next)
MOD_NAME(addr, fp->f_name); /* this field must come first */
MOD_TYPE(addr, fp->f_type);
if (fp->f_args)
MOD_ARGS(addr, fp->f_args);
MOD_ADDR(addr, fp->f_addr);
MOD_SIZE(addr, fp->f_size);
for (md = fp->f_metadata; md != NULL; md = md->md_next)
if (!(md->md_type & MODINFOMD_NOCOPY))
MOD_METADATA(addr, md);
}
@ -235,7 +235,7 @@ bi_copymodules(vm_offset_t addr)
int
bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip)
{
struct loaded_module *xp;
struct preloaded_file *xp;
struct i386_devdesc *rootdev;
vm_offset_t addr, bootinfo_addr;
char *rootdevname;
@ -295,9 +295,9 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip)
/* find the last module in the chain */
addr = 0;
for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) {
if (addr < (xp->m_addr + xp->m_size))
addr = xp->m_addr + xp->m_size;
for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
if (addr < (xp->f_addr + xp->f_size))
addr = xp->f_addr + xp->f_size;
}
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;

View File

@ -203,19 +203,19 @@ bi_copyenv(vm_offset_t addr)
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct loaded_module *mp;
struct module_metadata *md;
struct preloaded_file *fp;
struct file_metadata *md;
/* start with the first module on the list, should be the kernel */
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
MOD_NAME(addr, mp->m_name); /* this field must come first */
MOD_TYPE(addr, mp->m_type);
if (mp->m_args)
MOD_ARGS(addr, mp->m_args);
MOD_ADDR(addr, mp->m_addr);
MOD_SIZE(addr, mp->m_size);
for (md = mp->m_metadata; md != NULL; md = md->md_next)
MOD_NAME(addr, fp->f_name); /* this field must come first */
MOD_TYPE(addr, fp->f_type);
if (fp->f_args)
MOD_ARGS(addr, fp->f_args);
MOD_ADDR(addr, fp->f_addr);
MOD_SIZE(addr, fp->f_size);
for (md = fp->f_metadata; md != NULL; md = md->md_next)
if (!(md->md_type & MODINFOMD_NOCOPY))
MOD_METADATA(addr, md);
}
@ -235,7 +235,7 @@ bi_copymodules(vm_offset_t addr)
int
bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip)
{
struct loaded_module *xp;
struct preloaded_file *xp;
struct i386_devdesc *rootdev;
vm_offset_t addr, bootinfo_addr;
char *rootdevname;
@ -295,9 +295,9 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip)
/* find the last module in the chain */
addr = 0;
for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) {
if (addr < (xp->m_addr + xp->m_size))
addr = xp->m_addr + xp->m_size;
for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
if (addr < (xp->f_addr + xp->f_size))
addr = xp->f_addr + xp->f_size;
}
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;

View File

@ -203,19 +203,19 @@ bi_copyenv(vm_offset_t addr)
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct loaded_module *mp;
struct module_metadata *md;
struct preloaded_file *fp;
struct file_metadata *md;
/* start with the first module on the list, should be the kernel */
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
MOD_NAME(addr, mp->m_name); /* this field must come first */
MOD_TYPE(addr, mp->m_type);
if (mp->m_args)
MOD_ARGS(addr, mp->m_args);
MOD_ADDR(addr, mp->m_addr);
MOD_SIZE(addr, mp->m_size);
for (md = mp->m_metadata; md != NULL; md = md->md_next)
MOD_NAME(addr, fp->f_name); /* this field must come first */
MOD_TYPE(addr, fp->f_type);
if (fp->f_args)
MOD_ARGS(addr, fp->f_args);
MOD_ADDR(addr, fp->f_addr);
MOD_SIZE(addr, fp->f_size);
for (md = fp->f_metadata; md != NULL; md = md->md_next)
if (!(md->md_type & MODINFOMD_NOCOPY))
MOD_METADATA(addr, md);
}
@ -235,7 +235,7 @@ bi_copymodules(vm_offset_t addr)
int
bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip)
{
struct loaded_module *xp;
struct preloaded_file *xp;
struct i386_devdesc *rootdev;
vm_offset_t addr, bootinfo_addr;
char *rootdevname;
@ -295,9 +295,9 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip)
/* find the last module in the chain */
addr = 0;
for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) {
if (addr < (xp->m_addr + xp->m_size))
addr = xp->m_addr + xp->m_size;
for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
if (addr < (xp->f_addr + xp->f_size))
addr = xp->f_addr + xp->f_size;
}
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;

View File

@ -39,9 +39,9 @@
#include "libi386.h"
#include "btxv86.h"
static int elf_exec(struct loaded_module *amp);
static int elf_exec(struct preloaded_file *amp);
struct module_format i386_elf = { elf_loadmodule, elf_exec };
struct file_format i386_elf = { elf_loadfile, elf_exec };
static struct bootinfo bi;
@ -51,27 +51,27 @@ static struct bootinfo bi;
* preparations as are required, and do so.
*/
static int
elf_exec(struct loaded_module *mp)
elf_exec(struct preloaded_file *fp)
{
struct module_metadata *md;
struct file_metadata *md;
Elf_Ehdr *ehdr;
vm_offset_t entry, bootinfop;
int boothowto, err, bootdev;
struct bootinfo *bi;
vm_offset_t ssym, esym;
if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE); /* XXX actually EFUCKUP */
ehdr = (Elf_Ehdr *)&(md->md_data);
if ((err = bi_load(mp->m_args, &boothowto, &bootdev, &bootinfop)) != 0)
if ((err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop)) != 0)
return(err);
entry = ehdr->e_entry & 0xffffff;
ssym = esym = 0;
if ((md = mod_findmetadata(mp, MODINFOMD_SSYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL)
ssym = *((vm_offset_t *)&(md->md_data));
if ((md = mod_findmetadata(mp, MODINFOMD_ESYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL)
esym = *((vm_offset_t *)&(md->md_data));
if (ssym == 0 || esym == 0)
ssym = esym = 0; /* sanity */

View File

@ -39,9 +39,9 @@
#include "libi386.h"
#include "btxv86.h"
static int elf_exec(struct loaded_module *amp);
static int elf_exec(struct preloaded_file *amp);
struct module_format i386_elf = { elf_loadmodule, elf_exec };
struct file_format i386_elf = { elf_loadfile, elf_exec };
static struct bootinfo bi;
@ -51,27 +51,27 @@ static struct bootinfo bi;
* preparations as are required, and do so.
*/
static int
elf_exec(struct loaded_module *mp)
elf_exec(struct preloaded_file *fp)
{
struct module_metadata *md;
struct file_metadata *md;
Elf_Ehdr *ehdr;
vm_offset_t entry, bootinfop;
int boothowto, err, bootdev;
struct bootinfo *bi;
vm_offset_t ssym, esym;
if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE); /* XXX actually EFUCKUP */
ehdr = (Elf_Ehdr *)&(md->md_data);
if ((err = bi_load(mp->m_args, &boothowto, &bootdev, &bootinfop)) != 0)
if ((err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop)) != 0)
return(err);
entry = ehdr->e_entry & 0xffffff;
ssym = esym = 0;
if ((md = mod_findmetadata(mp, MODINFOMD_SSYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL)
ssym = *((vm_offset_t *)&(md->md_data));
if ((md = mod_findmetadata(mp, MODINFOMD_ESYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL)
esym = *((vm_offset_t *)&(md->md_data));
if (ssym == 0 || esym == 0)
ssym = esym = 0; /* sanity */

View File

@ -39,9 +39,9 @@
#include "libi386.h"
#include "btxv86.h"
static int elf_exec(struct loaded_module *amp);
static int elf_exec(struct preloaded_file *amp);
struct module_format i386_elf = { elf_loadmodule, elf_exec };
struct file_format i386_elf = { elf_loadfile, elf_exec };
static struct bootinfo bi;
@ -51,27 +51,27 @@ static struct bootinfo bi;
* preparations as are required, and do so.
*/
static int
elf_exec(struct loaded_module *mp)
elf_exec(struct preloaded_file *fp)
{
struct module_metadata *md;
struct file_metadata *md;
Elf_Ehdr *ehdr;
vm_offset_t entry, bootinfop;
int boothowto, err, bootdev;
struct bootinfo *bi;
vm_offset_t ssym, esym;
if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE); /* XXX actually EFUCKUP */
ehdr = (Elf_Ehdr *)&(md->md_data);
if ((err = bi_load(mp->m_args, &boothowto, &bootdev, &bootinfop)) != 0)
if ((err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop)) != 0)
return(err);
entry = ehdr->e_entry & 0xffffff;
ssym = esym = 0;
if ((md = mod_findmetadata(mp, MODINFOMD_SSYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL)
ssym = *((vm_offset_t *)&(md->md_data));
if ((md = mod_findmetadata(mp, MODINFOMD_ESYM)) != NULL)
if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL)
esym = *((vm_offset_t *)&(md->md_data));
if (ssym == 0 || esym == 0)
ssym = esym = 0; /* sanity */

View File

@ -73,10 +73,10 @@ struct fs_ops *file_system[] = {
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct module_format i386_aout;
extern struct module_format i386_elf;
extern struct file_format i386_aout;
extern struct file_format i386_elf;
struct module_format *module_formats[] = {
struct file_format *file_formats[] = {
&i386_elf,
&i386_aout,
NULL

View File

@ -81,9 +81,9 @@ struct netif_driver *netif_drivers[] = {
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct module_format alpha_elf;
extern struct file_format alpha_elf;
struct module_format *module_formats[] = {
struct file_format *file_formats[] = {
&alpha_elf,
NULL
};

View File

@ -81,9 +81,9 @@ struct netif_driver *netif_drivers[] = {
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct module_format alpha_elf;
extern struct file_format alpha_elf;
struct module_format *module_formats[] = {
struct file_format *file_formats[] = {
&alpha_elf,
NULL
};