[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