multiboot2: fix 32 bit elf section loading
Existing code was using 64 bit elf section header unconditionally. This commit fixes that :)
This commit is contained in:
parent
1a4888858b
commit
fdcb9a9243
|
@ -76,19 +76,6 @@ struct elf32_phdr {
|
||||||
uint32_t p_align;
|
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 {
|
struct elf64_rela {
|
||||||
uint64_t r_addr;
|
uint64_t r_addr;
|
||||||
uint32_t r_info;
|
uint32_t r_info;
|
||||||
|
|
|
@ -69,6 +69,19 @@ struct elf64_shdr {
|
||||||
uint64_t sh_entsize;
|
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 {
|
struct elf64_sym {
|
||||||
uint32_t st_name;
|
uint32_t st_name;
|
||||||
uint8_t st_info;
|
uint8_t st_info;
|
||||||
|
|
|
@ -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);
|
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++) {
|
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) {
|
if (shdr->sh_addr != 0 || shdr->sh_size == 0) {
|
||||||
continue;
|
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);
|
append_tag(info_idx, tag);
|
||||||
|
|
Loading…
Reference in New Issue