Hi! My typed DWARF stack changes apparently broke ia64-hpux and H.J.'s out of tree x32 target. There are several issues: 1) for SUBREG mem_loc_descriptor's 3rd argument was wrong, found by code inspection 2) CONST/SYMBOL_REF/LABEL_REF when in MEM addresses on POINTERS_EXTEND_UNSIGNED targets are often Pmode, which is unfortunately larger than DWARF2_ADDR_SIZE and my conditional would just return NULL in that case instead of emitting DW_OP_addr. 3) and, when mem_loc_descriptor is called from unwind code, Pmodes larger than DWARF2_ADDR_SIZE would result in the new DW_OP_GNU_*_type etc. ops which are not allowed in .eh_frame/.debug_frame The following patch ought to fix that, bootstrapped/regtested on x86_64-linux and i686-linux and Steve tested it on ia64-hpux and H.J. on his port. Ok for trunk?
2011-05-05 Jakub Jelinek <ja...@redhat.com> PR debug/48853 * dwarf2out.c (mem_loc_descriptor) <case SUBREG>: Pass mem_mode instead of mode as 3rd argument to recursive call. (mem_loc_descriptor) <case REG>: If POINTERS_EXTEND_UNSIGNED, don't emit DW_OP_GNU_regval_type if mode is Pmode and mem_mode is not VOIDmode. (mem_loc_descriptor) <case SYMBOL_REF>: If POINTERS_EXTEND_UNSIGNED, don't give up if mode is Pmode and mem_mode is not VOIDmode. (mem_loc_descriptor) <case CONST_INT>: If POINTERS_EXTEND_UNSIGNED, use int_loc_descriptor if mode is Pmode and mem_mode is not VOIDmode. --- gcc/dwarf2out.c.jj 2011-05-04 10:14:08.000000000 +0200 +++ gcc/dwarf2out.c 2011-05-04 19:08:22.000000000 +0200 @@ -13883,7 +13883,7 @@ mem_loc_descriptor (rtx rtl, enum machin mem_loc_result = mem_loc_descriptor (SUBREG_REG (rtl), GET_MODE (SUBREG_REG (rtl)), - mode, initialized); + mem_mode, initialized); if (mem_loc_result == NULL) break; type_die = base_type_for_mode (mode, 0); @@ -13906,7 +13906,13 @@ mem_loc_descriptor (rtx rtl, enum machin case REG: if (GET_MODE_CLASS (mode) != MODE_INT - || GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE) + || (GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE +#ifdef POINTERS_EXTEND_UNSIGNED + && (mode != Pmode + || GET_MODE_SIZE (ptr_mode) != DWARF2_ADDR_SIZE + || mem_mode == VOIDmode) +#endif + )) { dw_die_ref type_die; @@ -14049,9 +14055,18 @@ mem_loc_descriptor (rtx rtl, enum machin pool. */ case CONST: case SYMBOL_REF: + if (GET_MODE_CLASS (mode) != MODE_INT) + break; +#ifndef POINTERS_EXTEND_UNSIGNED + if (GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE) + break; +#else if (GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE - || GET_MODE_CLASS (mode) != MODE_INT) + && (mode != Pmode + || GET_MODE_SIZE (ptr_mode) != DWARF2_ADDR_SIZE + || mem_mode == VOIDmode)) break; +#endif if (GET_CODE (rtl) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE) { @@ -14288,7 +14303,14 @@ mem_loc_descriptor (rtx rtl, enum machin break; case CONST_INT: - if (GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE) + if (GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE +#ifdef POINTERS_EXTEND_UNSIGNED + || (mode == Pmode + && GET_MODE_SIZE (ptr_mode) == DWARF2_ADDR_SIZE + && mem_mode != VOIDmode + && trunc_int_for_mode (INTVAL (rtl), ptr_mode) == INTVAL (rtl)) +#endif + ) { mem_loc_result = int_loc_descriptor (INTVAL (rtl)); break; Jakub