diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-03-09 21:11:53 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-03-09 21:11:53 +0100 |
commit | 8325c9b804e4165308944bf947100625603a9486 (patch) | |
tree | ab7572bf283d52e87e2f0464a7c644b796abb31b /gcc | |
parent | eb1fcdaa11c571780374065c383708826624f22d (diff) | |
download | gcc-8325c9b804e4165308944bf947100625603a9486.zip gcc-8325c9b804e4165308944bf947100625603a9486.tar.gz gcc-8325c9b804e4165308944bf947100625603a9486.tar.bz2 |
re PR debug/43293 (Invalid unwind info for i?86 -fpic)
PR debug/43293
* config/i386/t-i386 (i386.o): Depend on debug.h and dwarf2out.h.
* config/i386/i386.c: Include debug.h and dwarf2out.h.
(ix86_file_end): If dwarf2out_do_cfi_asm (), emit .cfi_startproc
and .cfi_endproc around the pic thunks.
(output_set_got): For TARGET_DEEP_BRANCH_PREDICTION pic, ensure
all queued unwind info register saves are saved before the call.
For !TARGET_DEEP_BRANCH_PREDICTION pic, ensure the call is
considered as sp-=4 for unwind info and the pop as sp+=4 which
also clobbers dest, but doesn't actually restore it.
From-SVN: r157325
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/i386/i386.c | 67 | ||||
-rw-r--r-- | gcc/config/i386/t-i386 | 2 |
2 files changed, 66 insertions, 3 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index ab242a6..087c30f 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -53,6 +53,8 @@ along with GCC; see the file COPYING3. If not see #include "tm-constrs.h" #include "params.h" #include "cselib.h" +#include "debug.h" +#include "dwarf2out.h" static rtx legitimize_dllimport_symbol (rtx, bool); @@ -7584,6 +7586,9 @@ ix86_file_end (void) for (regno = 0; regno < 8; ++regno) { char name[32]; +#ifdef DWARF2_UNWIND_INFO + bool do_cfi; +#endif if (! ((pic_labels_used >> regno) & 1)) continue; @@ -7629,10 +7634,19 @@ ix86_file_end (void) ASM_OUTPUT_LABEL (asm_out_file, name); } +#ifdef DWARF2_UNWIND_INFO + do_cfi = dwarf2out_do_cfi_asm (); + if (do_cfi) + fprintf (asm_out_file, "\t.cfi_startproc\n"); +#endif xops[0] = gen_rtx_REG (Pmode, regno); xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx); output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops); output_asm_insn ("ret", xops); +#ifdef DWARF2_UNWIND_INFO + if (do_cfi) + fprintf (asm_out_file, "\t.cfi_endproc\n"); +#endif } if (NEED_INDICATE_EXEC_STACK) @@ -7673,7 +7687,24 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED) if (!flag_pic) output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops); else - output_asm_insn ("call\t%a2", xops); + { + output_asm_insn ("call\t%a2", xops); +#ifdef DWARF2_UNWIND_INFO + /* The call to next label acts as a push. */ + if (dwarf2out_do_frame ()) + { + rtx insn; + start_sequence (); + insn = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, + gen_rtx_PLUS (Pmode, + stack_pointer_rtx, + GEN_INT (-4)))); + RTX_FRAME_RELATED_P (insn) = 1; + dwarf2out_frame_debug (insn, true); + end_sequence (); + } +#endif + } #if TARGET_MACHO /* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This @@ -7686,7 +7717,27 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED) CODE_LABEL_NUMBER (XEXP (xops[2], 0))); if (flag_pic) - output_asm_insn ("pop%z0\t%0", xops); + { + output_asm_insn ("pop%z0\t%0", xops); +#ifdef DWARF2_UNWIND_INFO + /* The pop is a pop and clobbers dest, but doesn't restore it + for unwind info purposes. */ + if (dwarf2out_do_frame ()) + { + rtx insn; + start_sequence (); + insn = emit_insn (gen_rtx_SET (VOIDmode, dest, const0_rtx)); + dwarf2out_frame_debug (insn, true); + insn = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, + gen_rtx_PLUS (Pmode, + stack_pointer_rtx, + GEN_INT (4)))); + RTX_FRAME_RELATED_P (insn) = 1; + dwarf2out_frame_debug (insn, true); + end_sequence (); + } +#endif + } } else { @@ -7694,6 +7745,18 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED) get_pc_thunk_name (name, REGNO (dest)); pic_labels_used |= 1 << REGNO (dest); +#ifdef DWARF2_UNWIND_INFO + /* Ensure all queued register saves are flushed before the + call. */ + if (dwarf2out_do_frame ()) + { + rtx insn; + start_sequence (); + insn = emit_barrier (); + end_sequence (); + dwarf2out_frame_debug (insn, false); + } +#endif xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); xops[2] = gen_rtx_MEM (QImode, xops[2]); output_asm_insn ("call\t%X2", xops); diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386 index 55ddd1e..ba3b4e4 100644 --- a/gcc/config/i386/t-i386 +++ b/gcc/config/i386/t-i386 @@ -23,7 +23,7 @@ i386.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RECOG_H) $(EXPR_H) $(OPTABS_H) toplev.h $(BASIC_BLOCK_H) \ $(GGC_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h $(CGRAPH_H) \ $(TREE_GIMPLE_H) $(DWARF2_H) $(DF_H) tm-constrs.h $(PARAMS_H) \ - i386-builtin-types.inc + i386-builtin-types.inc debug.h dwarf2out.h i386-c.o: $(srcdir)/config/i386/i386-c.c \ $(srcdir)/config/i386/i386-protos.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \ |