Hi, Would you please help on how to generate correct epilogue dwarf info? Without correct dwarf info, when shrink-wrap is enabled, it tends to ICE at dwarf2cfi.c: function maybe_record_trace_start.
/* We ought to have the same state incoming to a given trace no matter how we arrive at the trace. Anything else means we've got some kind of optimization error. */ gcc_checking_assert (cfi_row_equal_p (cur_row, ti->beg_row)); Issues: 1) pretend_args The attached pretend_arg.c shows an example about pretend_args dwarf info push {r2, r3} .cfi_def_cfa_offset 8 .cfi_offset 2, -8 .cfi_offset 3, -4 use r3 push {r4, r5, lr} ... pop {r4, r5, lr} add sp, sp, #8 //No instruction here to restore r2 and r3 Can we RESTORE r2 and r3? * If we notes to RESTORE r2 and r3, it might lead to wrong info for GDB since no instruction restores them. * If we do not RESTORE them, the reg_save dwarf info will not be cleared. Then the dwarf check will fail when the function is shrink-wrapped. 2) frame_pointer_needed In prologue, we set fp like fp = sp + INT After this instruction, cfi_def_cfa_register is set to fp In epilogue. we have fp += INT sp = fp Can we reset cfi_def_cfa_register back to sp? * If we set it back to sp, how to handle it in arm_unwind_emit_set, which assumes sp can not be set from other register? /* A stack increment. */ if (GET_CODE (e1) != PLUS || !REG_P (XEXP (e1, 0)) || REGNO (XEXP (e1, 0)) != SP_REGNUM || !CONST_INT_P (XEXP (e1, 1))) abort (); * If we do not set it back, to get correct dwarf info for POP after "sp = fp", we have to add notes " sp = fp + INT" for dwarf-info while we have "sp = sp + INT" in the insn. Here is the workaround POP RTL example for the attached alloca,c: (insn/f 62 61 66 3 (parallel [ (set/f (reg/f:SI 13 sp) // sp = sp + 8 (plus:SI (reg/f:SI 13 sp) (const_int 8 [0x8]))) (set/f (reg:SI 3 r3) (mem/c:SI (reg/f:SI 13 sp) [3 S4 A32])) (set/f (reg/f:SI 7 r7) (mem/c:SI (plus:SI (reg/f:SI 13 sp) (const_int 4 [0x4])) [3 S4 A32])) ]) alloca.c:8 329 {*load_multiple_with_writeback} (expr_list:REG_UNUSED (reg:SI 3 r3) (expr_list:REG_CFA_ADJUST_CFA (set (reg/f:SI 13 sp) (plus:SI (reg/f:SI 7 r7) // sp = fp + 8 (const_int 8 [0x8]))) (expr_list:REG_CFA_RESTORE (reg/f:SI 7 r7) (expr_list:REG_CFA_RESTORE (reg:SI 3 r3) (nil)))))) (3) No idea for if (crtl->calls_eh_return) emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, gen_rtx_REG (SImode, ARM_EH_STACKADJ_REGNUM))); Currently I have no shrink-wrapped test case which crtl->calls_eh_return is true. Thanks! -Zhenqiang
#include <stdlib.h> #include <stdio.h> #include <stdarg.h> #define DEBUG_BUFFER_SIZE 80 int unifi_debug = 5; void unifi_trace(void* ospriv, int level, const char *fmt, ...) { static char s[DEBUG_BUFFER_SIZE]; va_list args; unsigned int len; if (!ospriv) return; if(unifi_debug >= level) { va_start(args, fmt); len = vsnprintf(&(s)[0], (DEBUG_BUFFER_SIZE), fmt, args); va_end(args); if (len >= DEBUG_BUFFER_SIZE) { (s)[DEBUG_BUFFER_SIZE - 2] = '\n'; (s)[DEBUG_BUFFER_SIZE - 1] = 0; } printf("%s", s); } }
pretend_arg.s
Description: Binary data
extern int * alloca(int); int *p; void test(int a) { if (a > 0) p = alloca(4); }
_______________________________________________ linaro-toolchain mailing list linaro-toolchain@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-toolchain