[Bug target/50678] [4.7 Regression] FAIL: c52104y on x86_64-apple-darwin10

iains at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Oct 18 19:20:00 GMT 2011


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50678

--- Comment #50 from Iain Sandoe <iains at gcc dot gnu.org> 2011-10-18 19:18:38 UTC ---
well I've hit a few issues.
1. _Unwind_Find_FDE is not part of the public interface (nor are the types it
needs).

2. if the vendor decides to 'fix' libunwind .. we won't detect this ... 
(although I still think this idea is worth pursuing, on the grounds that 'no
fix' or a fix to Libc are more likely).

3. _Unwind_Find_FDE is returning NULL in the following proof-of-concept hack..

.. not having any joy debugging this from the c++ case (maybe have to try a
newer debugger)..

(have to do some other things for a while - but if you can spot my obvious
mistake .. then let me know).

#if defined (__x86_64__)

/* Work around radar #10302855/pr50678, where the unwinders (libunwind or
   libgcc_s depending on the system revision) and the DWARF unwind data for
   the sigtramp have different ideas about register numbering (causing rbx
   and rdx to be transposed).  */

#define DX86FIX_CHECKED 0x01
#define DX86FIX_DOFIXUP 0x02

struct dwarf_eh_bases
{
  void *tbase;
  void *dbase;
  void *func;
};

typedef          int  sword __attribute__ ((mode (SI)));
typedef unsigned int  uword __attribute__ ((mode (SI)));

struct dwarf_fde
{
  uword length;
  sword CIE_delta;
  unsigned char pc_begin[];
} __attribute__ ((packed, aligned (__alignof__ (void *))));

extern struct dwarf_fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);

static void
__gnat_darwin_maybe_fixup_unwind_context (ucontext_t *uc, void *ad)
{
  static unsigned need_fixup = 0;

  /* Look for the FDE for the sig tramp.  */
  if ((need_fixup & DX86FIX_CHECKED) == 0)
    {
      struct dwarf_eh_bases bases;
      const struct dwarf_fde *myfde = _Unwind_Find_FDE (ad, &bases);

      if (myfde == NULL)
        need_fixup |= DX86FIX_DOFIXUP;  /* We're likely broken.  */
      else
    {
      unsigned MCONTEXT_SS_RBX, MCONTEXT_SS_RDX, ts;
      /* These are the offsets for the registers.  */
      ts = __builtin_offsetof (_STRUCT_MCONTEXT,__ss);
      MCONTEXT_SS_RBX = __builtin_offsetof (_STRUCT_X86_THREAD_STATE64,__rbx);
      MCONTEXT_SS_RBX += ts;
      MCONTEXT_SS_RDX = __builtin_offsetof (_STRUCT_X86_THREAD_STATE64,__rdx);
      MCONTEXT_SS_RDX += ts;

// UNFINISHED
    }
      need_fixup |= DX86FIX_CHECKED;
    }

  if (need_fixup & DX86FIX_DOFIXUP)
    {
      unsigned long t = uc->uc_mcontext->__ss.__rbx;
      uc->uc_mcontext->__ss.__rbx = uc->uc_mcontext->__ss.__rdx;
      uc->uc_mcontext->__ss.__rdx = t;
    }
}

#endif

static void
__gnat_error_handler (int sig, siginfo_t *si, void *ucontext)
{
  struct Exception_Data *exception;
  const char *msg;

#if defined (__x86_64__)
  /* We pass the address from here so that we don't need to worry about
     inlining.  */
  __gnat_darwin_maybe_fixup_unwind_context ((ucontext_t *)ucontext,
                        __builtin_return_address (0));
#endif



More information about the Gcc-bugs mailing list