[M3devel] checking function pointers for null?

Jay K jay.krell at cornell.edu
Mon Jun 21 22:55:06 CEST 2010


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