summaryrefslogtreecommitdiff
path: root/jvmfwk
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2014-05-23 00:01:45 +0200
committerMichael Stahl <mstahl@redhat.com>2014-05-23 00:19:31 +0200
commit831c8e02ca4640ddc7fb4966c0026f99b6e6296a (patch)
tree937da6767fe65e95ff248ec23237d19822912398 /jvmfwk
parent6deec9c9106eed60e32450a28323e139bd3ced1f (diff)
jvmfwk: generalize (and fix) the do_msvcr71_magic to Oracle JRE 7
With just the Oracle JRE installed, it is not possible to load the "jvm.dll" directly, because the required MSVC runtime DLL is not found (unless some other software happens to install it system-wide), as described in http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7184978 There was a hack "do_msvcr71_magic" to manually load the runtime that is bundled with Oracle JRE 6 and this generalizes that to work with the MSVCR100.DLL that is bundled with Oracle JRE 7 as well. An additional adaption of the virtual addresses in the file is done, and it's a mystery whether it even worked before without that. This issue was not user-visible before because LO releases 3.5 - 4.2 bundle the MSVCR100.DLL themselves. Change-Id: If61565df80ff8a68472a76000ab5b10d6c78e11c
Diffstat (limited to 'jvmfwk')
-rw-r--r--jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx67
1 files changed, 50 insertions, 17 deletions
diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx
index 266cdc6030d5..ef91401308d1 100644
--- a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx
+++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx
@@ -449,20 +449,20 @@ javaPluginError jfw_plugin_getJavaInfoByPath(
// think it should be, do nothing, and just let the implicit loading
// that happens when loading the JVM take care of it.
-static void load_msvcr71(LPCWSTR jvm_dll)
+static void load_msvcr(LPCWSTR jvm_dll, wchar_t const* msvcr)
{
- wchar_t msvcr71_dll[MAX_PATH];
+ wchar_t msvcr_dll[MAX_PATH];
wchar_t *slash;
if (wcslen(jvm_dll) > MAX_PATH - 15)
return;
- wcscpy(msvcr71_dll, jvm_dll);
+ wcscpy(msvcr_dll, jvm_dll);
// First check if msvcr71.dll is in the same folder as jvm.dll. It
// normally isn't, at least up to 1.6.0_22, but who knows if it
// might be in the future.
- slash = wcsrchr(msvcr71_dll, L'\\');
+ slash = wcsrchr(msvcr_dll, L'\\');
if (!slash)
{
@@ -470,27 +470,27 @@ static void load_msvcr71(LPCWSTR jvm_dll)
return;
}
- wcscpy(slash+1, L"msvcr71.dll");
- if (LoadLibraryW(msvcr71_dll))
+ wcscpy(slash+1, msvcr);
+ if (LoadLibraryW(msvcr_dll))
return;
// Then check if msvcr71.dll is in the parent folder of where
// jvm.dll is. That is currently (1.6.0_22) as far as I know the
// normal case.
*slash = 0;
- slash = wcsrchr(msvcr71_dll, L'\\');
+ slash = wcsrchr(msvcr_dll, L'\\');
if (!slash)
return;
- wcscpy(slash+1, L"msvcr71.dll");
- LoadLibraryW(msvcr71_dll);
+ wcscpy(slash+1, msvcr);
+ LoadLibraryW(msvcr_dll);
}
// Check if the jvm DLL imports msvcr71.dll, and in that case try
// loading it explicitly. In case something goes wrong, do nothing,
// and just let the implicit loading try to take care of it.
-static void do_msvcr71_magic(rtl_uString *jvm_dll)
+static void do_msvcr_magic(rtl_uString *jvm_dll)
{
rtl_uString* Module(0);
struct stat st;
@@ -524,18 +524,51 @@ static void do_msvcr71_magic(rtl_uString *jvm_dll)
IMAGE_NT_HEADERS *nt_hdr = (IMAGE_NT_HEADERS *) ((char *)dos_hdr + dos_hdr->e_lfanew);
+ DWORD importsVA = nt_hdr->OptionalHeader
+ .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
+ // first determine Virtual-to-File-address mapping for the section
+ // that contains the import directory
+ IMAGE_SECTION_HEADER *sections = IMAGE_FIRST_SECTION(nt_hdr);
+ ptrdiff_t VAtoPhys = -1;
+ for (int i = 0; i < nt_hdr->FileHeader.NumberOfSections; ++i)
+ {
+ if (sections->VirtualAddress <= importsVA &&
+ importsVA < sections->VirtualAddress + sections->SizeOfRawData)
+ {
+ VAtoPhys = sections->PointerToRawData - sections->VirtualAddress;
+ break;
+ }
+ ++sections;
+ }
+ if (-1 == VAtoPhys) // not found?
+ {
+ free(dos_hdr);
+ return;
+ }
IMAGE_IMPORT_DESCRIPTOR *imports =
- (IMAGE_IMPORT_DESCRIPTOR *) ((char *) dos_hdr + nt_hdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
+ (IMAGE_IMPORT_DESCRIPTOR *) ((char *) dos_hdr + importsVA + VAtoPhys);
while (imports <= (IMAGE_IMPORT_DESCRIPTOR *) ((char *) dos_hdr + st.st_size - sizeof (IMAGE_IMPORT_DESCRIPTOR)) &&
imports->Name != 0 &&
- imports->Name < (DWORD) st.st_size)
+ imports->Name + VAtoPhys < (DWORD) st.st_size)
{
- // Intentional use of sizeof("msvcr71.dll") here to include the terminating zero byte
- if (strnicmp((char *) dos_hdr + imports->Name, "msvcr71.dll", sizeof("msvcr71.dll")) == 0)
+ static struct { char const * name; wchar_t const * wname; } msvcrts[] =
{
- load_msvcr71(reinterpret_cast<LPCWSTR>(Module->buffer));
- break;
+ { "msvcr71.dll" , L"msvcr71.dll" },
+ { "msvcr100.dll", L"msvcr100.dll" },
+ };
+ char const* importName = (char *) dos_hdr + imports->Name + VAtoPhys;
+ for (size_t i = 0; i < SAL_N_ELEMENTS(msvcrts); ++i)
+ {
+ if (0 == strnicmp(importName,
+ // Intentional strlen() + 1 here to include terminating zero
+ msvcrts[i].name, strlen(msvcrts[i].name) + 1))
+ {
+ load_msvcr(reinterpret_cast<LPCWSTR>(Module->buffer),
+ msvcrts[i].wname);
+ free(dos_hdr);
+ return;
+ }
}
imports++;
}
@@ -584,7 +617,7 @@ javaPluginError jfw_plugin_startJavaVirtualMachine(
SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_NOW)) == 0 )
#else
#if defined(WNT)
- do_msvcr71_magic(sRuntimeLib.pData);
+ do_msvcr_magic(sRuntimeLib.pData);
#endif
if ((moduleRt = osl_loadModule(sRuntimeLib.pData, SAL_LOADMODULE_DEFAULT)) == 0)
#endif