From fdcb9a92432ca2c9c9131fdc879c572c30c60b20 Mon Sep 17 00:00:00 2001 From: Bryce Lanham Date: Tue, 2 May 2023 20:09:36 -0500 Subject: [PATCH] multiboot2: fix 32 bit elf section loading Existing code was using 64 bit elf section header unconditionally. This commit fixes that :) --- common/lib/elf.c | 13 ----------- common/lib/elf.h | 13 +++++++++++ common/protos/multiboot2.c | 46 +++++++++++++++++++++++++++----------- 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/common/lib/elf.c b/common/lib/elf.c index ed0b63eb..b5f7e8f5 100644 --- a/common/lib/elf.c +++ b/common/lib/elf.c @@ -76,19 +76,6 @@ struct elf32_phdr { uint32_t p_align; }; -struct elf32_shdr { - uint32_t sh_name; - uint32_t sh_type; - uint32_t sh_flags; - uint32_t sh_addr; - uint32_t sh_offset; - uint32_t sh_size; - uint32_t sh_link; - uint32_t sh_info; - uint32_t sh_addralign; - uint32_t sh_entsize; -}; - struct elf64_rela { uint64_t r_addr; uint32_t r_info; diff --git a/common/lib/elf.h b/common/lib/elf.h index 98a7c9d1..e7df68c0 100644 --- a/common/lib/elf.h +++ b/common/lib/elf.h @@ -69,6 +69,19 @@ struct elf64_shdr { uint64_t sh_entsize; }; +struct elf32_shdr { + uint32_t sh_name; + uint32_t sh_type; + uint32_t sh_flags; + uint32_t sh_addr; + uint32_t sh_offset; + uint32_t sh_size; + uint32_t sh_link; + uint32_t sh_info; + uint32_t sh_addralign; + uint32_t sh_entsize; +}; + struct elf64_sym { uint32_t st_name; uint8_t st_info; diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c index 65f678c0..c3fc8c3d 100644 --- a/common/protos/multiboot2.c +++ b/common/protos/multiboot2.c @@ -376,22 +376,42 @@ noreturn void multiboot2_load(char *config, char* cmdline) { memcpy(tag->sections, kernel + section_hdr_info.section_offset, section_hdr_info.section_entry_size * section_hdr_info.num); + int bits = elf_bits(kernel); + for (size_t i = 0; i < section_hdr_info.num; i++) { - struct elf64_shdr *shdr = (void *)tag->sections + i * section_hdr_info.section_entry_size; + if (bits == 64) { + struct elf64_shdr *shdr = (void *)tag->sections + i * section_hdr_info.section_entry_size; - if (shdr->sh_addr != 0 || shdr->sh_size == 0) { - continue; + if (shdr->sh_addr != 0 || shdr->sh_size == 0) { + continue; + } + + uint64_t section = (uint64_t)-1; /* no target preference, use top */ + + if (!elsewhere_append(true /* flexible target */, + ranges, &ranges_count, + kernel + shdr->sh_offset, §ion, shdr->sh_size)) { + panic(true, "multiboot2: Cannot allocate elf sections"); + } + + shdr->sh_addr = section; + } else { + struct elf32_shdr *shdr = (void *)tag->sections + i * section_hdr_info.section_entry_size; + + if (shdr->sh_addr != 0 || shdr->sh_size == 0) { + continue; + } + + uint64_t section = (uint64_t)-1; /* no target preference, use top */ + + if (!elsewhere_append(true /* flexible target */, + ranges, &ranges_count, + kernel + shdr->sh_offset, §ion, shdr->sh_size)) { + panic(true, "multiboot2: Cannot allocate elf sections"); + } + + shdr->sh_addr = section; } - - uint64_t section = (uint64_t)-1; /* no target preference, use top */ - - if (!elsewhere_append(true /* flexible target */, - ranges, &ranges_count, - kernel + shdr->sh_offset, §ion, shdr->sh_size)) { - panic(true, "multiboot2: Cannot allocate elf sections"); - } - - shdr->sh_addr = section; } append_tag(info_idx, tag);