svn commit: r246613 - projects/uefi/sys/boot/common

Benno Rice benno at FreeBSD.org
Sun Feb 10 10:17:42 UTC 2013


Author: benno
Date: Sun Feb 10 10:17:41 2013
New Revision: 246613
URL: http://svnweb.freebsd.org/changeset/base/246613

Log:
  Make it possible to load 32-bit kernels/modules from a 64-bit loader.
  
  Sponsored by:	FreeBSD Foundation

Modified:
  projects/uefi/sys/boot/common/load_elf.c

Modified: projects/uefi/sys/boot/common/load_elf.c
==============================================================================
--- projects/uefi/sys/boot/common/load_elf.c	Sun Feb 10 10:17:33 2013	(r246612)
+++ projects/uefi/sys/boot/common/load_elf.c	Sun Feb 10 10:17:41 2013	(r246613)
@@ -50,6 +50,13 @@ __FBSDID("$FreeBSD$");
 #define ELF_TARG_MACH   EM_X86_64
 #endif
 
+#if defined(__amd64__) && __ELF_WORD_SIZE == 32
+#undef ELF_TARG_CLASS
+#undef ELF_TARG_MACH
+#define ELF_TARG_CLASS  ELFCLASS32
+#define ELF_TARG_MACH   EM_386
+#endif
+
 typedef struct elf_file {
     Elf_Phdr 	*ph;
     Elf_Ehdr	*ehdr;
@@ -595,6 +602,13 @@ struct mod_metadata64 {
 	u_int64_t	md_data;	/* specific data */
 	u_int64_t	md_cval;	/* common string label */
 };
+#elif defined(__amd64__) && __ELF_WORD_SIZE == 32
+struct mod_metadata32 {
+	int		md_version;	/* structure version MDTV_* */  
+	int		md_type;	/* type of entry MDT_* */
+	u_int32_t	md_data;	/* specific data */
+	u_int32_t	md_cval;	/* common string label */
+};
 #endif
 
 int
@@ -603,6 +617,8 @@ __elfN(parse_modmetadata)(struct preload
     struct mod_metadata md;
 #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64
     struct mod_metadata64 md64;
+#elif defined(__amd64__) && __ELF_WORD_SIZE == 32
+    struct mod_metadata32 md32;
 #endif
     struct mod_depend *mdepend;
     struct mod_version mver;
@@ -638,6 +654,18 @@ __elfN(parse_modmetadata)(struct preload
 	md.md_type = md64.md_type;
 	md.md_cval = (const char *)(uintptr_t)md64.md_cval;
 	md.md_data = (void *)(uintptr_t)md64.md_data;
+#elif defined(__amd64__) && __ELF_WORD_SIZE == 32
+	COPYOUT(v, &md32, sizeof(md32));
+	error = __elfN(reloc_ptr)(fp, ef, v, &md32, sizeof(md32));
+	if (error == EOPNOTSUPP) {
+	    md32.md_cval += ef->off;
+	    md32.md_data += ef->off;
+	} else if (error != 0)
+	    return (error);
+	md.md_version = md32.md_version;
+	md.md_type = md32.md_type;
+	md.md_cval = (const char *)(uintptr_t)md32.md_cval;
+	md.md_data = (void *)(uintptr_t)md32.md_data;
 #else
 	COPYOUT(v, &md, sizeof(md));
 	error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md));


More information about the svn-src-projects mailing list