From 025e16f239fa7014bddfaf3c876dfa15d7018165 Mon Sep 17 00:00:00 2001
From: David Lovemore
Date: Wed, 1 Aug 2012 20:45:29 +0100
Subject: [PATCH] Fix for unix stack scanner now that gcc sometimes omits frame
pointers.
Copied from Perforce
Change: 178810
ServerID: perforce.ravenbrook.com
---
mps/code/ssixi3.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/mps/code/ssixi3.c b/mps/code/ssixi3.c
index 950897c8840..0d1c31c7501 100644
--- a/mps/code/ssixi3.c
+++ b/mps/code/ssixi3.c
@@ -22,6 +22,8 @@
*
* .source.callees.saves: Set of callee-saved registers taken from
* CALL_USED_REGISTERS in /config/i386/i386.h.
+ * ebp added to the list because gcc now doesn't always use it as
+ * a frame pointer so it could contain a root.
*
* ASSUMPTIONS
*
@@ -49,20 +51,23 @@ SRCID(ssixi3, "$Id$");
Res StackScan(ScanState ss, Addr *stackBot)
{
+ Addr calleeSaveRegs[4];
Addr *stackTop;
Res res;
/* .assume.asm.stack */
- ASMV("push %ebx"); /* These registers are callee-saved */
- ASMV("push %esi"); /* and so may contain roots. They are pushed */
- ASMV("push %edi"); /* for scanning. See .source.callees.saves. */
+ /* Store the callee save registers on the stack so they get scanned
+ * as they may contain roots.
+ */
+ ASMV("mov %%ebx, %0" : "=m" (calleeSaveRegs[0]));
+ ASMV("mov %%esi, %0" : "=m" (calleeSaveRegs[1]));
+ ASMV("mov %%edi, %0" : "=m" (calleeSaveRegs[2]));
+ ASMV("mov %%ebp, %0" : "=m" (calleeSaveRegs[3]));
ASMV("mov %%esp, %0" : "=r" (stackTop) :); /* stackTop = esp */
AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .assume.align */
res = TraceScanArea(ss, stackTop, stackBot);
- ASMV("add $12, %esp"); /* pop 3 regs to restore the stack pointer */
-
return res;
}