Added x86_64 ELF64 relocation functions for the bootloader. All that's left to do now is handle the 64-bit load address properly.

This commit is contained in:
Alex Smith 2012-06-24 19:22:33 +01:00
parent c2656eb9bd
commit f6a3444449
8 changed files with 95 additions and 5 deletions

View File

@ -69,7 +69,7 @@ struct elf_image_info {
#define STRING(image, offset) ((char *)(&(image)->strtab[(offset)]))
#define SYMNAME(image, sym) STRING(image, (sym)->st_name)
#define SYMBOL(image, num) ((struct Elf32_Sym *)&(image)->syms[num])
#define SYMBOL(image, num) (&(image)->syms[num])
#define HASHTABSIZE(image) ((image)->symhash[0])
#define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2])
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])

View File

@ -154,7 +154,7 @@ typedef struct image_queue_t {
#define STRING(image, offset) ((char *)(&(image)->strtab[(offset)]))
#define SYMNAME(image, sym) STRING(image, (sym)->st_name)
#define SYMBOL(image, num) ((struct Elf32_Sym *)&(image)->syms[num])
#define SYMBOL(image, num) (&(image)->syms[num])
#define HASHTABSIZE(image) ((image)->symhash[0])
#define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2])
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])

View File

@ -19,6 +19,7 @@ local kernelLibArchObjects =
;
BootMergeObject boot_arch_$(TARGET_ARCH).o :
arch_elf64.cpp
$(kernelArchSources)
$(kernelLibArchSources)
: # additional flags

View File

@ -0,0 +1 @@
#include "../../../kernel/arch/x86_64/arch_elf.cpp"

View File

@ -16,6 +16,7 @@ local librootOsArchSources =
;
BootMergeObject boot_arch_$(TARGET_ARCH).o :
arch_elf64.cpp
$(kernelArchSources)
$(kernelLibArchSources)
$(librootOsArchSources)
@ -28,3 +29,5 @@ SEARCH on [ FGristFiles $(kernelLibArchSources) ]
= [ FDirName $(HAIKU_TOP) src system kernel lib arch x86 ] ;
SEARCH on [ FGristFiles $(librootOsArchSources) ]
= [ FDirName $(HAIKU_TOP) src system libroot os arch x86 ] ;
SEARCH on [ FGristFiles $(kernelArchSources) ]
= [ FDirName $(HAIKU_TOP) src system boot arch x86 ] ;

View File

@ -39,7 +39,7 @@ UsePrivateHeaders shared storage ;
{
defines +=
ALTERNATE_BOOT_ARCH=\\\"x86_64\\\"
#BOOT_SUPPORT_ELF64
BOOT_SUPPORT_ELF64
BOOT_SUPPORT_PARTITION_EFI
@ -50,7 +50,7 @@ UsePrivateHeaders shared storage ;
{
defines +=
ALTERNATE_BOOT_ARCH=\\\"x86\\\"
#BOOT_SUPPORT_ELF64
BOOT_SUPPORT_ELF64
BOOT_SUPPORT_PARTITION_EFI

View File

@ -178,4 +178,3 @@ arch_elf_relocate_rela(struct elf_image_info *image,
dprintf("arch_elf_relocate_rela: not supported on x86\n");
return B_ERROR;
}

View File

@ -3,10 +3,19 @@
* Distributed under the terms of the MIT License.
*/
#ifdef _BOOT_MODE
# include <boot/arch.h>
#endif
#include <KernelExport.h>
#include <elf.h>
#include <elf_priv.h>
#include <arch/elf.h>
#ifndef _BOOT_MODE
// Currently got generic elf.cpp #ifdef'd out for x86_64, define stub versions here.
status_t
@ -80,3 +89,80 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
{
return B_ERROR;
}
#endif
#ifdef _BOOT_MODE
status_t
boot_arch_elf_relocate_rel(preloaded_elf64_image* image, Elf64_Rel* rel,
int relLength)
//#else
//int
//arch_elf_relocate_rel(struct elf_image_info *image,
// struct elf_image_info *resolveImage, struct Elf32_Rel *rel, int relLength)
//#endif
{
dprintf("arch_elf_relocate_rel: not supported on x86_64\n");
return B_ERROR;
}
//#ifdef _BOOT_MODE
status_t
boot_arch_elf_relocate_rela(preloaded_elf64_image* image, Elf64_Rela* rel,
int relLength)
//#else
//int
//arch_elf_relocate_rela(struct elf_image_info *image,
// struct elf_image_info *resolveImage, struct Elf32_Rela *rel, int relLength)
//#endif
{
for (int i = 0; i < relLength / (int)sizeof(Elf64_Rela); i++) {
int type = ELF64_R_TYPE(rel[i].r_info);
int symIndex = ELF64_R_SYM(rel[i].r_info);
Elf64_Addr symAddr = 0;
// Resolve the symbol, if any.
if (symIndex != 0) {
Elf64_Sym* symbol = SYMBOL(image, symIndex);
status_t status;
//#ifdef _BOOT_MODE
status = boot_elf_resolve_symbol(image, symbol, &symAddr);
//#else
// status = elf_resolve_symbol(image, symbol, resolveImage, &S);
//#endif
if (status < B_OK)
return status;
}
// Address of the relocation.
Elf64_Addr* resolveAddr = (Elf64_Addr *)(image->text_region.delta
+ rel[i].r_offset);
// Perform the relocation.
switch(type) {
case R_X86_64_NONE:
break;
case R_X86_64_64:
*resolveAddr = symAddr + rel[i].r_addend;
break;
case R_X86_64_PC32:
*resolveAddr = symAddr + rel[i].r_addend - rel[i].r_offset;
break;
case R_X86_64_GLOB_DAT:
case R_X86_64_JUMP_SLOT:
*resolveAddr = symAddr + rel[i].r_addend;
break;
case R_X86_64_RELATIVE:
*resolveAddr = image->text_region.delta + rel[i].r_addend;
break;
default:
dprintf("arch_elf_relocate_rel: unhandled relocation type %d\n",
type);
return B_BAD_DATA;
}
}
return B_OK;
}
#endif