[haiku-commits] haiku: hrev51921 - in src/system/runtime_loader: . arch/x86

  • From: jerome.duval@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 5 May 2018 05:37:52 -0400 (EDT)

hrev51921 adds 1 changeset to branch 'master'
old head: 51dfedd76b8108157b8015c30eac02ab7666b948
new head: 2aaad308b8ccd55cf9d044d2128c6a75b32f18a3
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=2aaad308b8cc+%5E51dfedd76b81

----------------------------------------------------------------------------

2aaad308b8cc: runtime_loader: enable elf32 on x86_64, elf64 on x86.
  
  use x86 as default sSearchPathSubDir in compatibility mode.
  use the generic memset/memcpy when x86_64 is the primary arch.
  
  Change-Id: Ib464c308ff97f7ae2482ef4c037de1b1bb2bf61b

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev51921
Commit:      2aaad308b8ccd55cf9d044d2128c6a75b32f18a3
URL:         https://git.haiku-os.org/haiku/commit/?id=2aaad308b8cc
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Wed May  2 15:54:27 2018 UTC

----------------------------------------------------------------------------

7 files changed, 130 insertions(+), 4 deletions(-)
src/system/runtime_loader/Jamfile                |  5 ++
src/system/runtime_loader/arch/x86/Jamfile       |  7 ++-
src/system/runtime_loader/elf.cpp                | 27 +++++++++
src/system/runtime_loader/elf_load_image.cpp     | 59 ++++++++++++++++++++
src/system/runtime_loader/elf_load_image.h       |  9 +++
src/system/runtime_loader/runtime_loader.cpp     |  9 +++
.../runtime_loader/runtime_loader_private.h      | 18 +++++-

----------------------------------------------------------------------------

diff --git a/src/system/runtime_loader/Jamfile 
b/src/system/runtime_loader/Jamfile
index 5476f5da01..46239d120e 100644
--- a/src/system/runtime_loader/Jamfile
+++ b/src/system/runtime_loader/Jamfile
@@ -1,6 +1,11 @@
 SubDir HAIKU_TOP src system runtime_loader ;
 
 
+if $(TARGET_ARCH) = x86_64
+       && ( x86 in $(HAIKU_ARCHS[2-]) || x86_gcc2 in $(HAIKU_ARCHS[2-]) ) {
+       DEFINES += _COMPAT_MODE ;
+}
+
 local architectureObject ;
 for architectureObject in [ MultiArchSubDirSetup ] {
        on $(architectureObject) {
diff --git a/src/system/runtime_loader/arch/x86/Jamfile 
b/src/system/runtime_loader/arch/x86/Jamfile
index 444c3211b0..68cb226dd0 100644
--- a/src/system/runtime_loader/arch/x86/Jamfile
+++ b/src/system/runtime_loader/arch/x86/Jamfile
@@ -16,7 +16,12 @@ for architectureObject in [ MultiArchSubDirSetup x86 
x86_gcc2 ] {
                        
<src!system!libroot!os!arch!$(TARGET_ARCH)!$(architecture)>atomic.o
                        
<src!system!libroot!os!arch!$(TARGET_ARCH)!$(architecture)>thread.o
 
-                       
<src!system!libroot!posix!string!arch!$(TARGET_ARCH)!$(architecture)>arch_string.o
+                       [ MultiArchIfPrimary
+                               
<src!system!libroot!posix!string!arch!$(TARGET_ARCH)!$(architecture)>memcpy.o
+                               
<src!system!libroot!posix!string!arch!$(TARGET_ARCH)!$(architecture)>memset.o
+                               :
+                               
<src!system!libroot!posix!string!arch!$(TARGET_ARCH)!$(architecture)>arch_string.o
+                               : x86_64 ]
                        ;
        }
 }
diff --git a/src/system/runtime_loader/elf.cpp 
b/src/system/runtime_loader/elf.cpp
index 03b8bd1c73..018315955d 100644
--- a/src/system/runtime_loader/elf.cpp
+++ b/src/system/runtime_loader/elf.cpp
@@ -1012,6 +1012,33 @@ elf_verify_header(void *header, size_t length)
 }
 
 
