From 26fc730dd2b04a718f12ea5ba0aa7a8737cc513e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 19 Jan 2018 23:36:04 +0100 Subject: [PATCH] re PR debug/81570 (create_pseudo_cfg assumes that INCOMING_FRAME_SP_OFFSET is a constant) PR debug/81570 PR debug/83728 * dwarf2cfi.c (DEFAULT_INCOMING_FRAME_SP_OFFSET): Define to INCOMING_FRAME_SP_OFFSET if not defined. (scan_trace): Add ENTRY argument. If true and DEFAULT_INCOMING_FRAME_SP_OFFSET != INCOMING_FRAME_SP_OFFSET, emit a note to adjust the CFA offset. (create_cfi_notes): Adjust scan_trace callers. (create_cie_data): Use DEFAULT_INCOMING_FRAME_SP_OFFSET rather than INCOMING_FRAME_SP_OFFSET in the CIE. * config/i386/i386.h (DEFAULT_INCOMING_FRAME_SP_OFFSET): Define. * config/stormy16/stormy16.h (DEFAULT_INCOMING_FRAME_SP_OFFSET): Likewise. * doc/tm.texi.in (DEFAULT_INCOMING_FRAME_SP_OFFSET): Document. * doc/tm.texi: Regenerated. From-SVN: r256904 --- gcc/ChangeLog | 18 ++++++++++++++++++ gcc/config/i386/i386.h | 4 ++++ gcc/config/stormy16/stormy16.h | 1 + gcc/doc/tm.texi | 9 +++++++++ gcc/doc/tm.texi.in | 9 +++++++++ gcc/dwarf2cfi.c | 28 ++++++++++++++++++++++++---- 6 files changed, 65 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8bffc6627d7..bd3c00361f1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2018-01-19 Jakub Jelinek + + PR debug/81570 + PR debug/83728 + * dwarf2cfi.c (DEFAULT_INCOMING_FRAME_SP_OFFSET): Define to + INCOMING_FRAME_SP_OFFSET if not defined. + (scan_trace): Add ENTRY argument. If true and + DEFAULT_INCOMING_FRAME_SP_OFFSET != INCOMING_FRAME_SP_OFFSET, + emit a note to adjust the CFA offset. + (create_cfi_notes): Adjust scan_trace callers. + (create_cie_data): Use DEFAULT_INCOMING_FRAME_SP_OFFSET rather than + INCOMING_FRAME_SP_OFFSET in the CIE. + * config/i386/i386.h (DEFAULT_INCOMING_FRAME_SP_OFFSET): Define. + * config/stormy16/stormy16.h (DEFAULT_INCOMING_FRAME_SP_OFFSET): + Likewise. + * doc/tm.texi.in (DEFAULT_INCOMING_FRAME_SP_OFFSET): Document. + * doc/tm.texi: Regenerated. + 2018-01-19 Andreas Krebbel PR rtl-optimization/83147 diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index bc4bc9a7a48..59522ccba02 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2110,6 +2110,10 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER]; (cfun->machine->func_type == TYPE_EXCEPTION \ ? 2 * UNITS_PER_WORD : UNITS_PER_WORD) +/* The value of INCOMING_FRAME_SP_OFFSET the assembler assumes in + .cfi_startproc. */ +#define DEFAULT_INCOMING_FRAME_SP_OFFSET UNITS_PER_WORD + /* Describe how we implement __builtin_eh_return. */ #define EH_RETURN_DATA_REGNO(N) ((N) <= DX_REG ? (N) : INVALID_REGNUM) #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, CX_REG) diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h index 715e05d139d..4667d8d96dc 100644 --- a/gcc/config/stormy16/stormy16.h +++ b/gcc/config/stormy16/stormy16.h @@ -228,6 +228,7 @@ enum reg_class #define INCOMING_FRAME_SP_OFFSET (xstormy16_interrupt_function_p () ? -6 : -4) +#define DEFAULT_INCOMING_FRAME_SP_OFFSET -4 /* Register That Address the Stack Frame. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 7f02b0d1708..2f317b5a368 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3168,6 +3168,15 @@ You only need to define this macro if you want to support call frame debugging information like that provided by DWARF 2. @end defmac +@defmac DEFAULT_INCOMING_FRAME_SP_OFFSET +Like @code{INCOMING_FRAME_SP_OFFSET}, but must be the same for all +functions of the same ABI, and when using GAS @code{.cfi_*} directives +must also agree with the default CFI GAS emits. Define this macro +only if @code{INCOMING_FRAME_SP_OFFSET} can have different values +between different functions of the same ABI or when +@code{INCOMING_FRAME_SP_OFFSET} does not agree with GAS default CFI. +@end defmac + @defmac ARG_POINTER_CFA_OFFSET (@var{fundecl}) A C expression whose value is an integer giving the offset, in bytes, from the argument pointer to the canonical frame address (cfa). The diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 90c24beee88..2a42038829d 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -2559,6 +2559,15 @@ You only need to define this macro if you want to support call frame debugging information like that provided by DWARF 2. @end defmac +@defmac DEFAULT_INCOMING_FRAME_SP_OFFSET +Like @code{INCOMING_FRAME_SP_OFFSET}, but must be the same for all +functions of the same ABI, and when using GAS @code{.cfi_*} directives +must also agree with the default CFI GAS emits. Define this macro +only if @code{INCOMING_FRAME_SP_OFFSET} can have different values +between different functions of the same ABI or when +@code{INCOMING_FRAME_SP_OFFSET} does not agree with GAS default CFI. +@end defmac + @defmac ARG_POINTER_CFA_OFFSET (@var{fundecl}) A C expression whose value is an integer giving the offset, in bytes, from the argument pointer to the canonical frame address (cfa). The diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index 3ae5b8e894f..07e6a5a2887 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -52,6 +52,10 @@ along with GCC; see the file COPYING3. If not see #ifndef INCOMING_RETURN_ADDR_RTX #define INCOMING_RETURN_ADDR_RTX (gcc_unreachable (), NULL_RTX) #endif + +#ifndef DEFAULT_INCOMING_FRAME_SP_OFFSET +#define DEFAULT_INCOMING_FRAME_SP_OFFSET INCOMING_FRAME_SP_OFFSET +#endif /* A collected description of an entire row of the abstract CFI table. */ struct GTY(()) dw_cfi_row @@ -2484,7 +2488,7 @@ scan_insn_after (rtx_insn *insn) instructions therein. */ static void -scan_trace (dw_trace_info *trace) +scan_trace (dw_trace_info *trace, bool entry) { rtx_insn *prev, *insn = trace->head; dw_cfa_location this_cfa; @@ -2503,6 +2507,17 @@ scan_trace (dw_trace_info *trace) this_cfa = cur_row->cfa; cur_cfa = &this_cfa; + /* If the current function starts with a non-standard incoming frame + sp offset, emit a note before the first instruction. */ + if (entry + && DEFAULT_INCOMING_FRAME_SP_OFFSET != INCOMING_FRAME_SP_OFFSET) + { + add_cfi_insn = insn; + gcc_assert (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED); + this_cfa.offset = INCOMING_FRAME_SP_OFFSET; + def_cfa_1 (&this_cfa); + } + for (prev = insn, insn = NEXT_INSN (insn); insn; prev = insn, insn = NEXT_INSN (insn)) @@ -2671,12 +2686,12 @@ create_cfi_notes (void) /* Always begin at the entry trace. */ ti = &trace_info[0]; - scan_trace (ti); + scan_trace (ti, true); while (!trace_work_list.is_empty ()) { ti = trace_work_list.pop (); - scan_trace (ti); + scan_trace (ti, false); } queued_reg_saves.release (); @@ -2980,7 +2995,12 @@ create_cie_data (void) /* On entry, the Canonical Frame Address is at SP. */ memset (&loc, 0, sizeof (loc)); loc.reg = dw_stack_pointer_regnum; - loc.offset = INCOMING_FRAME_SP_OFFSET; + /* create_cie_data is called just once per TU, and when using .cfi_startproc + is even done by the assembler rather than the compiler. If the target + has different incoming frame sp offsets depending on what kind of + function it is, use a single constant offset for the target and + if needed, adjust before the first instruction in insn stream. */ + loc.offset = DEFAULT_INCOMING_FRAME_SP_OFFSET; def_cfa_1 (&loc); if (targetm.debug_unwind_info () == UI_DWARF2 -- 2.30.2