This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

[RFC] Wrong register numbers in .dwarf_frame on Linux/PowerPC


Hello,

I noticed what appears to be a long-standing bug in generating .dwarf_frame
sections with GCC on Linux on PowerPC.

It had been my understanding that .dwarf_frame is supposed to differ from
.eh_frame on PowerPC w.r.t. register numbers: .eh_frame should use GCC
internal numbers, while .dwarf_frame should use the DWARF register numbers
documented in the PowerPC ELF ABI.  However, in actual fact, .dwarf_frame
does not use the DWARF numbers; and it does not use the GCC numbers either,
but a weird mixture: it uses GCC numbers for everything except for the
condition code register, for which it uses the DWARF number (64).

Doing a bit of code archaeology, it seems this behaviour goes back to a
patch checked in by Geoff Keating just before GCC 4.2.  (And indeed in
GCC 4.1 we actually have DWARF numbers in .dwarf_frame.):

use correct DWARF register numbers on rs6000 non-ELF ports
http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00766.html

This patch moves the definition of the two macros DBX_REGISTER_NUMBER
and DWARF2_FRAME_REG_OUT from rs6000/sysv4.h to rs6000/rs6000.h:

  #define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)

  /* Map register numbers held in the call frame info that gcc has
     collected using DWARF_FRAME_REGNUM to those that should be output in
     .debug_frame and .eh_frame.  We continue to use gcc hard reg numbers
     for .eh_frame, but use the numbers mandated by the various ABIs for
     .debug_frame.  rs6000_emit_prologue has translated any combination of
     CR2, CR3, CR4 saves to a save of CR2.  The actual code emitted saves
     the whole of CR, so we map CR2_REGNO to the DWARF reg for CR.  */
  #define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH)	\
    ((FOR_EH) ? (REGNO)				\
     : (REGNO) == CR2_REGNO ? 64		\
     : DBX_REGISTER_NUMBER (REGNO))

The intention apparently was to make Darwin use the same numbers as
Linux.  However, the actual effect was to make Darwin use the same
numbers Linux used to use before, while at the same time breaking
the numbers used by Linux.

The problem is that target macro headers were included in the
following sequence:
   rs6000/rs6000.h
   svr4.h
   rs6000/sysv4.h
and the common svr4.h header contained a line:
  #undef DBX_REGISTER_NUMBER

When DBX_REGISTER_NUMBER was defined in rs6000/sysv4.h, this didn't
matter.  But now that the definition was moved to rs6000/rs6000.h,
it was in effect undone by the #undef in svr4.h, transforming the
definition of DWARF2_FRAME_REG_OUT to be:
  #define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH)   \
    ((FOR_EH) ? (REGNO)                         \
     : (REGNO) == CR2_REGNO ? 64                \       
     : (REGNO))
which explains the observed behaviour of GCC since 4.2.


Since then, a couple of changes were done to the sources, but all
preserved this behaviour.  Most notably, Joseph Myers eliminated
the common sysv4.h header, but moved the #undef to rs6000/sysv4.h
instead:

svr4.h avoidance: rs6000/powerpc
http://gcc.gnu.org/ml/gcc-patches/2010-12/msg01264.html


Also, with current GCC and binutils, .dwarf_frame is usually not
generated by GCC directly, but via .cfi_... directives interpreted
by gas.  This was implemented by a patch by Jakub Jelinek:

[PATCH] Add support for .cfi_sections - way to emit also .debug_frame from .cfi_* directives
http://sourceware.org/ml/binutils/2009-10/msg00028.html

which notes:

> On ppc this is uglified by the need to translate register numbers - as
> .eh_frame uses different numbering of registers than .debug_frame.

In the patch as posted to the mailing list, this translation is here:

  /* ppc uses different register numbers between .eh_frame and .debug_frame.
     This macro translates the .eh_frame register numbers to .debug_frame
     register numbers.  */
  #define md_reg_eh_frame_to_debug_frame(regno) \
    ((regno) == 70 ? 64	/* cr2 */					\
     : (regno) == 64 ? 100 /* mq */					\
     : (regno) == 65 ? 108 /* lr */					\
     : (regno) == 66 ? 109 /* ctr */					\
     : (regno) >= 68 && (regno) <= 75 ? (regno) + 86 - 68 /* crN */	\
     : (regno) == 76 ? 101 /* xer */					\
     : (regno) >= 77 && (regno) <= 108 ? (regno) + 1124 - 77 /* vrN */	\
     : (regno) == 109 ? 356 /* vrsave */				\
     : (regno) == 110 ? 67 /* vscr */					\
     : (regno) == 111 ? 99 /* spe_acc */				\
     : (regno) == 112 ? 612 /* spefscr */				\
     : (regno))

But in the patch as actually checked in (tc-ppc.h rev. 1.41), we have:

  /* ppc uses different register numbers between .eh_frame and .debug_frame.
     This macro translates the .eh_frame register numbers to .debug_frame
     register numbers.  */
  #define md_reg_eh_frame_to_debug_frame(regno) \
    ((regno) == 70 ? 64 /* cr2 */ : (regno))

So it seems Jakub also noticed that GCC's behaviour did not actually
followed the documented ABI, and chose to mirror the actual behaviour
in GCC instead.


However, on the GDB side, we actually expect DWARF numbers in .dwarf_frame.
There is a hack in rs6000-tdep.c:rs6000_adjust_frame_regnum that makes it
proceed at least somewhat by fixing up the LR number:

static int
rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p)
{
  /* GCC releases before 3.4 use GCC internal register numbering in
     .debug_frame (and .debug_info, et cetera).  The numbering is
     different from the standard SysV numbering for everything except
     for GPRs and FPRs.  We can not detect this problem in most cases
     - to get accurate debug info for variables living in lr, ctr, v0,
     et cetera, use a newer version of GCC.  But we must detect
     one important case - lr is in column 65 in .debug_frame output,
     instead of 108.

     GCC 3.4, and the "hammer" branch, have a related problem.  They
     record lr register saves in .debug_frame as 108, but still record
     the return column as 65.  We fix that up too.

     We can do this because 65 is assigned to fpsr, and GCC never
     generates debug info referring to it.  To add support for
     handwritten debug info that restores fpsr, we would need to add a
     producer version check to this.  */
  if (!eh_frame_p)
    {
      if (num == 65)
        return 108;
      else
        return num;
    }

But as the comment says, this isn't really a solution for things like
values in vector registers.  Unfortunately, "use a newer version of
GCC" isn't really quite right any more: the only versions of GCC that
ever did it correctly were 4.0 and 4.1, it would appear.


So I'm wondering where to go from here.  I guess we could:

1. Bring GCC (and gas) behaviour in compliance with the documented ABI
   by removing the #undef DBX_REGISTER_NUMBER and changing gas's
   md_reg_eh_frame_to_debug_frame to the original implementation from
   Jakub's patch.  That would make GDB work well on new files, but
   there are a large number of binaries out there where we continue
   to have the same behaviour as today ...

2. Leave GCC and gas as-is and modify GDB to expect GCC numbering in
   .dwarf_frame, except for the condition code register.  This would
   break debugging of files built with GCC 4.0 and 4.1 unless we
   want to add a special hack for that.

3. Like 2., but remove the condition code hack: simply use identical
   numbers in .eh_frame and .dwarf_frame.  This would make PowerPC
   like other Linux platforms in that respect.

Thoughts?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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