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
This commit is contained in:
Jérôme Duval
2018-05-05 09:37:49 +00:00
parent 51dfedd76b
commit 2aaad308b8
7 changed files with 130 additions and 4 deletions
+5
View File
@@ -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) {
+6 -1
View File
@@ -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 ]
;
}
}
+27
View File
@@ -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)
{
@@ -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);
@@ -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);
@@ -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
@@ -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);