summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2003-05-12 05:48:09 +0000
committerpeter <peter@FreeBSD.org>2003-05-12 05:48:09 +0000
commitf6f3e2ff8f29ef1c2290bd3aa8eb455ba2c2bee2 (patch)
tree6b5006a3e0586b5ed7773ab55173193fe69c55c7 /sys/boot
parent57b595dfe174133fadf03c52f8c0f38f7dc83fd4 (diff)
downloadFreeBSD-src-f6f3e2ff8f29ef1c2290bd3aa8eb455ba2c2bee2.zip
FreeBSD-src-f6f3e2ff8f29ef1c2290bd3aa8eb455ba2c2bee2.tar.gz
Fix lookup of module metadata on amd64 systems. While this is in
common code, the non-trivial part is #ifdef'ed and only executes when loading amd64 kernels. The rest is trivial but needed for the the amd64 case. (Two variables changed from char ** to Elf_Addr). Approved by: re (amd64 "low-risk" stuff)
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/common/load_elf.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c
index b28abb8..31d5d59 100644
--- a/sys/boot/common/load_elf.c
+++ b/sys/boot/common/load_elf.c
@@ -568,23 +568,35 @@ fake_modname(const char *name)
return fp;
}
+#if defined(__i386__) && __ELF_WORD_SIZE == 64
+struct mod_metadata64 {
+ int md_version; /* structure version MDTV_* */
+ int md_type; /* type of entry MDT_* */
+ u_int64_t md_data; /* specific data */
+ u_int64_t md_cval; /* common string label */
+};
+#endif
+
int
__elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef)
{
struct mod_metadata md;
+#if defined(__i386__) && __ELF_WORD_SIZE == 64
+ struct mod_metadata64 md64;
+#endif
struct mod_depend *mdepend;
struct mod_version mver;
Elf_Sym sym;
- char *s, **p, **p_stop;
+ char *s;
int modcnt, minfolen;
- Elf_Addr v;
+ Elf_Addr v, p, p_stop;
if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", &sym) != 0)
return ENOENT;
- p = (char **)(uintptr_t)(sym.st_value + ef->off);
+ p = sym.st_value + ef->off;
if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", &sym) != 0)
return ENOENT;
- p_stop = (char **)(uintptr_t)(sym.st_value + ef->off);
+ p_stop = sym.st_value + ef->off;
modcnt = 0;
while (p < p_stop) {
@@ -594,6 +606,13 @@ __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef)
#else
v += ef->off;
#endif
+#if defined(__i386__) && __ELF_WORD_SIZE == 64
+ COPYOUT(v, &md64, sizeof(md64));
+ md.md_version = md64.md_version;
+ md.md_type = md64.md_type;
+ md.md_cval = (const char *)(uintptr_t)(md64.md_cval + ef->off);
+ md.md_data = (void *)(uintptr_t)(md64.md_data + ef->off);
+#else
COPYOUT(v, &md, sizeof(md));
#ifdef __sparc64__
__elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md));
@@ -601,7 +620,8 @@ __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef)
md.md_cval += ef->off;
md.md_data += ef->off;
#endif
- p++;
+#endif
+ p += sizeof(Elf_Addr);
switch(md.md_type) {
case MDT_DEPEND:
if (ef->kernel) /* kernel must not depend on anything */
OpenPOWER on IntegriCloud