+#ifdef _COMPAT_MODE
+#ifdef __x86_64__
+status_t
+elf32_verify_header(void *header, size_t length)
+{
+       int32 programSize, sectionSize;
+
+       if (length < sizeof(Elf32_Ehdr))
+               return B_NOT_AN_EXECUTABLE;
+
+       return parse_elf32_header((Elf32_Ehdr *)header, &programSize, 
&sectionSize);
+}
+#else
+status_t
+elf64_verify_header(void *header, size_t length)
+{
+       int32 programSize, sectionSize;
+
+       if (length < sizeof(Elf64_Ehdr))
+               return B_NOT_AN_EXECUTABLE;
+
+       return parse_elf64_header((Elf64_Ehdr *)header, &programSize, 
&sectionSize);
+}
+#endif // __x86_64__
+#endif // _COMPAT_MODE
+
+
 void
 terminate_program(void)
 {
diff --git a/src/system/runtime_loader/elf_load_image.cpp 
b/src/system/runtime_loader/elf_load_image.cpp
index 3822f36266..ebd3f41b0f 100644
--- a/src/system/runtime_loader/elf_load_image.cpp
+++ b/src/system/runtime_loader/elf_load_image.cpp
@@ -421,6 +421,61 @@ parse_elf_header(elf_ehdr* eheader, int32* _pheaderSize,
 }
 
 
+#if defined(_COMPAT_MODE)
+#if defined(__x86_64__)
+status_t
+parse_elf32_header(Elf32_Ehdr* eheader, int32* _pheaderSize,
+       int32* _sheaderSize)
+{
+       if (memcmp(eheader->e_ident, ELFMAG, 4) != 0)
+               return B_NOT_AN_EXECUTABLE;
+
+       if (eheader->e_ident[4] != ELFCLASS32)
+               return B_NOT_AN_EXECUTABLE;
+
+       if (eheader->e_phoff == 0)
+               return B_NOT_AN_EXECUTABLE;
+
+       if (eheader->e_phentsize < sizeof(Elf32_Phdr))
+               return B_NOT_AN_EXECUTABLE;
+
+       *_pheaderSize = eheader->e_phentsize * eheader->e_phnum;
+       *_sheaderSize = eheader->e_shentsize * eheader->e_shnum;
+
+       if (*_pheaderSize <= 0 || *_sheaderSize <= 0)
+               return B_NOT_AN_EXECUTABLE;
+
+       return B_OK;
+}
+#else
+status_t
+parse_elf64_header(Elf64_Ehdr* eheader, int32* _pheaderSize,
+       int32* _sheaderSize)
+{
+       if (memcmp(eheader->e_ident, ELFMAG, 4) != 0)
+               return B_NOT_AN_EXECUTABLE;
+
+       if (eheader->e_ident[4] != ELFCLASS64)
+               return B_NOT_AN_EXECUTABLE;
+
+       if (eheader->e_phoff == 0)
+               return B_NOT_AN_EXECUTABLE;
+
+       if (eheader->e_phentsize < sizeof(Elf64_Phdr))
+               return B_NOT_AN_EXECUTABLE;
+
+       *_pheaderSize = eheader->e_phentsize * eheader->e_phnum;
+       *_sheaderSize = eheader->e_shentsize * eheader->e_shnum;
+
+       if (*_pheaderSize <= 0 || *_sheaderSize <= 0)
+               return B_NOT_AN_EXECUTABLE;
+
+       return B_OK;
+}
+#endif // __x86_64__
+#endif // _COMPAT_MODE
+
+
 status_t
 load_image(char const* name, image_type type, const char* rpath,
        const char* requestingObjectPath, image_t** _image)
@@ -574,6 +629,9 @@ load_image(char const* name, image_type type, const char* 
rpath,
        // loading) we init the search path subdir if the compiler version 
doesn't
        // match ours.
        if (sSearchPathSubDir == NULL) {
+#if defined(_COMPAT_MODE) && !defined(__x86_64__)
+               sSearchPathSubDir = "x86";
+#else
                #if __GNUC__ == 2
                        if ((image->abi & B_HAIKU_ABI_MAJOR) == 
B_HAIKU_ABI_GCC_4)
                                sSearchPathSubDir = "x86";
@@ -581,6 +639,7 @@ load_image(char const* name, image_type type, const char* 
rpath,
                        if ((image->abi & B_HAIKU_ABI_MAJOR) == 
B_HAIKU_ABI_GCC_2)
                                sSearchPathSubDir = "x86_gcc2";
                #endif
+#endif
        }
 
        set_abi_version(image->abi);
diff --git a/src/system/runtime_loader/elf_load_image.h 
b/src/system/runtime_loader/elf_load_image.h
index 77ead88b86..061c0677ae 100644
--- a/src/system/runtime_loader/elf_load_image.h
+++ b/src/system/runtime_loader/elf_load_image.h
@@ -10,6 +10,15 @@
 
 status_t       parse_elf_header(elf_ehdr* eheader, int32* _pheaderSize,
                                int32* _sheaderSize);
+#if defined(_COMPAT_MODE)
+       #if defined(__x86_64__)
+status_t       parse_elf32_header(Elf32_Ehdr* eheader, int32* _pheaderSize,
+       int32* _sheaderSize);
+       #else
+status_t       parse_elf64_header(Elf64_Ehdr* eheader, int32* _pheaderSize,
+       int32* _sheaderSize);
+       #endif
+#endif
 status_t       load_image(char const* name, image_type type, const char* rpath,
                                const char* requestingObjectPath, image_t** 
_image);
 
diff --git a/src/system/runtime_loader/runtime_loader.cpp 
b/src/system/runtime_loader/runtime_loader.cpp
index 3aa9cc34e8..e632895e92 100644
--- a/src/system/runtime_loader/runtime_loader.cpp
+++ b/src/system/runtime_loader/runtime_loader.cpp
@@ -416,6 +416,15 @@ test_executable(const char *name, char *invoker)
        }
 
        status = elf_verify_header(buffer, length);
+#ifdef _COMPAT_MODE
+#ifdef __x86_64__
+       if (status == B_NOT_AN_EXECUTABLE)
+               status = elf32_verify_header(buffer, length);
+#else
+       if (status == B_NOT_AN_EXECUTABLE)
+               status = elf64_verify_header(buffer, length);
+#endif // __x86_64__
+#endif // _COMPAT_MODE
        if (status == B_NOT_AN_EXECUTABLE) {
                if (!strncmp(buffer, "#!", 2)) {
                        // test for shell scripts
diff --git a/src/system/runtime_loader/runtime_loader_private.h 
b/src/system/runtime_loader/runtime_loader_private.h
index be40233378..5df7dc6b7a 100644
--- a/src/system/runtime_loader/runtime_loader_private.h
+++ b/src/system/runtime_loader/runtime_loader_private.h
@@ -30,12 +30,17 @@
 #      define KTRACE(x...)
 #endif // RUNTIME_LOADER_TRACING
 
-
+#if defined(_COMPAT_MODE) && !defined(__x86_64__)
+#define RLD_PREFIX "runtime_loader_compat: "
+#endif
+#ifndef RLD_PREFIX
+#define RLD_PREFIX "runtime_loader: "
+#endif
 #define FATAL(x...)                                                    \
        do {                                                                    
\
-               dprintf("runtime_loader: " x);          \
+               dprintf(RLD_PREFIX x);          \
                if (!gProgramLoaded)                            \
-                       printf("runtime_loader: " x);   \
+                       printf(RLD_PREFIX x);   \
        } while (false)
 
 
@@ -81,6 +86,13 @@ int resolve_symbol(image_t* rootImage, image_t* image, 
elf_sym* sym,
 
 
 status_t elf_verify_header(void* header, size_t length);
+#ifdef _COMPAT_MODE
+#ifdef __x86_64__
+status_t elf32_verify_header(void *header, size_t length);
+#else
+status_t elf64_verify_header(void *header, size_t length);
+#endif // __x86_64__
+#endif // _COMPAT_MODE
 void rldelf_init(void);
 void rldexport_init(void);
 void set_abi_version(int abi_version);


Other related posts:

  • » [haiku-commits] haiku: hrev51921 - in src/system/runtime_loader: . arch/x86 - jerome . duval