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
+1 -1
View File
@@ -69,7 +69,7 @@ struct elf_image_info {
#define STRING(image, offset) ((char *)(&(image)->strtab[(offset)])) #define STRING(image, offset) ((char *)(&(image)->strtab[(offset)]))
#define SYMNAME(image, sym) STRING(image, (sym)->st_name) #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 HASHTABSIZE(image) ((image)->symhash[0])
#define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2]) #define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2])
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)]) #define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
@@ -154,7 +154,7 @@ typedef struct image_queue_t {
#define STRING(image, offset) ((char *)(&(image)->strtab[(offset)])) #define STRING(image, offset) ((char *)(&(image)->strtab[(offset)]))
#define SYMNAME(image, sym) STRING(image, (sym)->st_name) #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 HASHTABSIZE(image) ((image)->symhash[0])
#define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2]) #define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2])
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)]) #define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
+1
View File
@@ -19,6 +19,7 @@ local kernelLibArchObjects =
; ;
BootMergeObject boot_arch_$(TARGET_ARCH).o : BootMergeObject boot_arch_$(TARGET_ARCH).o :
arch_elf64.cpp
$(kernelArchSources) $(kernelArchSources)
$(kernelLibArchSources) $(kernelLibArchSources)
: # additional flags : # additional flags
+1
View File
@@ -0,0 +1 @@
#include "../../../kernel/arch/x86_64/arch_elf.cpp"
+3
View File
@@ -16,6 +16,7 @@ local librootOsArchSources =
; ;
BootMergeObject boot_arch_$(TARGET_ARCH).o : BootMergeObject boot_arch_$(TARGET_ARCH).o :
arch_elf64.cpp
$(kernelArchSources) $(kernelArchSources)
$(kernelLibArchSources) $(kernelLibArchSources)
$(librootOsArchSources) $(librootOsArchSources)
@@ -28,3 +29,5 @@ SEARCH on [ FGristFiles $(kernelLibArchSources) ]
= [ FDirName $(HAIKU_TOP) src system kernel lib arch x86 ] ; = [ FDirName $(HAIKU_TOP) src system kernel lib arch x86 ] ;
SEARCH on [ FGristFiles $(librootOsArchSources) ] SEARCH on [ FGristFiles $(librootOsArchSources) ]
= [ FDirName $(HAIKU_TOP) src system libroot os arch x86 ] ; = [ FDirName $(HAIKU_TOP) src system libroot os arch x86 ] ;
SEARCH on [ FGristFiles $(kernelArchSources) ]
= [ FDirName $(HAIKU_TOP) src system boot arch x86 ] ;
+2 -2
View File
@@ -39,7 +39,7 @@ UsePrivateHeaders shared storage ;
{ {
defines += defines +=
ALTERNATE_BOOT_ARCH=\\\"x86_64\\\" ALTERNATE_BOOT_ARCH=\\\"x86_64\\\"
#BOOT_SUPPORT_ELF64 BOOT_SUPPORT_ELF64
BOOT_SUPPORT_PARTITION_EFI BOOT_SUPPORT_PARTITION_EFI
@@ -50,7 +50,7 @@ UsePrivateHeaders shared storage ;
{ {
defines += defines +=
ALTERNATE_BOOT_ARCH=\\\"x86\\\" ALTERNATE_BOOT_ARCH=\\\"x86\\\"
#BOOT_SUPPORT_ELF64 BOOT_SUPPORT_ELF64
BOOT_SUPPORT_PARTITION_EFI BOOT_SUPPORT_PARTITION_EFI
-1
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"); dprintf("arch_elf_relocate_rela: not supported on x86\n");
return B_ERROR; return B_ERROR;
} }
@@ -3,10 +3,19 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifdef _BOOT_MODE
# include <boot/arch.h>
#endif
#include <KernelExport.h>
#include <elf.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. // Currently got generic elf.cpp #ifdef'd out for x86_64, define stub versions here.
status_t status_t
@@ -80,3 +89,80 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
{ {
return B_ERROR; 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