[M3devel] checking function pointers for null?
Tony Hosking
hosking at cs.purdue.edu
Mon Jun 21 23:09:08 CEST 2010
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