hotspot/src/os/windows/vm/os_windows.cpp
// Loads .dll/.so and
// in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on
void * os::dll_load(const char *name, char *ebuf, int ebuflen)
{
{- -------------------------------------------
(1) LoadLibrary() が成功すればそれを返す.
---------------------------------------- -}
void * result = LoadLibrary(name);
if (result != NULL)
{
return result;
}
{- -------------------------------------------
(1) (以下は LoadLibrary() が失敗した場合の処理.
失敗の原因を少し調べて分かりやすいエラーメッセージを返すようにしている.)
---------------------------------------- -}
long errcode = GetLastError();
if (errcode == ERROR_MOD_NOT_FOUND) {
strncpy(ebuf, "Can't find dependent libraries", ebuflen-1);
ebuf[ebuflen-1]='\0';
return NULL;
}
// Parsing dll below
// If we can read dll-info and find that dll was built
// for an architecture other than Hotspot is running in
// - then print to buffer "DLL was built for a different architecture"
// else call getLastErrorString to obtain system error message
// Read system error message into ebuf
// It may or may not be overwritten below (in the for loop and just above)
getLastErrorString(ebuf, (size_t) ebuflen);
ebuf[ebuflen-1]='\0';
int file_descriptor=::open(name, O_RDONLY | O_BINARY, 0);
if (file_descriptor<0)
{
return NULL;
}
uint32_t signature_offset;
uint16_t lib_arch=0;
bool failed_to_get_lib_arch=
(
//Go to position 3c in the dll
(os::seek_to_file_offset(file_descriptor,IMAGE_FILE_PTR_TO_SIGNATURE)<0)
||
// Read loacation of signature
(sizeof(signature_offset)!=
(os::read(file_descriptor, (void*)&signature_offset,sizeof(signature_offset))))
||
//Go to COFF File Header in dll
//that is located after"signature" (4 bytes long)
(os::seek_to_file_offset(file_descriptor,
signature_offset+IMAGE_FILE_SIGNATURE_LENGTH)<0)
||
//Read field that contains code of architecture
// that dll was build for
(sizeof(lib_arch)!=
(os::read(file_descriptor, (void*)&lib_arch,sizeof(lib_arch))))
);
::close(file_descriptor);
if (failed_to_get_lib_arch)
{
// file i/o error - report getLastErrorString(...) msg
return NULL;
}
typedef struct
{
uint16_t arch_code;
char* arch_name;
} arch_t;
static const arch_t arch_array[]={
{IMAGE_FILE_MACHINE_I386, (char*)"IA 32"},
{IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"},
{IMAGE_FILE_MACHINE_IA64, (char*)"IA 64"}
};
#if (defined _M_IA64)
static const uint16_t running_arch=IMAGE_FILE_MACHINE_IA64;
#elif (defined _M_AMD64)
static const uint16_t running_arch=IMAGE_FILE_MACHINE_AMD64;
#elif (defined _M_IX86)
static const uint16_t running_arch=IMAGE_FILE_MACHINE_I386;
#else
#error Method os::dll_load requires that one of following \
is defined :_M_IA64,_M_AMD64 or _M_IX86
#endif
// Obtain a string for printf operation
// lib_arch_str shall contain string what platform this .dll was built for
// running_arch_str shall string contain what platform Hotspot was built for
char *running_arch_str=NULL,*lib_arch_str=NULL;
for (unsigned int i=0;i<ARRAY_SIZE(arch_array);i++)
{
if (lib_arch==arch_array[i].arch_code)
lib_arch_str=arch_array[i].arch_name;
if (running_arch==arch_array[i].arch_code)
running_arch_str=arch_array[i].arch_name;
}
assert(running_arch_str,
"Didn't find runing architecture code in arch_array");
// If the architure is right
// but some other error took place - report getLastErrorString(...) msg
if (lib_arch == running_arch)
{
return NULL;
}
if (lib_arch_str!=NULL)
{
::_snprintf(ebuf, ebuflen-1,
"Can't load %s-bit .dll on a %s-bit platform",
lib_arch_str,running_arch_str);
}
else
{
// don't know what architecture this dll was build for
::_snprintf(ebuf, ebuflen-1,
"Can't load this .dll (machine code=0x%x) on a %s-bit platform",
lib_arch,running_arch_str);
}
return NULL;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.