diff --git a/multiboot.c b/multiboot.c index 02744e8..3b79e3c 100644 --- a/multiboot.c +++ b/multiboot.c @@ -40,8 +40,6 @@ #include -void *entry = NULL; - uint32_t multiboot_info_set_meminfo(struct multiboot_info* info, uint32_t mem_lower, uint32_t mem_upper) @@ -223,8 +221,7 @@ mb_scan(void *kernel, size_t kernsz) } enum LOAD_TYPE -multiboot_load_type (void* kernel, size_t kernsz, Elf **kernel_elf, - struct multiboot *mb) +multiboot_load_type (void* kernel, size_t kernsz, struct multiboot *mb) { struct multiboot_header *mbh = mb->header.mb.header; @@ -235,12 +232,12 @@ multiboot_load_type (void* kernel, size_t kernsz, Elf **kernel_elf, } /* Check if the file is an ELF */ - if (((*kernel_elf = elf_memory(kernel, kernsz)) == NULL) - || (elf_kind(*kernel_elf) != ELF_K_ELF)) + if (((mb->kernel_elf = elf_memory(kernel, kernsz)) == NULL) + || (elf_kind(mb->kernel_elf) != ELF_K_ELF)) { /* Not an ELF. Try loading it as an a.out. */ - elf_end(*kernel_elf); - *kernel_elf = NULL; + elf_end(mb->kernel_elf); + mb->kernel_elf = NULL; return LOAD_AOUT; } @@ -344,26 +341,26 @@ multiboot_load_aout(void* kernel, size_t kernsz, struct multiboot *mb) */ } - entry = (void*) (uintptr_t) mbh->entry_addr; + mb->entry = (void*) (uintptr_t) mbh->entry_addr; return 0; } uint32_t -multiboot_load_elf(void *kernel, size_t kernsz, Elf *kernel_elf) { +multiboot_load_elf(void *kernel, size_t kernsz, struct multiboot *mb) { size_t elf_phnum = 0; int elf_phidx = 0; GElf_Ehdr elf_ehdr; GElf_Phdr elf_phdr; /* Get the elf Ehdr */ - if (!gelf_getehdr(kernel_elf, &elf_ehdr)) { + if (!gelf_getehdr(mb->kernel_elf, &elf_ehdr)) { ERROR(EINVAL, "Could not get number of ELF headers"); return EINVAL; } /* Get the number of ELF program headers. */ - if (!elf_getphnum(kernel_elf, &elf_phnum)) { + if (!elf_getphnum(mb->kernel_elf, &elf_phnum)) { ERROR(EINVAL, "Could not get number of ELF program headers."); return EINVAL; } @@ -382,7 +379,7 @@ multiboot_load_elf(void *kernel, size_t kernsz, Elf *kernel_elf) { } for (elf_phidx = 0; elf_phidx < elf_phnum; elf_phidx++) { - gelf_getphdr(kernel_elf, elf_phidx, &elf_phdr); + gelf_getphdr(mb->kernel_elf, elf_phidx, &elf_phdr); if (elf_phdr.p_type != PT_LOAD) continue; @@ -439,25 +436,24 @@ multiboot_load_elf(void *kernel, size_t kernsz, Elf *kernel_elf) { */ } - entry = (void*) elf_ehdr.e_entry; + mb->entry = (void*) elf_ehdr.e_entry; return 0; } uint32_t multiboot_load(void* kernel, size_t kernsz, struct multiboot *mb) { - Elf *kernel_elf = NULL; uint32_t error = 0; - switch (multiboot_load_type(kernel, kernsz, &kernel_elf, mb)) { + switch (multiboot_load_type(kernel, kernsz, mb)) { case LOAD_AOUT: error = multiboot_load_aout(kernel, kernsz, mb); return error; case LOAD_ELF: - error = multiboot_load_elf(kernel, kernsz, kernel_elf); - if (kernel_elf) - elf_end(kernel_elf); + error = multiboot_load_elf(kernel, kernsz, mb); + if (mb->kernel_elf) + elf_end(mb->kernel_elf); return error; } } diff --git a/multiboot.h b/multiboot.h index d7eff02..b573d33 100644 --- a/multiboot.h +++ b/multiboot.h @@ -32,7 +32,7 @@ #include #define MULTIBOOT1_MAGIC 0x1BADB002 -#define MULTIBOOT1_BOOTLOADER_MAGICC 0x2BADB002 +#define MULTIBOOT1_BOOTLOADER_MAGIC 0x2BADB002 #define MULTIBOOT2_MAGIC 0xE85250D6 #define MULTIBOOT_AOUT_KLUDGE (1<<16) @@ -174,6 +174,8 @@ struct multiboot { struct multiboot2_header* header; } mb2; } header; + void* entry; + Elf *kernel_elf; struct multiboot_info info; }; @@ -194,14 +196,11 @@ struct multiboot* mb_scan(void *kernel, size_t kernsz); * * @param kernel pointer to the kernel * @param kernsz size of the kernel - * @param kernel_elf pointer to the ELF object to initialize if loading as an - * ELF. * @param mb pointer to the multiboot context * @return enum LOAD_TYPE */ enum LOAD_TYPE -multiboot_load_type (void* kernel, size_t kernsz, Elf **kernel_elf, - struct multiboot *mb); +multiboot_load_type (void* kernel, size_t kernsz, struct multiboot *mb); /** * @brief Attempt to load a file as an a.out object. @@ -219,11 +218,11 @@ multiboot_load_aout(void* kernel, size_t kernsz, struct multiboot *mb); * * @param kernel pointer to the kernel * @param kernsz size of the kernel - * @param kernel_elf kernel ELF object + * @param mb pointer to the multiboot context * @return uint32_t 0 on success, error code on failure. */ uint32_t -multiboot_load_elf(void *kernel, size_t kernsz, Elf *kernel_elf); +multiboot_load_elf(void *kernel, size_t kernsz, struct multiboot *mb); /** * @brief Load a kernel into guest memory. diff --git a/tests/test-multiboot.c b/tests/test-multiboot.c index cc36a82..cf50f4c 100644 --- a/tests/test-multiboot.c +++ b/tests/test-multiboot.c @@ -158,16 +158,15 @@ ATF_TC_BODY(loadtype, tc) void *kernel = MB_TESTDATA_START(mmap); size_t kernsz = MB_TESTDATA_SIZE(mmap); enum LOAD_TYPE type; - Elf *kernelf; mb = mb_scan(kernel, kernsz); - type = multiboot_load_type(kernel, kernsz, &kernelf, mb); + type = multiboot_load_type(kernel, kernsz, mb); ATF_CHECK_EQ_MSG(type, LOAD_ELF, "mmap test kernel not loaded as ELF"); ATF_CHECK(urandom = fopen("/dev/urandom", "r")); ATF_CHECK_MSG(random_buffer = malloc(128*kiB), "could not allocate memory"); - elf_end(kernelf); + elf_end(mb->kernel_elf); /* Craft a valid multiboot header */ ATF_CHECK(fread(random_buffer, 128*kiB, 1, urandom)); @@ -179,11 +178,9 @@ ATF_TC_BODY(loadtype, tc) ATF_CHECK_EQ_MSG(mb->header.mb.header, mbh, "did not find crafted valid header"); mbh = NULL; - type = multiboot_load_type(random_buffer, 128*kiB, - &kernelf, mb); + type = multiboot_load_type(random_buffer, 128*kiB, mb); ATF_CHECK_EQ_MSG(type, LOAD_AOUT, "random test data not loaded as a.out kludge"); - ATF_CHECK_EQ_MSG(NULL, kernelf, "ELF resources not freed"); free(random_buffer); fclose(urandom); @@ -293,7 +290,6 @@ ATF_TC_BODY(load_elf_direct, tc) size_t highmem = 0; void *kernel = MB_TESTDATA_START(mmap); size_t kernsz = MB_TESTDATA_SIZE(mmap); - Elf *kernelf; setmem(4*MiB, 0); callbacks->getmem(callbacks_arg, &lowmem, &highmem); @@ -301,11 +297,11 @@ ATF_TC_BODY(load_elf_direct, tc) mb = mb_scan(kernel, kernsz); mbh = mb->header.mb.header; - multiboot_load_type(kernel, kernsz, &kernelf, mb); - error = multiboot_load_elf(kernel, kernsz, kernelf); + multiboot_load_type(kernel, kernsz, mb); + error = multiboot_load_elf(kernel, kernsz, mb); ATF_CHECK_EQ_MSG(0, error, "multiboot_load_elf failed"); - elf_end(kernelf); + elf_end(mb->kernel_elf); } ATF_TC(load_elf);