boot/loader: relocate kernel to virtual address space on 32-bit architectures

Change-Id: Ic86ca6874f358df8755a0c691cccb155d145e06c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4675
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
This commit is contained in:
David Karoly 2021-12-19 12:17:58 +01:00 committed by Adrien Destugues
parent abef198c1a
commit 6117e0c29c
4 changed files with 43 additions and 3 deletions

View File

@ -90,6 +90,9 @@ extern status_t boot_elf_resolve_symbol(preloaded_elf32_image* image,
Elf32_Sym* symbol, Elf32_Addr* symbolAddress);
extern status_t boot_elf_resolve_symbol(preloaded_elf64_image* image,
Elf64_Sym* symbol, Elf64_Addr* symbolAddress);
extern Elf32_Addr boot_elf32_get_relocation(Elf32_Addr resolveAddress);
extern void boot_elf32_set_relocation(Elf32_Addr resolveAddress,
Elf32_Addr finalAddress);
extern void boot_elf64_set_relocation(Elf64_Addr resolveAddress,
Elf64_Addr finalAddress);
#endif

View File

@ -86,13 +86,24 @@ struct ELF32Class {
return status;
*_mappedAddress = (void*)*_address;
addr_t res;
platform_bootloader_address_to_kernel_address((void*)*_address, &res);
*_address = res;
return B_OK;
}
static inline void*
Map(AddrType address)
{
return (void*)address;
void *result = NULL;
if (platform_kernel_address_to_bootloader_address(address, &result) != B_OK) {
panic("Couldn't convert address 0x%08x", (uint32_t)address);
}
return result;
}
};
@ -742,6 +753,20 @@ boot_elf_resolve_symbol(preloaded_elf32_image* image, Elf32_Sym* symbol,
{
return ELF32Loader::Resolve(image, symbol, symbolAddress);
}
Elf32_Addr
boot_elf32_get_relocation(Elf32_Addr resolveAddress)
{
Elf32_Addr* src = (Elf32_Addr*)ELF32Class::Map(resolveAddress);
return *src;
}
void
boot_elf32_set_relocation(Elf32_Addr resolveAddress, Elf32_Addr finalAddress)
{
Elf32_Addr* dest = (Elf32_Addr*)ELF32Class::Map(resolveAddress);
*dest = finalAddress;
}
#endif

View File

@ -220,7 +220,11 @@ arch_elf_relocate_rel(struct elf_image_info *image,
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_ARM_ABS32:
case R_ARM_RELATIVE:
#ifndef _BOOT_MODE
A = *(addr_t *)(image->text_region.delta + rel[i].r_offset);
#else
A = boot_elf32_get_relocation(image->text_region.delta + rel[i].r_offset);
#endif
TRACE(("A %p\n", (void *)A));
break;
}
@ -252,8 +256,10 @@ arch_elf_relocate_rel(struct elf_image_info *image,
rel[i].r_offset);
return B_BAD_ADDRESS;
}
#endif
*resolveAddress = finalAddress;
#else
boot_elf32_set_relocation((Elf32_Addr)resolveAddress, finalAddress);
#endif
TRACE(("-> offset %#lx = %#lx\n",
(image->text_region.delta + rel[i].r_offset), finalAddress));
}

View File

@ -113,7 +113,11 @@ arch_elf_relocate_rel(struct elf_image_info *image,
case R_386_RELATIVE:
case R_386_GOTOFF:
case R_386_GOTPC:
#ifndef _BOOT_MODE
A = *(uint32 *)(image->text_region.delta + rel[i].r_offset);
#else
A = boot_elf32_get_relocation(image->text_region.delta + rel[i].r_offset);
#endif
TRACE(("A %p\n", (void *)A));
break;
}
@ -159,8 +163,10 @@ arch_elf_relocate_rel(struct elf_image_info *image,
rel[i].r_offset);
return B_BAD_ADDRESS;
}
#endif
*resolveAddress = finalAddress;
#else
boot_elf32_set_relocation((Elf32_Addr)resolveAddress, finalAddress);
#endif
TRACE(("-> offset %#lx (%#lx) = %#lx\n",
(image->text_region.delta + rel[i].r_offset), rel[i].r_offset, finalAddress));
}