This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
PATCH: -fomit-frame-pointer and exceptions or setjmp/longjmp
- From: Denis Zaitsev <zzz at cd-club dot ru>
- To: Nix <nix at esperi dot demon dot co dot uk>
- Cc: Richard Henderson <rth at redhat dot com>, gcc at gcc dot gnu dot org
- Date: Tue, 2 Jul 2002 05:08:49 +0600
- Subject: PATCH: -fomit-frame-pointer and exceptions or setjmp/longjmp
- References: <20020603032930.A23158@natasha.zzz.zzz> <20020602151141.A13006@redhat.com> <87fzzuc12b.fsf@amaterasu.srvr.nix> <20020614052419.A6289@natasha.zzz.zzz> <87it4l8z43.fsf@amaterasu.srvr.nix>
The problem (i386): GCC generates bad DWARF call frame info, when it
works with -fomit-frame-pointer, so it becomes impossible to unwind
the call frame correctly. This makes, for example, any thrown
exception uncatchable. (This problem has already been discussed here.)
The place, where the call frame info goes astray, is loading of the
PIC register. It consists of a call for a "just after the call" point
and then pop pc's value there. The call must be considered just as it
would be push(pc), but instead it asumed to be a usual call, which
leaves the stack pointer the same after return. And it is an error.
The patch below cures the problem. Please, apply it. It is for
3.0.4, but does for 3.1 too.
--- gcc/config/i386/i386.c.orig Fri Nov 30 02:48:41 2001
+++ gcc/config/i386/i386.c Tue Jul 2 03:32:29 2002
@@ -1877,7 +1877,7 @@
void
load_pic_register ()
{
- rtx gotsym, pclab;
+ rtx gotsym, pclab, getpc;
gotsym = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
@@ -1892,7 +1892,15 @@
pclab = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
}
- emit_insn (gen_prologue_get_pc (pic_offset_table_rtx, pclab));
+ getpc = emit_insn (gen_prologue_get_pc (pic_offset_table_rtx, pclab));
+ RTX_FRAME_RELATED_P (getpc) = 1;
+ REG_NOTES (getpc) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode,
+ stack_pointer_rtx,
+ gen_rtx_PLUS (SImode,
+ stack_pointer_rtx,
+ GEN_INT (-UNITS_PER_WORD))),
+ REG_NOTES (getpc));
if (! TARGET_DEEP_BRANCH_PREDICTION)
emit_insn (gen_popsi1 (pic_offset_table_rtx));