[M3devel] checking function pointers for null?

Jay K jay.krell at cornell.edu
Tue Jun 22 02:38:37 CEST 2010


Isn't that the cm3cg -y output below?
It's all fairly obvious.
 
 
I looked, I might have the names wrong, but there is a function is_closure in the frontend. It is used by more than just call, e.g. it is used for function pointer comparison. So the "silent null check" is sometimes required, but I think it is dubious for call. (And comparing function pointers to other than null is dubious, and often doesn't "work" in the face of dynamic linking.)
 
 
 - Jay


----------------------------------------
> From: hosking at cs.purdue.edu
> Date: Mon, 21 Jun 2010 17:09:08 -0400
> To: jay.krell at cornell.edu
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] checking function pointers for null?
>
> I want to see the IR.
>
>
> On 21 Jun 2010, at 16:55, Jay K wrote:
>
>>
>> The backend is doing what the front/middle end asks.
>> My original question stands: The check for NULL is worthless, right?
>> Either it should do more: call m3_fault
>> Or it should do less: don't bother checking, let the hardware do it at the call or marker check (the marker check, in reality)
>> ?
>>
>> I can understand the stance that the software does all the checking. That we don't/shouldn't depend on hardware checking.
>> Though that isn't true -- the rationale for "Target.first_readable_address" or such is that hardware checks for NULL deref,
>> and even "small deref" -- anything in the first page at least.
>>
>> But this seems in between -- it avoids the null deref for the marker check but doesn't avoid it for the call.
>> Perhaps there is an idea that the hardware checking is somehow different for data vs. code??
>>
>>
>> MODULE Main;
>>
>> TYPE Function = PROCEDURE ();
>>
>> PROCEDURE C(a:Function) =
>> BEGIN
>> a();
>> END C;
>>
>> BEGIN
>> END Main.
>>
>>
>> (23) begin_procedure
>> procedure Main__C
>> Main__C(24) set_source_line
>> source line 6
>> (25) set_source_line
>> source line 7
>> (26) load
>> type:addr
>> type:addr
>> m3cg_load (M3_CQL02D_a): offset 0x0, convert addr -> addr
>> (27) declare_temp
>> type:addr
>> temp var type:addr size:0x40 alignment:0x40
>> (28) store
>> type:addr
>> type:addr
>> store (noname) offset:0x0 src_t:addr dst_t:addr
>> (29) start_call_indirect
>> type:void
>> start call procedure indirect type:void
>> (30) load
>> type:addr
>> type:addr
>> m3cg_load (noname): offset 0x0, convert addr -> addr
>> (31) load_nil ***
>> (32) if_eq ***
>> type:addr
>> label 1
>> (33) load
>> type:addr
>> type:addr
>> m3cg_load (noname): offset 0x0, convert addr -> addr
>> (34) load_indirect
>> type:int64
>> type:int64
>> load address offset:0x0 src_t:int64 dst_t:int64
>> (35) load_integer
>> type:int64
>> integer i:0xfe n_bytes:0x1 0x00000000000000001 sign -1
>> (36) if_ne
>> type:int64
>> label 1
>> (37) set_label
>> label 2
>> (38) load
>> type:addr
>> type:addr
>> m3cg_load (noname): offset 0x0, convert addr -> addr
>> (39) load_indirect
>> type:addr
>> type:addr
>> load address offset:0x80 src_t:addr dst_t:addr
>> (40) pop_static_link
>> (41) load
>> type:addr
>> type:addr
>> m3cg_load (noname): offset 0x0, convert addr -> addr
>> (42) load_indirect
>> type:addr
>> type:addr
>> load address offset:0x40 src_t:addr dst_t:addr
>> (43) store
>> type:addr
>> type:addr
>> store (noname) offset:0x0 src_t:addr dst_t:addr
>> (44) set_label
>> label 1
>> (45) load
>> type:addr
>> type:addr
>> m3cg_load (noname): offset 0x0, convert addr -> addr
>> (46) call_indirect
>> type:void
>> call procedure indirect type:void
>> (47) set_source_line
>> source line 8
>> (48) exit_proc
>> type:void
>> (49) free_temp
>> (50) end_procedure
>> procedure Main__C
>>
>> - Jay
>>
>>
>> ________________________________
>>> From: jay.krell at cornell.edu
>>> To: hosking at cs.purdue.edu
>>> CC: m3devel at elegosoft.com
>>> Subject: RE: [M3devel] checking function pointers for null?
>>> Date: Mon, 21 Jun 2010 17:47:48 +0000
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> Neither backend would add these checks themself, it is m3cg, IR later.
>>>
>>>> Subject: Re: [M3devel] checking function pointers for null?
>>>> From: hosking at cs.purdue.edu
>>>> Date: Mon, 21 Jun 2010 10:26:31 -0400
>>>> CC: m3devel at elegosoft.com
>>>> To: jay.krell at cornell.edu
>>>>
>>>> Is this code from M3CG or the Windows native backend?
>>>>
>>>> If from M3CG perhaps you can show us the M3CG IR code.
>>>>
>>>> On 21 Jun 2010, at 03:55, Jay K wrote:
>>>>
>>>>>
>>>>> This is code that calls a function pointer:
>>>>>
>>>>>
>>>>> testq %rbx, %rbx ; test function pointer for null
>>>>> je L6
>>>>> cmpq $-1, (%rbx) ; check for closure marker
>>>>> jne L6 ; if not a closure, goto L6
>>>>> movq 16(%rbx), %r13 ; r13=static chain (ought to use r10?)
>>>>> movq 8(%rbx), %rax ; rax=actual function pointer
>>>>> jmp L8
>>>>> L6:
>>>>> movq %rbx, %rax ; rax=actual function pointer
>>>>> L8:
>>>>> movq %r13, %r10 ; r10=static chain (it should have just used r10 in the first place? or is r13 otherwise the previous static chain?)
>>>>> call *%rax
>>>>>
>>>>>
>>>>> What is the point of the initial testq/je, if we are just going to jump to the address anyway?
>>>>> Should we do something else if in fact the function pointer is null? Or just let a jump to null fail as it will?
>>>>> You know -- it seems me we should do either more or less here.
>>>>> More: report a null deref by calling m3_fault
>>>>> Less: remove the null check
>>>>>
>>>>>
>>>>> - Jay
>>>>>
>>>>
>>
> 		 	   		  


More information about the M3devel mailing list