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:
@@ -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) {
|
||||
|
||||
@@ -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 ]
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user