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:
parent
f1711d4db1
commit
93440aad9b
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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]");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user