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