This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PowerPC DWARF2 information mismatch


On PowerPC, we have a test case which results in a mismatch between the register number used for the return address in the DWARF2 CIE and the FDE. That causes backtraces to go wonky. The test case is kinda big, but I'll post it when I get it cut down.

In any case, I can sort-of explain what's going on, though my DWARF2-fu is very weak. I'd appreciate any insight on how this might be fixed.

In the CIE, we have:

.byte 0x41 # CIE RA Column

In the FDE, we have:

        .byte   0x11     # DW_CFA_offset_extended_sf
        .uleb128 0x6c
        .sleb128 -1

The mismatch occurs because of the PowerPC use of different DWARF2 register numbers of EH and debug information. It looks like 0x41 is the right choice for EH information, but not debug information. The code that generates the FDEs has a "for_eh" parameter that allows it to decide, but the code for CIEs does not -- and so it cannot get it right.

In more detail, register 65 (0x41) is GCC's internal register number for the link register:

#define LINK_REGISTER_REGNUM 65

The use of register 65 is coming from:

dw2_asm_output_data (1, DWARF_FRAME_RETURN_COLUMN, "CIE RA Column");

because rs6000.h does:

#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGISTER_REGNUM)
/* Use gcc hard register numbering for eh_frame. */
#define DWARF_FRAME_REGNUM(REGNO) (REGNO)


The use of register 108 comes from:

case DW_CFA_offset_extended_sf:
case DW_CFA_def_cfa_sf:
r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
dw2_asm_output_data_uleb128 (r, NULL);


Here, the register number is again 65. But,

  #define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH)     \
  ((FOR_EH) ? (REGNO)                           \
   : (REGNO) == CR2_REGNO ? 64                  \
   : DBX_REGISTER_NUMBER (REGNO))

and, in rs6000_dbx_register_number:

   if (regno == LINK_REGISTER_REGNUM)
    return 108;

So, for non-EH, we get 108.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
(916) 791-8304


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]