[haiku-commits] BRANCH xyzzy-github.x86_64 - src/system/kernel/arch/x86_64 src/system/boot/loader headers/private/kernel/util src/system/boot/platform src/system/kernel/debug

  • From: xyzzy-github.x86_64 <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 24 Jun 2012 20:48:57 +0200 (CEST)

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


Other related posts: