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:
parent
abef198c1a
commit
6117e0c29c
@ -90,6 +90,9 @@ extern status_t boot_elf_resolve_symbol(preloaded_elf32_image* image,
|
|||||||
Elf32_Sym* symbol, Elf32_Addr* symbolAddress);
|
Elf32_Sym* symbol, Elf32_Addr* symbolAddress);
|
||||||
extern status_t boot_elf_resolve_symbol(preloaded_elf64_image* image,
|
extern status_t boot_elf_resolve_symbol(preloaded_elf64_image* image,
|
||||||
Elf64_Sym* symbol, Elf64_Addr* symbolAddress);
|
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,
|
extern void boot_elf64_set_relocation(Elf64_Addr resolveAddress,
|
||||||
Elf64_Addr finalAddress);
|
Elf64_Addr finalAddress);
|
||||||
#endif
|
#endif
|
||||||
|
@ -86,13 +86,24 @@ struct ELF32Class {
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
*_mappedAddress = (void*)*_address;
|
*_mappedAddress = (void*)*_address;
|
||||||
|
|
||||||
|
addr_t res;
|
||||||
|
platform_bootloader_address_to_kernel_address((void*)*_address, &res);
|
||||||
|
|
||||||
|
*_address = res;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void*
|
static inline void*
|
||||||
Map(AddrType address)
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,7 +220,11 @@ arch_elf_relocate_rel(struct elf_image_info *image,
|
|||||||
switch (ELF32_R_TYPE(rel[i].r_info)) {
|
switch (ELF32_R_TYPE(rel[i].r_info)) {
|
||||||
case R_ARM_ABS32:
|
case R_ARM_ABS32:
|
||||||
case R_ARM_RELATIVE:
|
case R_ARM_RELATIVE:
|
||||||
|
#ifndef _BOOT_MODE
|
||||||
A = *(addr_t *)(image->text_region.delta + rel[i].r_offset);
|
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));
|
TRACE(("A %p\n", (void *)A));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -252,8 +256,10 @@ arch_elf_relocate_rel(struct elf_image_info *image,
|
|||||||
rel[i].r_offset);
|
rel[i].r_offset);
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
*resolveAddress = finalAddress;
|
*resolveAddress = finalAddress;
|
||||||
|
#else
|
||||||
|
boot_elf32_set_relocation((Elf32_Addr)resolveAddress, finalAddress);
|
||||||
|
#endif
|
||||||
TRACE(("-> offset %#lx = %#lx\n",
|
TRACE(("-> offset %#lx = %#lx\n",
|
||||||
(image->text_region.delta + rel[i].r_offset), finalAddress));
|
(image->text_region.delta + rel[i].r_offset), finalAddress));
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,11 @@ arch_elf_relocate_rel(struct elf_image_info *image,
|
|||||||
case R_386_RELATIVE:
|
case R_386_RELATIVE:
|
||||||
case R_386_GOTOFF:
|
case R_386_GOTOFF:
|
||||||
case R_386_GOTPC:
|
case R_386_GOTPC:
|
||||||
|
#ifndef _BOOT_MODE
|
||||||
A = *(uint32 *)(image->text_region.delta + rel[i].r_offset);
|
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));
|
TRACE(("A %p\n", (void *)A));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -159,8 +163,10 @@ arch_elf_relocate_rel(struct elf_image_info *image,
|
|||||||
rel[i].r_offset);
|
rel[i].r_offset);
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
*resolveAddress = finalAddress;
|
*resolveAddress = finalAddress;
|
||||||
|
#else
|
||||||
|
boot_elf32_set_relocation((Elf32_Addr)resolveAddress, finalAddress);
|
||||||
|
#endif
|
||||||
TRACE(("-> offset %#lx (%#lx) = %#lx\n",
|
TRACE(("-> offset %#lx (%#lx) = %#lx\n",
|
||||||
(image->text_region.delta + rel[i].r_offset), rel[i].r_offset, finalAddress));
|
(image->text_region.delta + rel[i].r_offset), rel[i].r_offset, finalAddress));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user