This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fix stop condition in dwarf2 execute_cfa_program



Olivier Hainque <hainque@ACT-Europe.FR> writes:
>  The confusion came from a misunderstanding of what the state we have after a
>  sequence like "Advance Location - Update State" is.
> 
>  IIUC, the state is the one after the effects of the code at the new location
>  and not the one in effect when the new location is reached (which is what I
>  initially thought after a first look at the code and at the standard draft).

Doh! Examining the case again this morning after a bit of sleep, I realized it
is actually just the other way around, so the patch may not be that wrong.

Sorry for the confusion, though it at least made the point more explicit :)

Let's look at a simple case to illustrate and discuss further :

     void
     f_with_noreturn (int x, int y)
          __attribute__ ((__noreturn__));

     void
     f_with_noreturn (int x, int y)
     {
       exit (0);
     }

     void
     f_without_noreturn (int x, int y)
     {
     }

     void
     caller (void)
     {
       f_without_noreturn (1, 2);
       f_with_noreturn (1, 2);
     }

The output for "caller" with 
  -fexceptions -fomit-frame-pointer -mno-accumulate-outgoing-args -dA

reads :

     caller:
     .LFB3:
             # basic block 0
             subl	$12, %esp
     .LCFI4:
             subl	$8, %esp
     .LCFI5:
             pushl	$2
     .LCFI6:
             pushl	$1
     .LCFI7:
             call	f_without_noreturn
             addl	$16, %esp
     .LCFI8:
             subl	$8, %esp
     .LCFI9:
             pushl	$2
     .LCFI10:
             pushl	$1
     .LCFI11:
             call	f_with_noreturn
     .LCFI12:
     .LFE3:
     .Lfe3:

We indeed see the absence of stack adjustment after the second call. Now, as
suggested by Jason, the unwind table reads :

[...]
	.byte	0x4	# DW_CFA_advance_loc4
	.long	.LCFI11-.LCFI10
	.byte	0xe	# DW_CFA_def_cfa_offset
	.uleb128 0x20
	.byte	0x2e	# DW_CFA_GNU_args_size
	.uleb128 0x10

=> Up to before the call, we have 16 bytes of args and the cfa is sp+32,
   with 32 = 4 (entry cfa offset) + 12 (allocated frame) + 16 (arguments).

   Then we have :

	.byte	0x4	# DW_CFA_advance_loc4
	.long	.LCFI12-.LCFI11
	.byte	0xe	# DW_CFA_def_cfa_offset
	.uleb128 0x10
	.byte	0x2e	# DW_CFA_GNU_args_size
	.uleb128 0x0

   Which says "at .LCFI12 (return address), we have 0 bytes of args and the
   cfa is sp+16 (4 + 12).

   This is indeed wrong as the arguments pop has not been done because the
   call is said never to return.

   As it's easy to misunderstand things, I prefer to ask what might be a silly
   question : why do we need the unwind information adjustment here, basically
   "pretending" the code did something when it actually did not ?

 Olivier
   


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]