Skip to content

Commit 69fc2f4

Browse files
committed
Fix library loading from Unicode paths on Windows
1 parent 14abd91 commit 69fc2f4

File tree

4 files changed

+52
-13
lines changed

4 files changed

+52
-13
lines changed

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsNativeLibrarySupport.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
import java.io.FileDescriptor;
2828

29-
import org.graalvm.nativeimage.c.type.CCharPointer;
3029
import org.graalvm.nativeimage.c.type.CTypeConversion;
3130
import org.graalvm.nativeimage.c.type.CTypeConversion.CCharPointerHolder;
3231
import org.graalvm.word.PointerBase;
@@ -42,10 +41,12 @@
4241
import com.oracle.svm.core.jdk.NativeLibrarySupport;
4342
import com.oracle.svm.core.jdk.PlatformNativeLibrarySupport;
4443
import com.oracle.svm.core.log.Log;
44+
import com.oracle.svm.core.windows.WindowsUtils.WCharPointerHolder;
4545
import com.oracle.svm.core.windows.headers.FileAPI;
4646
import com.oracle.svm.core.windows.headers.LibLoaderAPI;
4747
import com.oracle.svm.core.windows.headers.WinBase.HMODULE;
4848
import com.oracle.svm.core.windows.headers.WinSock;
49+
import com.oracle.svm.core.windows.headers.WindowsLibC.WCharPointer;
4950

5051
import jdk.graal.compiler.word.Word;
5152

@@ -166,13 +167,9 @@ private boolean doLoad() {
166167
return true;
167168
}
168169
assert dlhandle.isNull();
169-
try (CCharPointerHolder dllPathPin = CTypeConversion.toCString(canonicalIdentifier)) {
170-
CCharPointer dllPathPtr = dllPathPin.get();
171-
/*
172-
* WinBase.SetDllDirectoryA(dllpathPtr); CCharPointerHolder pathPin =
173-
* CTypeConversion.toCString(path); CCharPointer pathPtr = pathPin.get();
174-
*/
175-
dlhandle = LibLoaderAPI.LoadLibraryA(dllPathPtr);
170+
try (WCharPointerHolder dllPathPin = WindowsUtils.toWideCString(canonicalIdentifier)) {
171+
WCharPointer dllPathPtr = dllPathPin.get();
172+
dlhandle = LibLoaderAPI.LoadLibraryW(dllPathPtr);
176173
}
177174
return dlhandle.isNonNull();
178175
}

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsUtils.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@
4747
import com.oracle.svm.core.annotate.TargetClass;
4848
import com.oracle.svm.core.c.function.CEntryPointActions;
4949
import com.oracle.svm.core.graal.stackvalue.UnsafeStackValue;
50+
import com.oracle.svm.core.handles.PrimitiveArrayView;
5051
import com.oracle.svm.core.util.BasedOnJDKFile;
5152
import com.oracle.svm.core.windows.headers.FileAPI;
5253
import com.oracle.svm.core.windows.headers.LibLoaderAPI;
5354
import com.oracle.svm.core.windows.headers.WinBase;
5455
import com.oracle.svm.core.windows.headers.WinBase.HANDLE;
5556
import com.oracle.svm.core.windows.headers.WinBase.HMODULE;
57+
import com.oracle.svm.core.windows.headers.WindowsLibC.WCharPointer;
5658

5759
import jdk.graal.compiler.word.Word;
5860

@@ -232,4 +234,43 @@ private static HMODULE getDLLHandle(CCharPointer dllName) {
232234
}
233235
return dllHandle;
234236
}
237+
238+
/**
239+
* Returns a holder that exposes a {@linkplain WCharPointer WCharPointer} to a null-terminated
240+
* wide C string created from the given Java String.
241+
*/
242+
public static WCharPointerHolder toWideCString(String javaString) {
243+
assert javaString != null;
244+
return new WCharPointerHolder(javaString);
245+
}
246+
247+
/**
248+
* Holder for a null-terminated wide C string. The exposed {@linkplain WCharPointer
249+
* WCharPointer} remains valid only while this holder is open.
250+
*/
251+
public static final class WCharPointerHolder implements AutoCloseable {
252+
private final PrimitiveArrayView wideCString;
253+
254+
private WCharPointerHolder(String javaString) {
255+
/*
256+
* Windows wide C strings use UTF-16LE, matching Java char[]. So we add a trailing NUL
257+
* and then reinterpret the Java char[] as a wchar_t[].
258+
*/
259+
int length = javaString.length();
260+
char[] chars = new char[length + 1]; // trailing NUL
261+
javaString.getChars(0, length, chars, 0);
262+
wideCString = PrimitiveArrayView.createForReading(chars);
263+
}
264+
265+
/** Returns the pointer to the null-terminated wide C string. */
266+
public WCharPointer get() {
267+
return wideCString.addressOfArrayElement(0);
268+
}
269+
270+
/** Invalidates the pointer. */
271+
@Override
272+
public void close() {
273+
wideCString.close();
274+
}
275+
}
235276
}

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/headers/LibLoaderAPI.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ public class LibLoaderAPI {
7575

7676
/** Loads the specified module into the address space of the calling process. */
7777
@CFunction(transition = NO_TRANSITION)
78-
public static native HMODULE LoadLibraryA(CCharPointer lpLibFileName);
78+
public static native HMODULE LoadLibraryW(WCharPointer lpLibFileName);
7979

8080
/** Loads the specified module into the address space of the calling process. */
8181
@CFunction(transition = NO_TRANSITION)
82-
public static native HMODULE LoadLibraryExA(CCharPointer lpLibFileName, HANDLE hFile, int dwFlags);
82+
public static native HMODULE LoadLibraryExW(WCharPointer lpLibFileName, HANDLE hFile, int dwFlags);
8383
}

substratevm/src/com.oracle.svm.truffle.nfi.windows/src/com/oracle/svm/truffle/nfi/windows/WindowsTruffleNFIFeature.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package com.oracle.svm.truffle.nfi.windows;
2626

27-
import jdk.graal.compiler.word.Word;
2827
import org.graalvm.nativeimage.ImageSingletons;
2928
import org.graalvm.nativeimage.Platform;
3029
import org.graalvm.nativeimage.c.type.CCharPointer;
@@ -44,6 +43,8 @@
4443
import com.oracle.truffle.api.CompilerDirectives;
4544
import com.oracle.truffle.api.exception.AbstractTruffleException;
4645

46+
import jdk.graal.compiler.word.Word;
47+
4748
public final class WindowsTruffleNFIFeature implements InternalFeature {
4849

4950
@Override
@@ -75,8 +76,8 @@ protected CCharPointer strdupImpl(CCharPointer src) {
7576
protected long loadLibraryImpl(long nativeContext, String name, int flags) {
7677
String dllPath = name;
7778
HMODULE dlhandle;
78-
try (CTypeConversion.CCharPointerHolder dllpathPin = CTypeConversion.toCString(dllPath)) {
79-
dlhandle = LibLoaderAPI.LoadLibraryExA(dllpathPin.get(), Word.nullPointer(), flags);
79+
try (WindowsUtils.WCharPointerHolder dllpathPin = WindowsUtils.toWideCString(dllPath)) {
80+
dlhandle = LibLoaderAPI.LoadLibraryExW(dllpathPin.get(), Word.nullPointer(), flags);
8081
}
8182
if (dlhandle.isNull()) {
8283
CompilerDirectives.transferToInterpreter();

0 commit comments

Comments
 (0)