Generic (void *)int
Jorn Vernee
jbvernee at xs4all.nl
Mon Feb 18 11:42:19 UTC 2019
> I think we can limit the damage if we add an API for creating pointers
> from literals, but don't make them dereferencable on the Java side,
> e.g. by using MemoryBoundInfo.NOTHING or References.OfGrumpy. Then
> users can only shoot themselves in the foot when passing the created
> pointer to a native function, which is already a foot-shooty situation
> any ways.
Actually, I guess you could also shoot yourself in the foot by setting
and getting the pointer from somewhere, since the pointer gets re-boxed
(losing the not-dereferencable attribute), so that would be a security
problem any ways.
Jorn
Jorn Vernee schreef op 2019-02-18 12:38:
> Maurizio Cimadamore schreef op 2019-02-18 12:24:
>> Hi Giuseppe,
>> To generalize Jorn's trick, you can write a generic method like this:
>>
>> Pointer<?> makePointer(Scope sc, long value) {
>> return
>> sc.allocate(NativeType.VOID).set(value).cast(NativeTypes.VOID).cast(NativeTypes.VOID.pointer()).get();
>>
>> }
>>
>> I think this does what you want.
>>
>> As Jorn said, this is not 100% the same as in C code - as this will
>> actually allocate a pointer to long, set the long to the desired
>> value, then view it as pointer to pointer to void (so that the desired
>> value will be used as an address).
>>
>>
>> While an API can be added for this, we must also thread carefully -
>> there's a balance here between allowing common C idioms and safety -
>> if we make it too easy to create pointers to 'random' addresses, we
>> also make it easy for people to shoot themselves in the foot.
>
> I think this is mostly used to pass special values where a pointer is
> expected. The boxing code can handle the special values coming from
> native code already, so the hope is that there is a C API for
> retrieving a pointer with a special value in the library already.
>
> Though, jextract can not handle all such cases yet. For instance, the
> Windows registry API uses these declaration for root registry keys:
>
> #define HKEY_CLASSES_ROOT (( HKEY )
> (ULONG_PTR)((LONG)0x80000000) )
> #define HKEY_CURRENT_USER (( HKEY )
> (ULONG_PTR)((LONG)0x80000001) )
> #define HKEY_LOCAL_MACHINE (( HKEY )
> (ULONG_PTR)((LONG)0x80000002) )
> #define HKEY_USERS (( HKEY )
> (ULONG_PTR)((LONG)0x80000003) )
> #define HKEY_PERFORMANCE_DATA (( HKEY )
> (ULONG_PTR)((LONG)0x80000004) )
> #define HKEY_PERFORMANCE_TEXT (( HKEY )
> (ULONG_PTR)((LONG)0x80000050) )
> #define HKEY_PERFORMANCE_NLSTEXT (( HKEY )
> (ULONG_PTR)((LONG)0x80000060) )
> #if (WINVER >= 0x0400)
> #define HKEY_CURRENT_CONFIG (( HKEY )
> (ULONG_PTR)((LONG)0x80000005) )
> #define HKEY_DYN_DATA (( HKEY )
> (ULONG_PTR)((LONG)0x80000006) )
> #define HKEY_CURRENT_USER_LOCAL_SETTINGS (( HKEY )
> (ULONG_PTR)((LONG)0x80000007) )
>
> But, these get omitted from the final binary, presumably since the
> value is not constant. (FWIW, a warning about that would be nice to
> have as well)
>
> I think we can limit the damage if we add an API for creating pointers
> from literals, but don't make them dereferencable on the Java side,
> e.g. by using MemoryBoundInfo.NOTHING or References.OfGrumpy. Then
> users can only shoot themselves in the foot when passing the created
> pointer to a native function, which is already a foot-shooty situation
> any ways.
>
> One of the questions is; to what Scope do these literals belong? Do we
> allow users to pass in a Scope? I think with the assumption that
> "pointer literals are just special values", it makes sense to have
> their Scope just be null, since no actual memory is managed.
>
> Jorn
>
>> Also, in terms of API evolution, we should refrain from thinking that
>> pointer === address; there might be pointers (such as heap pointers)
>> whose notion of 'address' is more blurry. An heap pointer expresses
>> its address a pair of base Object + offset, so just creating a pointer
>> out of thin air with a long won't work there.
>>
>> Maurizio
>>
>>
>> On 18/02/2019 09:56, Jorn Vernee wrote:
>>> Hi Giuseppe,
>>>
>>> You should be able to use this trick:
>>>
>>> long pointerValue = 12L; // e.g.
>>> Scope scope = Scope.newNativeScope; // or
>>> Scope.globalScope().fork() depending on which version you are
>>> Pointer<Long> ptr = scope.allocate(NativeTypes.UINT64);
>>> ptr.set(pointerValue);
>>> Pointer<?> result =
>>> ptr.cast(NativeTypes.VOID).cast(NativeTypes.VOID.pointer()).get();
>>> // use 'result'
>>>
>>> Be aware that this does do an allocation of a 64 bit int, so you
>>> might want to reuse the allocated space if you create a lot of
>>> pointers from literals.
>>>
>>> Maybe in the future we can add an API for creating pointers from long
>>> literals directly.
>>>
>>> Jorn
>>>
>>> Giuseppe Barbieri schreef op 2019-02-18 10:44:
>>>> Thanks Sundar,
>>>>
>>>> that works flawless for `(void *)0`
>>>>
>>>> But now I also would need a generic solution, for example:
>>>>
>>>> (void *)12
>>>>
>>>> There is a sill opengl call ( glVertexPointer ) requesting
>>>> explicitely
>>>> that: https://stackoverflow.com/a/8283855/1047713
>>>>
>>>> Signature:
>>>>
>>>> void glVertexAttribPointer(int index, int size, int type, byte
>>>> normalized, int stride, Pointer<?> pointer);
>>>>
>>>>
>>>> is there actually a way?
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> You can use Pointer.nullPointer() method.
>>>>
>>>> -Sundar
>>>>
>>>> On 18/02/19, 8:09 AM, Giuseppe Barbieri wrote:
>>>>> Hi,
>>>>>
>>>>> I'm looking for a way to convert this:
>>>>>
>>>>> (void*)0
>>>>>
>>>>> in Java.
>>>>>
>>>>> I tried to allocate a pointer and set its value to 0, but it didnt
>>>>> work
>>>>>
>>>>> Any ideas, guys?
>>>>>
>>>>> Thanks in advance
More information about the panama-dev
mailing list