The binary may expose its type using the load type header tag. Implement it according to the specification.
Signed-off-by: Ross Lagerwall <ross.lagerw...@citrix.com> --- grub-core/loader/multiboot_mbi2.c | 45 ++++++++++++++++++++++++++++--- include/grub/multiboot2.h | 1 + include/multiboot2.h | 13 +++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index 00a48413c013..6ef4f265070a 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -119,10 +119,12 @@ grub_multiboot2_load (grub_file_t file, const char *filename) grub_uint32_t console_required = 0; struct multiboot_header_tag_framebuffer *fbtag = NULL; int accepted_consoles = GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT; + struct multiboot_header_tag_load_type *load_type_tag; mbi_load_data_t mld; mld.mbi_ver = 2; mld.relocatable = 0; + mld.load_type = MULTIBOOT_LOAD_TYPE_TOTAL; mld.buffer = grub_malloc (MULTIBOOT_SEARCH); if (!mld.buffer) @@ -258,6 +260,17 @@ grub_multiboot2_load (grub_file_t file, const char *filename) #endif break; + case MULTIBOOT_HEADER_TAG_LOAD_TYPE: + load_type_tag = (struct multiboot_header_tag_load_type *) tag; + mld.load_type = load_type_tag->load_type; + if (mld.load_type >= MULTIBOOT_LOAD_TYPE_TOTAL) + { + grub_free (mld.buffer); + return grub_error (GRUB_ERR_UNKNOWN_OS, + "unsupported load type: %u", load_type_tag->load_type); + } + break; + default: if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL)) { @@ -268,14 +281,32 @@ grub_multiboot2_load (grub_file_t file, const char *filename) break; } - if (addr_tag && !entry_specified && !(keep_bs && efi_entry_specified)) + if (mld.load_type == MULTIBOOT_LOAD_TYPE_ADDRESS && !addr_tag) + { + grub_free (mld.buffer); + return grub_error (GRUB_ERR_UNKNOWN_OS, + "load type address without address tag"); + } + if (mld.load_type < MULTIBOOT_LOAD_TYPE_TOTAL && + mld.load_type != MULTIBOOT_LOAD_TYPE_ADDRESS && addr_tag) + { + grub_free (mld.buffer); + return grub_error (GRUB_ERR_UNKNOWN_OS, + "address tag specified but load type doesn't match"); + } + if (mld.load_type == MULTIBOOT_LOAD_TYPE_TOTAL) + mld.load_type = addr_tag ? MULTIBOOT_LOAD_TYPE_ADDRESS : MULTIBOOT_LOAD_TYPE_ELF; + + if (mld.load_type == MULTIBOOT_LOAD_TYPE_ADDRESS && !entry_specified && + !(keep_bs && efi_entry_specified)) { grub_free (mld.buffer); return grub_error (GRUB_ERR_UNKNOWN_OS, "load address tag without entry address tag"); } - if (addr_tag) + switch (mld.load_type) { + case MULTIBOOT_LOAD_TYPE_ADDRESS: { grub_uint64_t load_addr = (addr_tag->load_addr + 1) ? addr_tag->load_addr : (addr_tag->header_addr @@ -343,8 +374,9 @@ grub_multiboot2_load (grub_file_t file, const char *filename) if (addr_tag->bss_end_addr) grub_memset ((grub_uint8_t *) source + load_size, 0, addr_tag->bss_end_addr - load_addr - load_size); + break; } - else + case MULTIBOOT_LOAD_TYPE_ELF: { mld.file = file; mld.filename = filename; @@ -355,7 +387,14 @@ grub_multiboot2_load (grub_file_t file, const char *filename) grub_free (mld.buffer); return err; } + break; } + case MULTIBOOT_LOAD_TYPE_PE: + grub_fatal ("Unsupported load type: %u\n", mld.load_type); + default: + /* should be impossible */ + grub_fatal ("Unknown load type: %u\n", mld.load_type); + } load_base_addr = mld.load_base_addr; diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h index b90aa6989674..1f6d4fc9e336 100644 --- a/include/grub/multiboot2.h +++ b/include/grub/multiboot2.h @@ -89,6 +89,7 @@ struct mbi_load_data grub_uint32_t link_base_addr; grub_uint32_t load_base_addr; int avoid_efi_boot_services; + grub_uint32_t load_type; }; typedef struct mbi_load_data mbi_load_data_t; diff --git a/include/multiboot2.h b/include/multiboot2.h index a039aa0439aa..f4377bf7b394 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -74,6 +74,7 @@ #define MULTIBOOT_HEADER_TAG_EFI_BS 7 #define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 #define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 +#define MULTIBOOT_HEADER_TAG_LOAD_TYPE 11 #define MULTIBOOT2_ARCHITECTURE_I386 0 #define MULTIBOOT2_ARCHITECTURE_MIPS32 4 @@ -178,6 +179,18 @@ struct multiboot_header_tag_relocatable multiboot_uint32_t preference; }; +struct multiboot_header_tag_load_type +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +#define MULTIBOOT_LOAD_TYPE_ADDRESS 0 +#define MULTIBOOT_LOAD_TYPE_ELF 1 +#define MULTIBOOT_LOAD_TYPE_PE 2 +#define MULTIBOOT_LOAD_TYPE_TOTAL 3 + multiboot_uint32_t load_type; +}; + struct multiboot_color { multiboot_uint8_t red; -- 2.43.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel