| 
9 | 9 | 
 
  | 
10 | 10 | package org.elasticsearch.entitlement.qa.test;  | 
11 | 11 | 
 
  | 
 | 12 | +import org.elasticsearch.entitlement.qa.entitled.EntitledPlugin;  | 
 | 13 | + | 
 | 14 | +import java.lang.foreign.AddressLayout;  | 
 | 15 | +import java.lang.foreign.Arena;  | 
 | 16 | +import java.lang.foreign.FunctionDescriptor;  | 
 | 17 | +import java.lang.foreign.Linker;  | 
 | 18 | +import java.lang.foreign.MemoryLayout;  | 
 | 19 | +import java.lang.foreign.MemorySegment;  | 
 | 20 | +import java.lang.foreign.SymbolLookup;  | 
 | 21 | +import java.lang.foreign.ValueLayout;  | 
 | 22 | +import java.lang.invoke.MethodHandle;  | 
 | 23 | +import java.lang.invoke.MethodHandles;  | 
 | 24 | +import java.lang.invoke.MethodType;  | 
 | 25 | +import java.lang.module.Configuration;  | 
 | 26 | +import java.lang.module.ModuleFinder;  | 
 | 27 | +import java.nio.file.Path;  | 
 | 28 | +import java.util.List;  | 
 | 29 | +import java.util.Set;  | 
 | 30 | + | 
 | 31 | +import static java.lang.foreign.ValueLayout.ADDRESS;  | 
 | 32 | +import static java.lang.foreign.ValueLayout.JAVA_LONG;  | 
 | 33 | + | 
