8226238: Improve error output and fix elf issues in os::dll_load
Reviewed-by: clanger, mdoerr
This commit is contained in:
parent
53fefe466c
commit
202159bc57
@ -84,6 +84,7 @@
|
||||
# include <sys/select.h>
|
||||
# include <pthread.h>
|
||||
# include <signal.h>
|
||||
# include <endian.h>
|
||||
# include <errno.h>
|
||||
# include <dlfcn.h>
|
||||
# include <stdio.h>
|
||||
@ -1747,11 +1748,26 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (elf_head.e_ident[EI_DATA] != LITTLE_ENDIAN_ONLY(ELFDATA2LSB) BIG_ENDIAN_ONLY(ELFDATA2MSB)) {
|
||||
// handle invalid/out of range endianness values
|
||||
if (elf_head.e_ident[EI_DATA] == 0 || elf_head.e_ident[EI_DATA] > 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(VM_LITTLE_ENDIAN)
|
||||
// VM is LE, shared object BE
|
||||
elf_head.e_machine = be16toh(elf_head.e_machine);
|
||||
#else
|
||||
// VM is BE, shared object LE
|
||||
elf_head.e_machine = le16toh(elf_head.e_machine);
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Elf32_Half code; // Actual value as defined in elf.h
|
||||
Elf32_Half compat_class; // Compatibility of archs at VM's sense
|
||||
unsigned char elf_class; // 32 or 64 bit
|
||||
unsigned char endianess; // MSB or LSB
|
||||
unsigned char endianness; // MSB or LSB
|
||||
char* name; // String representation
|
||||
} arch_t;
|
||||
|
||||
@ -1778,8 +1794,9 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
{EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
|
||||
{EM_SH, EM_SH, ELFCLASS32, ELFDATA2MSB, (char*)"SuperH BE"},
|
||||
#endif
|
||||
{EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
|
||||
{EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
|
||||
{EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
|
||||
// we only support 64 bit z architecture
|
||||
{EM_S390, EM_S390, ELFCLASS64, ELFDATA2MSB, (char*)"IBM System/390"},
|
||||
{EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
|
||||
{EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
|
||||
{EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
|
||||
@ -1825,7 +1842,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
AARCH64, ALPHA, ARM, AMD64, IA32, IA64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, S390, SH, __sparc
|
||||
#endif
|
||||
|
||||
// Identify compatability class for VM's architecture and library's architecture
|
||||
// Identify compatibility class for VM's architecture and library's architecture
|
||||
// Obtain string descriptions for architectures
|
||||
|
||||
arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
|
||||
@ -1849,29 +1866,35 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef S390
|
||||
if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
|
||||
return NULL;
|
||||
}
|
||||
#endif // !S390
|
||||
|
||||
if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
|
||||
if (lib_arch.name!=NULL) {
|
||||
if (lib_arch.name != NULL) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1,
|
||||
" (Possible cause: can't load %s-bit .so on a %s-bit platform)",
|
||||
" (Possible cause: can't load %s .so on a %s platform)",
|
||||
lib_arch.name, arch_array[running_arch_index].name);
|
||||
} else {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1,
|
||||
" (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
|
||||
lib_arch.code,
|
||||
arch_array[running_arch_index].name);
|
||||
" (Possible cause: can't load this .so (machine code=0x%x) on a %s platform)",
|
||||
lib_arch.code, arch_array[running_arch_index].name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lib_arch.endianness != arch_array[running_arch_index].endianness) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1, " (Possible cause: endianness mismatch)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ELF file class/capacity : 0 - invalid, 1 - 32bit, 2 - 64bit
|
||||
if (lib_arch.elf_class > 2 || lib_arch.elf_class < 1) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1, " (Possible cause: invalid ELF file class)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1,
|
||||
" (Possible cause: architecture word width mismatch, can't load %d-bit .so on a %d-bit platform)",
|
||||
(int) lib_arch.elf_class * 32, arch_array[running_arch_index].elf_class * 32);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -1520,6 +1520,13 @@ void os::print_dll_info(outputStream * st) {
|
||||
}
|
||||
}
|
||||
|
||||
static void change_endianness(Elf32_Half& val) {
|
||||
unsigned char *ptr = (unsigned char *)&val;
|
||||
unsigned char swp = ptr[0];
|
||||
ptr[0] = ptr[1];
|
||||
ptr[1] = swp;
|
||||
}
|
||||
|
||||
// Loads .dll/.so and
|
||||
// in case of error it checks if .dll/.so was built for the
|
||||
// same architecture as Hotspot is running on
|
||||
@ -1570,6 +1577,14 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (elf_head.e_ident[EI_DATA] != LITTLE_ENDIAN_ONLY(ELFDATA2LSB) BIG_ENDIAN_ONLY(ELFDATA2MSB)) {
|
||||
// handle invalid/out of range endianness values
|
||||
if (elf_head.e_ident[EI_DATA] == 0 || elf_head.e_ident[EI_DATA] > 2) {
|
||||
return NULL;
|
||||
}
|
||||
change_endianness(elf_head.e_machine);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Elf32_Half code; // Actual value as defined in elf.h
|
||||
Elf32_Half compat_class; // Compatibility of archs at VM's sense
|
||||
@ -1588,7 +1603,10 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
{EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
|
||||
{EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
|
||||
{EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
|
||||
{EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM 32"}
|
||||
{EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
|
||||
// we only support 64 bit z architecture
|
||||
{EM_S390, EM_S390, ELFCLASS64, ELFDATA2MSB, (char*)"IBM System/390"},
|
||||
{EM_AARCH64, EM_AARCH64, ELFCLASS64, ELFDATA2LSB, (char*)"AARCH64"}
|
||||
};
|
||||
|
||||
#if (defined IA32)
|
||||
@ -1612,7 +1630,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
IA32, AMD64, IA64, __sparc, __powerpc__, ARM, ARM
|
||||
#endif
|
||||
|
||||
// Identify compatability class for VM's architecture and library's architecture
|
||||
// Identify compatibility class for VM's architecture and library's architecture
|
||||
// Obtain string descriptions for architectures
|
||||
|
||||
arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
|
||||
@ -1636,27 +1654,35 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
|
||||
if (lib_arch.name != NULL) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1,
|
||||
" (Possible cause: can't load %s .so on a %s platform)",
|
||||
lib_arch.name, arch_array[running_arch_index].name);
|
||||
} else {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1,
|
||||
" (Possible cause: can't load this .so (machine code=0x%x) on a %s platform)",
|
||||
lib_arch.code, arch_array[running_arch_index].name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
|
||||
// ELF file class/capacity : 0 - invalid, 1 - 32bit, 2 - 64bit
|
||||
if (lib_arch.elf_class > 2 || lib_arch.elf_class < 1) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1, " (Possible cause: invalid ELF file class)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
|
||||
if (lib_arch.name!=NULL) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1,
|
||||
" (Possible cause: can't load %s-bit .so on a %s-bit platform)",
|
||||
lib_arch.name, arch_array[running_arch_index].name);
|
||||
} else {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1,
|
||||
" (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
|
||||
lib_arch.code,
|
||||
arch_array[running_arch_index].name);
|
||||
}
|
||||
if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
|
||||
::snprintf(diag_msg_buf, diag_msg_max_length-1,
|
||||
" (Possible cause: architecture word width mismatch, can't load %d-bit .so on a %d-bit platform)",
|
||||
(int) lib_arch.elf_class * 32, arch_array[running_arch_index].elf_class * 32);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user