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,
§ionSize);
+}
+#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,
§ionSize);
+}
+#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);