http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47324
--- Comment #14 from mrs at gcc dot gnu.org <mrs at gcc dot gnu.org> 2011-02-08 10:50:43 UTC --- 157762 seems to have new code that outputs a dwarf register number without going though DWARF2_FRAME_REG_OUT which I think is wrong. I fixed that and played around for a bit, the closest I could come up with was something like the below... but I'm certain it is wrong. :-( We need someone to puzzle over the dwarf/stabs/unwind/eh_frame debug info and come up with the right solution. Also, at lower optimizations the test still failed. I'm wondering if we are even wondering around in the right area yet. Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 169905) +++ dwarf2out.c (working copy) @@ -474,7 +474,7 @@ static void dwarf2out_frame_debug_expr (rtx, const char *); /* Support for complex CFA locations. */ -static void output_cfa_loc (dw_cfi_ref); +static void output_cfa_loc (dw_cfi_ref, bool); static void output_cfa_loc_raw (dw_cfi_ref); static void get_cfa_from_loc_descr (dw_cfa_location *, struct dw_loc_descr_struct *); @@ -3317,7 +3317,7 @@ case DW_CFA_def_cfa_expression: case DW_CFA_expression: - output_cfa_loc (cfi); + output_cfa_loc (cfi, for_eh); break; case DW_CFA_GNU_negative_offset_extended: @@ -5451,14 +5451,16 @@ description based on a cfi entry with a complex address. */ static void -output_cfa_loc (dw_cfi_ref cfi) +output_cfa_loc (dw_cfi_ref cfi, bool for_eh) { + unsigned long r; dw_loc_descr_ref loc; unsigned long size; if (cfi->dw_cfi_opc == DW_CFA_expression) { - dw2_asm_output_data (1, cfi->dw_cfi_oprnd1.dw_cfi_reg_num, NULL); + r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); + dw2_asm_output_data (1, r, NULL); loc = cfi->dw_cfi_oprnd2.dw_cfi_loc; } else Index: config/i386/darwin.h =================================================================== --- config/i386/darwin.h (revision 169905) +++ config/i386/darwin.h (working copy) @@ -252,17 +252,12 @@ #undef DBX_REGISTER_NUMBER #define DBX_REGISTER_NUMBER(n) \ (TARGET_64BIT ? dbx64_register_map[n] \ - : write_symbols == DWARF2_DEBUG ? svr4_dbx_register_map[n] \ - : dbx_register_map[n]) + : darwin_dbx_register_number(n)) /* Unfortunately, the 32-bit EH information also doesn't use the standard DWARF register numbers. */ #define DWARF2_FRAME_REG_OUT(n, for_eh) \ - (! (for_eh) || write_symbols != DWARF2_DEBUG || TARGET_64BIT ? (n) \ - : (n) == 5 ? 4 \ - : (n) == 4 ? 5 \ - : (n) >= 11 && (n) <= 18 ? (n) + 1 \ - : (n)) + darwin_dwarf2_frame_reg_out (n, for_eh) #undef REGISTER_SUBTARGET_PRAGMAS #define REGISTER_SUBTARGET_PRAGMAS() DARWIN_REGISTER_TARGET_PRAGMAS() Index: config/darwin.c =================================================================== --- config/darwin.c (revision 169905) +++ config/darwin.c (working copy) @@ -3094,4 +3094,47 @@ fputs (":\n", fp); } +static bool +darwin_will_use_eh () +{ + if () + return true; + return 0; +} + +int +darwin_dbx_register_number(n) +{ +#if 1 + /* Without -O3, eh-alloc-1.c -m32 fails. */ + /* Works! */ + if (write_symbols == DWARF2_DEBUG && !dwarf2out_do_frame()) + return svr4_dbx_register_map[n]; +#else + /* Works! */ + if (!(write_symbols == DWARF2_DEBUG + || write_symbols == NO_DEBUG)) + return svr4_dbx_register_map[n]; +#endif + return dbx_register_map[n]; +} + +int +darwin_dwarf2_frame_reg_out (n, for_eh) +{ + if (! (for_eh) + /* WTF, if we are doing this for_eh, and the eh uses the pre-svr4 numbers, then + we must convert the svr4 numbers back. */ + || (write_symbols != DWARF2_DEBUG, 0) + || TARGET_64BIT) + return n; + if (n == 5) + return 4; + if (n == 4) + return 5; + if (n >= 11 && n <= 18) + return n + 1; + return n; +} + #include "gt-darwin.h"