12 | 34 | class VersionSpecificNativeChecks {  | 
13 | 35 | 
 
  | 
14 |  | -    static void enableNativeAccess() throws Exception {}  | 
 | 36 | +    static void enableNativeAccess() throws Exception {  | 
 | 37 | +        ModuleLayer parent = ModuleLayer.boot();  | 
 | 38 | + | 
 | 39 | +        var location = EntitledPlugin.class.getProtectionDomain().getCodeSource().getLocation();  | 
 | 40 | + | 
 | 41 | +        // We create a layer for our own module, so we have a controller to try and call enableNativeAccess on it.  | 
 | 42 | +        // This works in both the modular and non-modular case: the target module has to be present in the new layer, but its entitlements  | 
 | 43 | +        // and policies do not matter to us: we are checking that the caller is (or isn't) entitled to use enableNativeAccess  | 
 | 44 | +        Configuration cf = parent.configuration()  | 
 | 45 | +            .resolve(ModuleFinder.of(Path.of(location.toURI())), ModuleFinder.of(), Set.of("org.elasticsearch.entitlement.qa.entitled"));  | 
 | 46 | +        var controller = ModuleLayer.defineModulesWithOneLoader(cf, List.of(parent), ClassLoader.getSystemClassLoader());  | 
 | 47 | +        var targetModule = controller.layer().findModule("org.elasticsearch.entitlement.qa.entitled");  | 
 | 48 | + | 
 | 49 | +        controller.enableNativeAccess(targetModule.get());  | 
 | 50 | +    }  | 
 | 51 | + | 
 | 52 | +    static void addressLayoutWithTargetLayout() {  | 
 | 53 | +        AddressLayout addressLayout = ADDRESS.withoutTargetLayout();  | 
 | 54 | +        addressLayout.withTargetLayout(MemoryLayout.sequenceLayout(Long.MAX_VALUE, ValueLayout.JAVA_BYTE));  | 
 | 55 | +    }  | 
 | 56 | + | 
 | 57 | +    static void linkerDowncallHandle() {  | 
 | 58 | +        Linker linker = Linker.nativeLinker();  | 
 | 59 | +        linker.downcallHandle(FunctionDescriptor.of(JAVA_LONG, ADDRESS));  | 
 | 60 | +    }  | 
 | 61 | + | 
 | 62 | +    static void linkerDowncallHandleWithAddress() {  | 
 | 63 | +        Linker linker = Linker.nativeLinker();  | 
 | 64 | +        linker.downcallHandle(linker.defaultLookup().find("strlen").get(), FunctionDescriptor.of(JAVA_LONG, ADDRESS));  | 
 | 65 | +    }  | 
15 | 66 | 
 
  | 
16 |  | -    static void addressLayoutWithTargetLayout() {}  | 
 | 67 | +    static int callback() {  | 
 | 68 | +        return 0;  | 
 | 69 | +    }  | 
17 | 70 | 
 
  | 
18 |  | -    static void linkerDowncallHandle() {}  | 
 | 71 | +    static void linkerUpcallStub() throws NoSuchMethodException {  | 
 | 72 | +        Linker linker = Linker.nativeLinker();  | 
19 | 73 | 
 
  | 
20 |  | -    static void linkerDowncallHandleWithAddress() {}  | 
 | 74 | +        MethodHandle mh = null;  | 
 | 75 | +        try {  | 
 | 76 | +            mh = MethodHandles.lookup().findStatic(VersionSpecificNativeChecks.class, "callback", MethodType.methodType(int.class));  | 
 | 77 | +        } catch (IllegalAccessException e) {  | 
 | 78 | +            assert false;  | 
 | 79 | +        }  | 
21 | 80 | 
 
  | 
22 |  | -    static void linkerUpcallStub() throws NoSuchMethodException {}  | 
 | 81 | +        FunctionDescriptor callbackDescriptor = FunctionDescriptor.of(ValueLayout.JAVA_INT);  | 
 | 82 | +        linker.upcallStub(mh, callbackDescriptor, Arena.ofAuto());  | 
 | 83 | +    }  | 
23 | 84 | 
 
  | 
24 |  | -    static void memorySegmentReinterpret() {}  | 
 | 85 | +    static void memorySegmentReinterpret() {  | 
 | 86 | +        Arena arena = Arena.ofAuto();  | 
 | 87 | +        MemorySegment segment = arena.allocate(100);  | 
 | 88 | +        segment.reinterpret(50);  | 
 | 89 | +    }  | 
25 | 90 | 
 
  | 
26 |  | -    static void memorySegmentReinterpretWithCleanup() {}  | 
 | 91 | +    static void memorySegmentReinterpretWithCleanup() {  | 
 | 92 | +        Arena arena = Arena.ofAuto();  | 
 | 93 | +        MemorySegment segment = arena.allocate(100);  | 
 | 94 | +        segment.reinterpret(Arena.ofAuto(), s -> {});  | 
 | 95 | +    }  | 
27 | 96 | 
 
  | 
28 |  | -    static void memorySegmentReinterpretWithSizeAndCleanup() {}  | 
 | 97 | +    static void memorySegmentReinterpretWithSizeAndCleanup() {  | 
 | 98 | +        Arena arena = Arena.ofAuto();  | 
 | 99 | +        MemorySegment segment = arena.allocate(100);  | 
 | 100 | +        segment.reinterpret(50, Arena.ofAuto(), s -> {});  | 
 | 101 | +    }  | 
29 | 102 | 
 
  | 
30 |  | -    static void symbolLookupWithPath() {}  | 
 | 103 | +    static void symbolLookupWithPath() {  | 
 | 104 | +        try {  | 
 | 105 | +            SymbolLookup.libraryLookup(Path.of("/foo/bar/libFoo.so"), Arena.ofAuto());  | 
 | 106 | +        } catch (IllegalArgumentException e) {  | 
 | 107 | +            // IllegalArgumentException is thrown if path does not point to a valid library (and it does not)  | 
 | 108 | +        }  | 
 | 109 | +    }  | 
31 | 110 | 
 
  | 
32 |  | -    static void symbolLookupWithName() {}  | 
 | 111 | +    static void symbolLookupWithName() {  | 
 | 112 | +        try {  | 
 | 113 | +            SymbolLookup.libraryLookup("foo", Arena.ofAuto());  | 
 | 114 | +        } catch (IllegalArgumentException e) {  | 
 | 115 | +            // IllegalArgumentException is thrown if path does not point to a valid library (and it does not)  | 
 | 116 | +        }  | 
 | 117 | +    }  | 
33 | 118 | }  | 
0 commit comments