This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix stop condition in dwarf2 execute_cfa_program
- From: Olivier Hainque <hainque at ACT-Europe dot FR>
- To: Jason Merrill <jason at redhat dot com>
- Cc: Richard Henderson <rth at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: 04 Jan 2002 08:49:43 +0100
- Subject: Re: Fix stop condition in dwarf2 execute_cfa_program
- References: <ktn125nzen.fsf@berlin.int.act-europe.fr><wvlr8pnaocf.fsf@prospero.cambridge.redhat.com><ktwuyzoz3u.fsf@berlin.int.act-europe.fr>
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