diff --git a/kern/elf.c b/kern/elf.c index 3e90ea0..f4a71c1 100644 --- a/kern/elf.c +++ b/kern/elf.c @@ -85,9 +85,8 @@ grub_elf_file (grub_file_t file) return elf; fail: - grub_error_push (); - grub_elf_close (elf); - grub_error_pop (); + grub_free (elf->phdrs); + grub_free (elf); return 0; } @@ -177,8 +176,8 @@ grub_elf32_size (grub_elf_t elf) /* Run through the program headers to calculate the total memory size we * should claim. */ - auto int calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg); - int calcsize (grub_elf_t UNUSED _elf, Elf32_Phdr *phdr, void UNUSED *_arg) + auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg); + int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf32_Phdr *phdr, void UNUSED *_arg) { /* Only consider loadable segments. */ if (phdr->p_type != PT_LOAD) @@ -355,8 +354,8 @@ grub_elf64_size (grub_elf_t elf) /* Run through the program headers to calculate the total memory size we * should claim. */ - auto int calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg); - int calcsize (grub_elf_t UNUSED _elf, Elf64_Phdr *phdr, void UNUSED *_arg) + auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg); + int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf64_Phdr *phdr, void UNUSED *_arg) { /* Only consider loadable segments. */ if (phdr->p_type != PT_LOAD) diff --git a/kern/i386/loader.S b/kern/i386/loader.S index baf1255..39cf6a0 100644 --- a/kern/i386/loader.S +++ b/kern/i386/loader.S @@ -181,6 +181,8 @@ FUNCTION(grub_unix_real_boot) /* Fetch `entry' address ... */ popl %eax - /* ... and put our return address in its place (the kernel will ignore - it, but it expects %esp to point to it. */ + /* + * ... and put our return address in its place. The kernel will + * ignore it, but it expects %esp to point to it. + */ call *%eax diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 2bc737e..4966afa 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -400,17 +400,24 @@ grub_bsd_unload (void) } static grub_err_t -grub_bsd_load_aout (grub_file_t file, union grub_aout_header *ah) +grub_bsd_load_aout (grub_file_t file) { grub_addr_t load_addr, bss_end_addr; int ofs, align_page; + union grub_aout_header ah; + + if ((grub_file_seek (file, 0)) == (grub_off_t) - 1) + return grub_errno; - if (grub_aout_get_type (ah) != AOUT_TYPE_AOUT32) + if (grub_file_read (file, (char *) &ah, sizeof (ah)) != sizeof (ah)) + return grub_error (GRUB_ERR_READ_ERROR, "cannot read the a.out header"); + + if (grub_aout_get_type (&ah) != AOUT_TYPE_AOUT32) return grub_error (GRUB_ERR_BAD_OS, "invalid a.out header"); - entry = ah->aout32.a_entry & 0xFFFFFF; + entry = ah.aout32.a_entry & 0xFFFFFF; - if (AOUT_GETMAGIC (ah->aout32) == AOUT32_ZMAGIC) + if (AOUT_GETMAGIC (ah.aout32) == AOUT32_ZMAGIC) { load_addr = entry; ofs = 0x1000; @@ -427,13 +434,13 @@ grub_bsd_load_aout (grub_file_t file, union grub_aout_header *ah) return grub_error (GRUB_ERR_BAD_OS, "load address below 1M"); kern_start = load_addr; - kern_end = load_addr + ah->aout32.a_text + ah->aout32.a_data; + kern_end = load_addr + ah.aout32.a_text + ah.aout32.a_data; if (align_page) kern_end = ALIGN_PAGE (kern_end); - if (ah->aout32.a_bss) + if (ah.aout32.a_bss) { - kern_end += ah->aout32.a_bss; + kern_end += ah.aout32.a_bss; if (align_page) kern_end = ALIGN_PAGE (kern_end); @@ -443,7 +450,7 @@ grub_bsd_load_aout (grub_file_t file, union grub_aout_header *ah) bss_end_addr = 0; return grub_aout_load (file, ofs, load_addr, - ah->aout32.a_text + ah->aout32.a_data, bss_end_addr); + ah.aout32.a_text + ah.aout32.a_data, bss_end_addr); } static grub_err_t @@ -469,32 +476,24 @@ grub_bsd_elf32_hook (Elf32_Phdr * phdr, UNUSED grub_addr_t * addr) } static grub_err_t -grub_bsd_load_elf (grub_file_t file) +grub_bsd_load_elf (grub_elf_t elf) { - grub_elf_t elf = 0; - grub_err_t err; - kern_start = kern_end = 0; - elf = grub_elf_file (file); - if (!elf) - return grub_errno; if (grub_elf_is_elf32 (elf)) { entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF; - err = grub_elf32_load (elf, grub_bsd_elf32_hook, 0, 0); + return grub_elf32_load (elf, grub_bsd_elf32_hook, 0, 0); } else - err = grub_error (GRUB_ERR_BAD_OS, "invalid elf"); - - return err; + return grub_error (GRUB_ERR_BAD_OS, "invalid elf"); } static grub_err_t grub_bsd_load (int argc, char *argv[]) { - grub_file_t file = 0; - union grub_aout_header ah; + grub_file_t file; + grub_elf_t elf; grub_dl_ref (my_mod); @@ -510,23 +509,23 @@ grub_bsd_load (int argc, char *argv[]) if (!file) goto fail; - if (grub_file_read (file, (char *) &ah, sizeof (ah)) != sizeof (ah)) + elf = grub_elf_file (file); + if (elf) { - grub_error (GRUB_ERR_READ_ERROR, "cannot read the a.out header"); - goto fail; + is_elf_kernel = 1; + grub_bsd_load_elf (elf); + grub_elf_close (elf); } - - is_elf_kernel = (grub_aout_get_type (&ah) == AOUT_TYPE_NONE); - if (is_elf_kernel) - grub_bsd_load_elf (file); else - grub_bsd_load_aout (file, &ah); + { + is_elf_kernel = 0; + grub_errno = 0; + grub_bsd_load_aout (file); + grub_file_close (file); + } fail: - if (file) - grub_file_close (file); - if (grub_errno != GRUB_ERR_NONE) grub_dl_unref (my_mod); diff --git a/loader/multiboot2.c b/loader/multiboot2.c index 65fdea1..42c6fad 100644 --- a/loader/multiboot2.c +++ b/loader/multiboot2.c @@ -371,6 +371,7 @@ grub_multiboot2 (int argc, char *argv[]) } else { + grub_errno = 0; grub_dprintf ("loader", "Loading non-ELF multiboot 2 file.\n"); if (header)