RFE: support safely wrapping restricted FFM calls
Kasper Nielsen
kasperni at gmail.com
Sun Nov 19 09:38:05 UTC 2023
Hi Rob,
In that case maybe just have an interface users of your library must
implement with all the relevant caller sensitive methods?
And then require the user to specify an instance whenever they call
into your library?
If you need to set up some static data structures this would probably
not be ideal though.
/Kasper
/Kasper
On Sat, 18 Nov 2023 at 15:00, Rob Spoor <openjdk at icemanx.nl> wrote:
>
> On 18/11/2023 06:46, Kasper Nielsen wrote:
> > Hi Rob,
> >
> > Delegating caller sensitive methods can be tricky.
> >
> > Besides the obvious solutions with StackWalker and/or Lookup objects I've
> > sometimes used an abstract class that must be extended by users of my library.
> > This may be more trouble in your case than the other solutions though.
> >
> > In your situation it would be something like this.
> >
> > // Defined in your library and extendable by users of your library
> > public abstract class NativeLoader {
> >
> > protected abstract MethodHandle downcallHandle(Linker linker, MemorySegment
> > address, FunctionDescriptor function, Linker.Option... options);
> >
> > public final <T> T load(Class<T> interFace) {
> > .. do stuff.
> > call this.downcallHandle
> > .. do more stuff
> > }
> > }
> >
> > // Usage by other library
> > class UsageByOtherLibrary {
> > private static final NativeLoader NL = new NativeLoader() {
> > protected MethodHandle downcallHandle(Linker linker, MemorySegment
> > address, FunctionDescriptor function, Option... options) {
> > return linker.downcallHandle(address, function, options);
> > }
> > };
> >
> > public void main() {
> > SomeInterface si = NL.load(SomeInterface.class);
> > }
> > }
> >
> > The actual call to Linker.downcallHandle is now only performed by the user of
> > your library. So depending on what you do, you might even be able to avoid
> > requiring enabling native access for your library. Only the libraries that use
> > your library would need it.
> >
> > /Kasper
>
> Hi Kasper,
>
> This would indeed be relatively easiy if Linker.downcallHandle was the
> only native call, but I've already used AddressLayout.withTargetLayout,
> and just had to add a call to MemorySegment.reinterpret for the
> MemorySegment an AddressLayout was referring to (the result of a native
> call like malloc). Such custom implementations would need to be passed
> around several method calls of my module. Still, this is something to
> consider, as it does take away restricted calls away from my module to
> the caller. Thanks for the hint!
>
> Rob
>
>
> >
> >
> >
> >
> > On Thu, 16 Nov 2023 at 19:21, Rob Spoor <openjdk at icemanx.nl> wrote:
> >>
> >> On 16/11/2023 18:15, Maurizio Cimadamore wrote:
> >>>
> >>> On 16/11/2023 16:54, Rob Spoor wrote:
> >>>> Hi Maurizio,
> >>>>
> >>>> I don't think you understand what my module is doing. For instance,
> >>>> it's not specifying the downcall method handles themselves, it's just
> >>>> making it easy to define them. Maybe a small example would show what
> >>>> I'm doing.
> >>>>
> >>>> Consider the following partial interface from JNA:
> >>>>
> >>>> public interface Kernel32 extends StdCallLibrary, WinNT, Wincon {
> >>>>
> >>>> /** The instance. */
> >>>> Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class,
> >>>> W32APIOptions.DEFAULT_OPTIONS);
> >>>>
> >>>> int GetLastError();
> >>>> }
> >>>>
> >>>> What JNA is doing is creating an implementation based on this
> >>>> interface that delegates to the native kernel32 library. This is all
> >>>> done through the Native.load method.
>
More information about the core-libs-dev
mailing list