mips.h (MASK_RETURN_ADDR): Expand commentary.
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 9 Aug 2008 18:19:32 +0000 (18:19 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sat, 9 Aug 2008 18:19:32 +0000 (18:19 +0000)
gcc/
* config/mips/mips.h (MASK_RETURN_ADDR): Expand commentary.
* config/mips/linux-unwind.h (mips_fallback_frame_state): Add 2
rather than 4 to PC.

From-SVN: r138910

gcc/ChangeLog
gcc/config/mips/linux-unwind.h
gcc/config/mips/mips.h

index 608a3f7..8e39561 100644 (file)
@@ -1,5 +1,11 @@
 2008-08-09  Richard Sandiford  <rdsandiford@googlemail.com>
 
+       * config/mips/mips.h (MASK_RETURN_ADDR): Expand commentary.
+       * config/mips/linux-unwind.h (mips_fallback_frame_state): Add 2
+       rather than 4 to PC.
+
+2008-08-09  Richard Sandiford  <rdsandiford@googlemail.com>
+
        * config/mips/mips.h (STATIC_CHAIN_REGNUM): Remap to $15.
        (FUNCTION_PROFILER): Save the static chain pointer into $2
        beforehand and restore it aftewards.
index 4e71182..818b436 100644 (file)
@@ -106,12 +106,17 @@ mips_fallback_frame_state (struct _Unwind_Context *context,
     fs->regs.reg[i].loc.offset
       = (_Unwind_Ptr)&(sc->sc_regs[i]) + reg_offset - new_cfa;
   }
-  /* The PC points to the faulting instruction, but the unwind tables
-     expect it point to the following instruction.  We compensate by
-     reporting a return address at the next instruction. */
+  /* "PC & -2" points to the faulting instruction, but the unwind code
+     searches for "(ADDR & -2) - 1".  (See MASK_RETURN_ADDR for the source
+     of the -2 mask.)  Adding 2 here ensures that "(ADDR & -2) - 1" is the
+     address of the second byte of the faulting instruction.
+
+     Note that setting fs->signal_frame would not work.  As the comment
+     above MASK_RETURN_ADDR explains, MIPS unwinders must earch for an
+     odd-valued address.  */
   fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].how = REG_SAVED_VAL_OFFSET;
   fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].loc.offset
-    = (_Unwind_Ptr)(sc->sc_pc) + 4 - new_cfa;
+    = (_Unwind_Ptr)(sc->sc_pc) + 2 - new_cfa;
   fs->retaddr_column = DWARF_ALT_FRAME_RETURN_COLUMN;
 
   return _URC_NO_REASON;
index 2d55104..006c73e 100644 (file)
@@ -1958,10 +1958,32 @@ enum reg_class
 
 #define RETURN_ADDR_RTX mips_return_addr
 
-/* Since the mips16 ISA mode is encoded in the least-significant bit
-   of the address, mask it off return addresses for purposes of
-   finding exception handling regions.  */
-
+/* Mask off the MIPS16 ISA bit in unwind addresses.
+
+   The reason for this is a little subtle.  When unwinding a call,
+   we are given the call's return address, which on most targets
+   is the address of the following instruction.  However, what we
+   actually want to find is the EH region for the call itself.
+   The target-independent unwind code therefore searches for "RA - 1".
+
+   In the MIPS16 case, RA is always an odd-valued (ISA-encoded) address.
+   RA - 1 is therefore the real (even-valued) start of the return
+   instruction.  EH region labels are usually odd-valued MIPS16 symbols
+   too, so a search for an even address within a MIPS16 region would
+   usually work.
+
+   However, there is an exception.  If the end of an EH region is also
+   the end of a function, the end label is allowed to be even.  This is
+   necessary because a following non-MIPS16 function may also need EH
+   information for its first instruction.
+
+   Thus a MIPS16 region may be terminated by an ISA-encoded or a
+   non-ISA-encoded address.  This probably isn't ideal, but it is
+   the traditional (legacy) behavior.  It is therefore only safe
+   to search MIPS EH regions for an _odd-valued_ address.
+
+   Masking off the ISA bit means that the target-independent code
+   will search for "(RA & -2) - 1", which is guaranteed to be odd.  */
 #define MASK_RETURN_ADDR GEN_INT (-2)