summaryrefslogtreecommitdiffstats
path: root/sys/boot/common/load_elf.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2001-09-11 01:09:24 +0000
committerpeter <peter@FreeBSD.org>2001-09-11 01:09:24 +0000
commit808991de7cecc9e774ffe5031e29362207e75564 (patch)
tree7b0e7fbc20bd6b09f4224a1d0187a77c9f747184 /sys/boot/common/load_elf.c
parentf07a058a30186a596af1595909ea89573a1a794f (diff)
downloadFreeBSD-src-808991de7cecc9e774ffe5031e29362207e75564.zip
FreeBSD-src-808991de7cecc9e774ffe5031e29362207e75564.tar.gz
Implement the long-awaited module->file cache database. A userland
tool (kldxref(8)) keeps a cache of what modules and versions are inside what .ko files. I have tested this on both Alpha and i386. Submitted by: bp
Diffstat (limited to 'sys/boot/common/load_elf.c')
-rw-r--r--sys/boot/common/load_elf.c40
1 files changed, 16 insertions, 24 deletions
diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c
index 0eddbb4..22f7ff7 100644
--- a/sys/boot/common/load_elf.c
+++ b/sys/boot/common/load_elf.c
@@ -83,7 +83,6 @@ elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result)
Elf_Ehdr *ehdr;
int err;
u_int pad;
- char *s;
ssize_t bytes_read;
fp = NULL;
@@ -183,11 +182,7 @@ elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result)
}
if (ef.kernel)
setenv("kernelname", filename, 1);
- s = strrchr(filename, '/');
- if (s)
- fp->f_name = strdup(s + 1);
- else
- fp->f_name = strdup(filename);
+ fp->f_name = strdup(filename);
fp->f_type = strdup(ef.kernel ? elf_kerneltype : elf_moduletype);
#ifdef ELF_VERBOSE
@@ -242,7 +237,6 @@ elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off)
vm_offset_t ssym, esym;
Elf_Dyn *dp;
int ndp;
- char *s;
int symstrindex;
int symtabindex;
long size;
@@ -515,19 +509,6 @@ nosyms:
if (ef->kernel) /* kernel must not depend on anything */
goto out;
- for (i = 0; i < ndp; i++) {
- 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 > ef->strsz - 2)
- continue;
- s = strdupout((vm_offset_t)&ef->strtab[j]);
- file_addmetadata(fp, MODINFOMD_DEPLIST, strlen(s) + 1, s);
- free(s);
- }
-
out:
if (dp)
free(dp);
@@ -537,6 +518,7 @@ out:
}
static char invalid_name[] = "bad";
+
char *
fake_modname(const char *name)
{
@@ -570,9 +552,11 @@ int
elf_parse_modmetadata(struct preloaded_file *fp, elf_file_t ef)
{
struct mod_metadata md;
+ struct mod_depend *mdepend;
+ struct mod_version mver;
Elf_Sym sym;
char *s, *v, **p, **p_stop;
- int modcnt;
+ int modcnt, minfolen;
if (elf_lookup_symbol(fp, ef, "__start_set_modmetadata_set", &sym) != 0)
return ENOENT;
@@ -590,12 +574,20 @@ elf_parse_modmetadata(struct preloaded_file *fp, elf_file_t ef)
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);
+ minfolen = sizeof(*mdepend) + strlen(s) + 1;
+ mdepend = malloc(minfolen);
+ if (mdepend == NULL)
+ return ENOMEM;
+ COPYOUT((vm_offset_t)(md.md_data + ef->off), mdepend, sizeof(*mdepend));
+ strcpy((char*)(mdepend + 1), s);
free(s);
+ file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, mdepend);
+ free(mdepend);
break;
case MDT_VERSION:
s = strdupout((vm_offset_t)(md.md_cval + ef->off));
- file_addmodule(fp, s, NULL);
+ COPYOUT((vm_offset_t)(md.md_data + ef->off), &mver, sizeof(mver));
+ file_addmodule(fp, s, mver.mv_version, NULL);
free(s);
modcnt++;
break;
@@ -603,7 +595,7 @@ elf_parse_modmetadata(struct preloaded_file *fp, elf_file_t ef)
}
if (modcnt == 0) {
s = fake_modname(fp->f_name);
- file_addmodule(fp, s, NULL);
+ file_addmodule(fp, s, 1, NULL);
free(s);
}
return 0;
OpenPOWER on IntegriCloud