aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2008-08-09 18:19:32 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2008-08-09 18:19:32 +0000
commit579725054c9c297a856c1a24224829ce0fb602c7 (patch)
tree95c8c240d7dcb1d3b15864f4b579007ec49651e2
parente538e028ec41ada02fa243b25a88b47b1a6d030b (diff)
downloadgcc-579725054c9c297a856c1a24224829ce0fb602c7.zip
gcc-579725054c9c297a856c1a24224829ce0fb602c7.tar.gz
gcc-579725054c9c297a856c1a24224829ce0fb602c7.tar.bz2
mips.h (MASK_RETURN_ADDR): Expand commentary.
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/mips/linux-unwind.h13
-rw-r--r--gcc/config/mips/mips.h30
3 files changed, 41 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 608a3f7..8e39561 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/mips/linux-unwind.h b/gcc/config/mips/linux-unwind.h
index 4e71182..818b436 100644
--- a/gcc/config/mips/linux-unwind.h
+++ b/gcc/config/mips/linux-unwind.h
@@ -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;
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 2d55104..006c73e 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -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)