added 5 changesets to branch 'refs/remotes/xyzzy-github/x86_64' old head: ccadfaeeb577eb5f129adcc1441b92aaf9f5e443 new head: f6a3444449c452a63e0e0d91e8480f39bca81aed ---------------------------------------------------------------------------- 69a8b95: FixedWidthPointer: Fix ==/!= operators, remove OtherType casts * FixedWidthPointer: - operators ==/!=: Change second operand type from void* to const Type*. Also add non-const version to resolve ambiguity warning when comparing with non-const pointer. - Add Pointer() getter. - Remove templatized cast operators. They are nice for casting the pointer directly to another pointer type, but result in ambiguity. * Make preloaded_image::debug_string_table non-const. Avoids clashes of the const and non-coast FixedWidthPointer comparison operators. A cleaner (but more verbose) solution would be to spezialize FixedWidthPointer for const types. [ Ingo Weinhold <ingo_weinhold@xxxxxx> ] acda52f: Fixes for other platforms. [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ] 035825c: Align the start of the kernel .data to a 2MB boundary, prevents ld from merging the text and data PHDRs. [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ] c2656eb: Improved elf_load_image() a bit. After enabling BOOT_SUPPORT_ELF64 on x86 the x86 kernel could no longer be booted because too many kernel_args allocations were taking place and filling kernel_args_ranges. This was because for each image load it would check if the image is ELF64, fail and fall back to ELF32 (each ELF64 check allocated a preloaded_image). Changed elf_load_image() so that it only tries both when loading the kernel image, and then for modules it will only try the same ELF class as the kernel image. [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ] f6a3444: Added x86_64 ELF64 relocation functions for the bootloader. All that's left to do now is handle the 64-bit load address properly. [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 22 files changed, 157 insertions(+), 42 deletions(-) headers/private/kernel/boot/elf.h | 2 +- headers/private/kernel/elf_priv.h | 2 +- headers/private/kernel/util/FixedWidthPointer.h | 42 ++++++--- headers/private/runtime_loader/runtime_loader.h | 2 +- src/system/boot/arch/x86/Jamfile | 1 + src/system/boot/arch/x86/arch_elf64.cpp | 1 + src/system/boot/arch/x86_64/Jamfile | 3 + src/system/boot/loader/Jamfile | 4 +- src/system/boot/loader/elf.cpp | 21 +++-- src/system/boot/loader/menu.cpp | 8 +- src/system/boot/platform/amiga_m68k/start.cpp | 2 +- src/system/boot/platform/atari_m68k/start.cpp | 2 +- src/system/boot/platform/bios_ia32/smp.cpp | 2 +- src/system/boot/platform/bios_ia32/start.cpp | 2 +- src/system/boot/platform/cfe/start.cpp | 2 +- src/system/boot/platform/openfirmware/start.cpp | 2 +- src/system/boot/platform/u-boot/start.cpp | 2 +- src/system/kernel/arch/x86/arch_elf.cpp | 1 - src/system/kernel/arch/x86/timers/x86_hpet.cpp | 2 +- src/system/kernel/arch/x86_64/arch_elf.cpp | 86 +++++++++++++++++++ src/system/kernel/debug/debug.cpp | 6 +- src/system/ldscripts/x86_64/kernel.ld | 4 +- ############################################################################ Commit: 69a8b95491c160f03a5b0dab0fa8d1899fe42d4b Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sat Jun 23 21:49:32 2012 UTC Committer: Alex Smith <alex@xxxxxxxxxxxxxxxx> Commit-Date: Sun Jun 24 14:26:00 2012 UTC FixedWidthPointer: Fix ==/!= operators, remove OtherType casts * FixedWidthPointer: - operators ==/!=: Change second operand type from void* to const Type*. Also add non-const version to resolve ambiguity warning when comparing with non-const pointer. - Add Pointer() getter. - Remove templatized cast operators. They are nice for casting the pointer directly to another pointer type, but result in ambiguity. * Make preloaded_image::debug_string_table non-const. Avoids clashes of the const and non-coast FixedWidthPointer comparison operators. A cleaner (but more verbose) solution would be to spezialize FixedWidthPointer for const types. ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/boot/elf.h b/headers/private/kernel/boot/elf.h index 6c07ebc..88514d9 100644 --- a/headers/private/kernel/boot/elf.h +++ b/headers/private/kernel/boot/elf.h @@ -32,7 +32,7 @@ struct preloaded_image { uint8 elf_class; addr_range dynamic_section; - FixedWidthPointer<const char> debug_string_table; + FixedWidthPointer<char> debug_string_table; uint32 num_debug_symbols; uint32 debug_string_table_size; diff --git a/headers/private/kernel/util/FixedWidthPointer.h b/headers/private/kernel/util/FixedWidthPointer.h index 7024b65..0329532 100644 --- a/headers/private/kernel/util/FixedWidthPointer.h +++ b/headers/private/kernel/util/FixedWidthPointer.h @@ -20,30 +20,29 @@ template<typename Type> class FixedWidthPointer { public: - operator Type*() const + Type * Pointer() const { return (Type*)(addr_t)fValue; } - template<typename OtherType> - operator OtherType*() const + operator Type*() const { - return static_cast<OtherType*>((Type*)(addr_t)fValue); + return Pointer(); } Type& operator*() const { - return *((Type*)(addr_t)fValue); + return *Pointer(); } Type* operator->() const { - return (Type*)(addr_t)fValue; + return Pointer(); } Type& operator[](size_t i) const { - return ((Type*)(addr_t)fValue)[i]; + return Pointer()[i]; } FixedWidthPointer& operator=(const FixedWidthPointer& p) @@ -85,15 +84,14 @@ private: template<> class FixedWidthPointer<void> { public: - operator void*() const + void * Pointer() const { return (void*)(addr_t)fValue; } - template<typename OtherType> - operator OtherType*() const + operator void*() const { - return (OtherType*)(addr_t)fValue; + return Pointer(); } FixedWidthPointer& operator=(const FixedWidthPointer& p) @@ -122,16 +120,34 @@ private: uint64 fValue; } _PACKED; + template<typename Type> inline bool -operator==(const FixedWidthPointer<Type>& a, void* b) +operator==(const FixedWidthPointer<Type>& a, const Type* b) { return a.Get() == (addr_t)b; } + +template<typename Type> +inline bool +operator!=(const FixedWidthPointer<Type>& a, const Type* b) +{ + return a.Get() != (addr_t)b; +} + + +template<typename Type> +inline bool +operator==(const FixedWidthPointer<Type>& a, Type* b) +{ + return a.Get() == (addr_t)b; +} + + template<typename Type> inline bool -operator!=(const FixedWidthPointer<Type>& a, void* b) +operator!=(const FixedWidthPointer<Type>& a, Type* b) { return a.Get() != (addr_t)b; } diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index 0397237..fbb90d5 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -534,7 +534,7 @@ debug_menu_display_current_log(Menu* menu, MenuItem* item) static bool debug_menu_display_previous_syslog(Menu* menu, MenuItem* item) { - ring_buffer* buffer = (ring_buffer*)gKernelArgs.debug_output; + ring_buffer* buffer = (ring_buffer*)gKernelArgs.debug_output.Pointer(); if (buffer == NULL) return true; @@ -595,7 +595,8 @@ save_previous_syslog_to_volume(Directory* directory) return fd; } - ring_buffer* syslogBuffer = (ring_buffer*)gKernelArgs.debug_output; + ring_buffer* syslogBuffer + = (ring_buffer*)gKernelArgs.debug_output.Pointer(); iovec vecs[2]; int32 vecCount = ring_buffer_get_vecs(syslogBuffer, vecs); if (vecCount > 0) { @@ -899,7 +900,8 @@ add_debug_menu() "Displays the debug info the boot loader has logged."); } - ring_buffer* syslogBuffer = (ring_buffer*)gKernelArgs.debug_output; + ring_buffer* syslogBuffer + = (ring_buffer*)gKernelArgs.debug_output.Pointer(); if (syslogBuffer != NULL && ring_buffer_readable(syslogBuffer) > 0) { if (!currentLogItemVisible) menu->AddSeparatorItem(); diff --git a/src/system/boot/platform/bios_ia32/smp.cpp b/src/system/boot/platform/bios_ia32/smp.cpp index d4364f7..4bc2402 100644 --- a/src/system/boot/platform/bios_ia32/smp.cpp +++ b/src/system/boot/platform/bios_ia32/smp.cpp @@ -357,7 +357,7 @@ smp_cpu_ready(void) //TRACE(("smp_cpu_ready: entry cpu %ld\n", curr_cpu)); preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( - gKernelArgs.kernel_image); + gKernelArgs.kernel_image.Pointer()); // Important. Make sure supervisor threads can fault on read only pages... asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1)); diff --git a/src/system/boot/platform/bios_ia32/start.cpp b/src/system/boot/platform/bios_ia32/start.cpp index 41284f6..b15d539 100644 --- a/src/system/boot/platform/bios_ia32/start.cpp +++ b/src/system/boot/platform/bios_ia32/start.cpp @@ -83,7 +83,7 @@ platform_start_kernel(void) = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( - gKernelArgs.kernel_image); + gKernelArgs.kernel_image.Pointer()); smp_init_other_cpus(); debug_cleanup(); diff --git a/src/system/kernel/arch/x86/timers/x86_hpet.cpp b/src/system/kernel/arch/x86/timers/x86_hpet.cpp index d5dfa48..e25785c 100644 --- a/src/system/kernel/arch/x86/timers/x86_hpet.cpp +++ b/src/system/kernel/arch/x86/timers/x86_hpet.cpp @@ -221,7 +221,7 @@ hpet_init(struct kernel_args *args) return B_ERROR; if (sHPETRegs == NULL) { - sHPETRegs = (struct hpet_regs *)args->arch_args.hpet; + sHPETRegs = (struct hpet_regs *)args->arch_args.hpet.Pointer(); if (vm_map_physical_memory(B_SYSTEM_TEAM, "hpet", (void **)&sHPETRegs, B_EXACT_ADDRESS, B_PAGE_SIZE, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, diff --git a/src/system/kernel/debug/debug.cpp b/src/system/kernel/debug/debug.cpp index 791c827..1b5d12d 100644 --- a/src/system/kernel/debug/debug.cpp +++ b/src/system/kernel/debug/debug.cpp @@ -1401,8 +1401,10 @@ syslog_init_post_vm(struct kernel_args* args) sSyslogMessage->ident[0] = '\0'; //strcpy(sSyslogMessage->ident, "KERNEL"); - if (args->debug_output != NULL) - syslog_write((const char*)args->debug_output, args->debug_size, false); + if (args->debug_output != NULL) { + syslog_write((const char*)args->debug_output.Pointer(), + args->debug_size, false); + } char revisionBuffer[64]; length = snprintf(revisionBuffer, sizeof(revisionBuffer), ############################################################################ Commit: acda52f5e963b1c76fed2eca0409444cda4529b5 Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Sun Jun 24 14:48:03 2012 UTC Fixes for other platforms. ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/amiga_m68k/start.cpp b/src/system/boot/platform/amiga_m68k/start.cpp index 490778e..8881ca7 100644 --- a/src/system/boot/platform/amiga_m68k/start.cpp +++ b/src/system/boot/platform/amiga_m68k/start.cpp @@ -75,7 +75,7 @@ platform_start_kernel(void) = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( - gKernelArgs.kernel_image); + gKernelArgs.kernel_image.Pointer()); //smp_init_other_cpus(); //serial_cleanup(); diff --git a/src/system/boot/platform/atari_m68k/start.cpp b/src/system/boot/platform/atari_m68k/start.cpp index 76fd2c7..c0f6503 100644 --- a/src/system/boot/platform/atari_m68k/start.cpp +++ b/src/system/boot/platform/atari_m68k/start.cpp @@ -75,7 +75,7 @@ platform_start_kernel(void) = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( - gKernelArgs.kernel_image); + gKernelArgs.kernel_image.Pointer()); //smp_init_other_cpus(); //serial_cleanup(); diff --git a/src/system/boot/platform/cfe/start.cpp b/src/system/boot/platform/cfe/start.cpp index 8d72532..b9a8daf 100644 --- a/src/system/boot/platform/cfe/start.cpp +++ b/src/system/boot/platform/cfe/start.cpp @@ -61,7 +61,7 @@ extern "C" void platform_start_kernel(void) { preloaded_elf32_image* image = static_cast<preloaded_elf32_image*>( - gKernelArgs.kernel_image); + gKernelArgs.kernel_image.Pointer()); addr_t kernelEntry = image->elf_header.e_entry; addr_t stackTop = gKernelArgs.cpu_kstack[0].start diff --git a/src/system/boot/platform/openfirmware/start.cpp b/src/system/boot/platform/openfirmware/start.cpp index d1729ad..0d983e8 100644 --- a/src/system/boot/platform/openfirmware/start.cpp +++ b/src/system/boot/platform/openfirmware/start.cpp @@ -96,7 +96,7 @@ extern "C" void platform_start_kernel(void) { preloaded_elf32_image* image = static_cast<preloaded_elf32_image*>( - gKernelArgs.kernel_image); + gKernelArgs.kernel_image.Pointer()); addr_t kernelEntry = image->elf_header.e_entry; addr_t stackTop = gKernelArgs.cpu_kstack[0].start diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 0f1fa00..a3b93bc 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -91,7 +91,7 @@ extern "C" void platform_start_kernel(void) { preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>( - gKernelArgs.kernel_image); + gKernelArgs.kernel_image.Pointer()); addr_t kernelEntry = image->elf_header.e_entry; addr_t stackTop ############################################################################ Commit: 035825cdfcf0f778a4e87c7a216c14ab5e9b8116 Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Sun Jun 24 16:19:48 2012 UTC Align the start of the kernel .data to a 2MB boundary, prevents ld from merging the text and data PHDRs. ---------------------------------------------------------------------------- diff --git a/src/system/ldscripts/x86_64/kernel.ld b/src/system/ldscripts/x86_64/kernel.ld index 0703792..1496cc7 100644 --- a/src/system/ldscripts/x86_64/kernel.ld +++ b/src/system/ldscripts/x86_64/kernel.ld @@ -28,8 +28,8 @@ SECTIONS .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - /* writable data */ - . = ALIGN(0x1000); + /* writable data */ + . = ALIGN (0x200000); __data_start = .; .data : { *(.data .data.* .gnu.linkonce.d.*) } ############################################################################ Commit: c2656eb9bd735878c33f979c273ba59a1f96cc09 Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Sun Jun 24 16:51:05 2012 UTC Improved elf_load_image() a bit. After enabling BOOT_SUPPORT_ELF64 on x86 the x86 kernel could no longer be booted because too many kernel_args allocations were taking place and filling kernel_args_ranges. This was because for each image load it would check if the image is ELF64, fail and fall back to ELF32 (each ELF64 check allocated a preloaded_image). Changed elf_load_image() so that it only tries both when loading the kernel image, and then for modules it will only try the same ELF class as the kernel image. ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/elf.cpp b/src/system/boot/loader/elf.cpp index f54e96b..1e1d7a4 100644 --- a/src/system/boot/loader/elf.cpp +++ b/src/system/boot/loader/elf.cpp @@ -222,7 +222,7 @@ ELFLoader<Class>::Load(int fd, preloaded_image* _image) // inbetween. totalSize = secondRegion->start + secondRegion->size - firstRegion->start; if (totalSize > image->text_region.size + image->data_region.size - + 8 * 1024) { + + 0x200000) { status = B_BAD_DATA; goto error1; } @@ -543,22 +543,27 @@ elf_init() status_t elf_load_image(int fd, preloaded_image** _image) { - status_t status; + status_t status = B_ERROR; TRACE(("elf_load_image(fd = %d, _image = %p)\n", fd, _image)); #if BOOT_SUPPORT_ELF64 - status = ELF64Loader::Create(fd, _image); - if (status == B_OK) { - return ELF64Loader::Load(fd, *_image); - } else if (status == B_BAD_TYPE) { + if (gKernelArgs.kernel_image == NULL + || gKernelArgs.kernel_image->elf_class == ELFCLASS64) { + status = ELF64Loader::Create(fd, _image); + if (status == B_OK) + return ELF64Loader::Load(fd, *_image); + else if (status != B_BAD_TYPE) + return status; + } #endif + + if (gKernelArgs.kernel_image == NULL + || gKernelArgs.kernel_image->elf_class == ELFCLASS32) { status = ELF32Loader::Create(fd, _image); if (status == B_OK) return ELF32Loader::Load(fd, *_image); -#if BOOT_SUPPORT_ELF64 } -#endif return status; } ############################################################################ Commit: f6a3444449c452a63e0e0d91e8480f39bca81aed Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Sun Jun 24 18:22:33 2012 UTC Added x86_64 ELF64 relocation functions for the bootloader. All that's left to do now is handle the 64-bit load address properly. ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/elf_priv.h b/headers/private/kernel/elf_priv.h index 8169574..fd386c4 100644 --- a/headers/private/kernel/elf_priv.h +++ b/headers/private/kernel/elf_priv.h @@ -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)]) diff --git a/headers/private/runtime_loader/runtime_loader.h b/headers/private/runtime_loader/runtime_loader.h index 132a674..ddccda1 100644 --- a/headers/private/runtime_loader/runtime_loader.h +++ b/headers/private/runtime_loader/runtime_loader.h @@ -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)]) diff --git a/src/system/boot/arch/x86/Jamfile b/src/system/boot/arch/x86/Jamfile index 21eb0ac..e7cff1e 100644 --- a/src/system/boot/arch/x86/Jamfile +++ b/src/system/boot/arch/x86/Jamfile @@ -19,6 +19,7 @@ local kernelLibArchObjects = ; BootMergeObject boot_arch_$(TARGET_ARCH).o : + arch_elf64.cpp $(kernelArchSources) $(kernelLibArchSources) : # additional flags diff --git a/src/system/boot/arch/x86/arch_elf64.cpp b/src/system/boot/arch/x86/arch_elf64.cpp new file mode 100644 index 0000000..41e0198 --- /dev/null +++ b/src/system/boot/arch/x86/arch_elf64.cpp @@ -0,0 +1 @@ +#include "../../../kernel/arch/x86_64/arch_elf.cpp" diff --git a/src/system/boot/arch/x86_64/Jamfile b/src/system/boot/arch/x86_64/Jamfile index dae2896..3dd0418 100644 --- a/src/system/boot/arch/x86_64/Jamfile +++ b/src/system/boot/arch/x86_64/Jamfile @@ -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 ] ; diff --git a/src/system/boot/loader/Jamfile b/src/system/boot/loader/Jamfile index c948699..f325c32 100644 --- a/src/system/boot/loader/Jamfile +++ b/src/system/boot/loader/Jamfile @@ -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 diff --git a/src/system/kernel/arch/x86/arch_elf.cpp b/src/system/kernel/arch/x86/arch_elf.cpp index df6cebe..2057052 100644 --- a/src/system/kernel/arch/x86/arch_elf.cpp +++ b/src/system/kernel/arch/x86/arch_elf.cpp @@ -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; } - diff --git a/src/system/kernel/arch/x86_64/arch_elf.cpp b/src/system/kernel/arch/x86_64/arch_elf.cpp index f8c6ad2..b0cbe9d 100644 --- a/src/system/kernel/arch/x86_64/arch_elf.cpp +++ b/src/system/kernel/arch/x86_64/arch_elf.cpp @@ -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