diff --git a/mps/code/fri3gc.gmk b/mps/code/fri3gc.gmk
index 28f7f71a8a2..ef740464e38 100644
--- a/mps/code/fri3gc.gmk
+++ b/mps/code/fri3gc.gmk
@@ -11,6 +11,7 @@ MPMPF = \
lockix.c \
prmcan.c \
prmcfri3.c \
+ prmcix.c \
protix.c \
protsgix.c \
pthrdext.c \
diff --git a/mps/code/fri3ll.gmk b/mps/code/fri3ll.gmk
index 43ba68a664c..7e8b51dd541 100644
--- a/mps/code/fri3ll.gmk
+++ b/mps/code/fri3ll.gmk
@@ -11,6 +11,7 @@ MPMPF = \
lockix.c \
prmcan.c \
prmcfri3.c \
+ prmcix.c \
protix.c \
protsgix.c \
pthrdext.c \
diff --git a/mps/code/fri6gc.gmk b/mps/code/fri6gc.gmk
index c2f536959a3..976717a74b4 100644
--- a/mps/code/fri6gc.gmk
+++ b/mps/code/fri6gc.gmk
@@ -11,6 +11,7 @@ MPMPF = \
lockix.c \
prmcan.c \
prmcfri6.c \
+ prmcix.c \
protix.c \
protsgix.c \
pthrdext.c \
diff --git a/mps/code/fri6ll.gmk b/mps/code/fri6ll.gmk
index c8148f38767..431f66aa38f 100644
--- a/mps/code/fri6ll.gmk
+++ b/mps/code/fri6ll.gmk
@@ -11,6 +11,7 @@ MPMPF = \
lockix.c \
prmcan.c \
prmcfri6.c \
+ prmcix.c \
protix.c \
protsgix.c \
pthrdext.c \
diff --git a/mps/code/lii3gc.gmk b/mps/code/lii3gc.gmk
index 5a0b073ca9f..8098925e559 100644
--- a/mps/code/lii3gc.gmk
+++ b/mps/code/lii3gc.gmk
@@ -10,6 +10,7 @@ PFM = lii3gc
MPMPF = \
lockix.c \
prmci3.c \
+ prmcix.c \
prmclii3.c \
protix.c \
protsgix.c \
diff --git a/mps/code/lii6gc.gmk b/mps/code/lii6gc.gmk
index 7c938a24197..81a4fe4b664 100644
--- a/mps/code/lii6gc.gmk
+++ b/mps/code/lii6gc.gmk
@@ -10,6 +10,7 @@ PFM = lii6gc
MPMPF = \
lockix.c \
prmci6.c \
+ prmcix.c \
prmclii6.c \
protix.c \
protsgix.c \
diff --git a/mps/code/lii6ll.gmk b/mps/code/lii6ll.gmk
index 9cc8fad72bf..ab636fe9278 100644
--- a/mps/code/lii6ll.gmk
+++ b/mps/code/lii6ll.gmk
@@ -10,6 +10,7 @@ PFM = lii6ll
MPMPF = \
lockix.c \
prmci6.c \
+ prmcix.c \
prmclii6.c \
protix.c \
protsgix.c \
diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h
index 9b16509c76a..d8ecc6596dd 100644
--- a/mps/code/mpmtypes.h
+++ b/mps/code/mpmtypes.h
@@ -94,7 +94,7 @@ typedef struct GlobalsStruct *Globals; /* */
typedef struct VMStruct *VM; /* * */
typedef struct RootStruct *Root; /* */
typedef struct mps_thr_s *Thread; /* * */
-typedef struct MutatorContextStruct *MutatorContext; /* */
+typedef struct MutatorContextStruct *MutatorContext; /* */
typedef struct PoolDebugMixinStruct *PoolDebugMixin;
typedef struct AllocPatternStruct *AllocPattern;
typedef struct AllocFrameStruct *AllocFrame; /* */
diff --git a/mps/code/mps.c b/mps/code/mps.c
index ce116a53e8e..3e60c93e1f4 100644
--- a/mps/code/mps.c
+++ b/mps/code/mps.c
@@ -120,6 +120,7 @@
#include "protix.c" /* Posix protection */
#include "protxc.c" /* OS X Mach exception handling */
#include "prmci3.c" /* 32-bit Intel mutator context decoding */
+#include "prmcxc.c" /* Mac OS X mutator context */
#include "prmcxci3.c" /* 32-bit Intel for Mac OS X mutator context */
#include "span.c" /* generic stack probe */
#include "ssixi3.c" /* Posix on 32-bit Intel stack scan */
@@ -134,6 +135,7 @@
#include "protix.c" /* Posix protection */
#include "protxc.c" /* OS X Mach exception handling */
#include "prmci6.c" /* 64-bit Intel mutator context decoding */
+#include "prmcxc.c" /* Mac OS X mutator context */
#include "prmcxci6.c" /* 64-bit Intel for Mac OS X mutator context */
#include "span.c" /* generic stack probe */
#include "ssixi6.c" /* Posix on 64-bit Intel stack scan */
@@ -149,6 +151,7 @@
#include "protix.c" /* Posix protection */
#include "protsgix.c" /* Posix signal handling */
#include "prmcan.c" /* generic mutator context */
+#include "prmcix.c" /* Posix mutator context */
#include "prmcfri3.c" /* 32-bit Intel for FreeBSD mutator context */
#include "span.c" /* generic stack probe */
#include "ssixi3.c" /* Posix on 32-bit Intel stack scan */
@@ -164,6 +167,7 @@
#include "protix.c" /* Posix protection */
#include "protsgix.c" /* Posix signal handling */
#include "prmcan.c" /* generic mutator context */
+#include "prmcix.c" /* Posix mutator context */
#include "prmcfri6.c" /* 64-bit Intel for FreeBSD mutator context */
#include "span.c" /* generic stack probe */
#include "ssixi6.c" /* Posix on 64-bit Intel stack scan */
@@ -179,6 +183,7 @@
#include "protix.c" /* Posix protection */
#include "protsgix.c" /* Posix signal handling */
#include "prmci3.c" /* 32-bit Intel mutator context */
+#include "prmcix.c" /* Posix mutator context */
#include "prmclii3.c" /* 32-bit Intel for Linux mutator context */
#include "span.c" /* generic stack probe */
#include "ssixi3.c" /* Posix on 32-bit Intel stack scan */
@@ -194,6 +199,7 @@
#include "protix.c" /* Posix protection */
#include "protsgix.c" /* Posix signal handling */
#include "prmci6.c" /* 64-bit Intel mutator context */
+#include "prmcix.c" /* Posix mutator context */
#include "prmclii6.c" /* 64-bit Intel for Linux mutator context */
#include "span.c" /* generic stack probe */
#include "ssixi6.c" /* Posix on 64-bit Intel stack scan */
diff --git a/mps/code/mps.xcodeproj/project.pbxproj b/mps/code/mps.xcodeproj/project.pbxproj
index b9d5a9d4864..1e5f2dff3a5 100644
--- a/mps/code/mps.xcodeproj/project.pbxproj
+++ b/mps/code/mps.xcodeproj/project.pbxproj
@@ -1452,6 +1452,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 2213454C1DB0386600E14202 /* prmc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prmc.h; sourceTree = ""; };
+ 2213454D1DB038D400E14202 /* prmcxc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = prmcxc.c; sourceTree = ""; };
2231BB5918CA97D8002D6322 /* locbwcss */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = locbwcss; sourceTree = BUILT_PRODUCTS_DIR; };
2231BB6718CA97DC002D6322 /* locusss */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = locusss; sourceTree = BUILT_PRODUCTS_DIR; };
2231BB6818CA9834002D6322 /* locbwcss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locbwcss.c; sourceTree = ""; };
@@ -1655,17 +1657,13 @@
311F2F6B17398B4C00C15B6A /* mpswin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mpswin.h; sourceTree = ""; };
311F2F6D17398B6300C15B6A /* prmci3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = prmci3.h; sourceTree = ""; };
311F2F6E17398B6300C15B6A /* prmci6.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = prmci6.h; sourceTree = ""; };
- 311F2F6F17398B6300C15B6A /* prmcix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = prmcix.h; sourceTree = ""; };
- 311F2F7017398B6300C15B6A /* prmcw3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = prmcw3.h; sourceTree = ""; };
311F2F7117398B7100C15B6A /* protocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = protocol.h; sourceTree = ""; };
- 311F2F7217398B7100C15B6A /* pthrdext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthrdext.h; sourceTree = ""; };
311F2F7317398B7100C15B6A /* ring.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ring.h; sourceTree = ""; };
311F2F7417398B7100C15B6A /* sac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sac.h; sourceTree = ""; };
311F2F7517398B8E00C15B6A /* sc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sc.h; sourceTree = ""; };
311F2F7617398B8E00C15B6A /* splay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = splay.h; sourceTree = ""; };
311F2F7717398B8E00C15B6A /* ss.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ss.h; sourceTree = ""; };
311F2F7817398B8E00C15B6A /* th.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = th.h; sourceTree = ""; };
- 311F2F7917398B8E00C15B6A /* thw3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = thw3.h; sourceTree = ""; };
311F2F7A17398B8E00C15B6A /* tract.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tract.h; sourceTree = ""; };
311F2F7B17398E7600C15B6A /* poolmv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = poolmv.h; sourceTree = ""; };
311F2F7C17398E9A00C15B6A /* mpscmv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mpscmv.h; sourceTree = ""; };
@@ -2453,7 +2451,6 @@
31EEABF4156AAF6500714D05 /* MPM Core */ = {
isa = PBXGroup;
children = (
- 31942A671C8EC3FC001AAF32 /* locus.h */,
3114A645156E9525001E0AA3 /* abq.c */,
2291A5EA175CB503001D4920 /* abq.h */,
31EEAC05156AB27B00714D05 /* arena.c */,
@@ -2489,6 +2486,7 @@
31EEAC2B156AB2F200714D05 /* ld.c */,
311F2F5E17398B0E00C15B6A /* lock.h */,
31EEAC08156AB27B00714D05 /* locus.c */,
+ 31942A671C8EC3FC001AAF32 /* locus.h */,
31EEAC2C156AB2F200714D05 /* message.c */,
31EEAC42156AB32500714D05 /* meter.c */,
311F2F5F17398B0E00C15B6A /* meter.h */,
@@ -2519,13 +2517,9 @@
311F2F7B17398E7600C15B6A /* poolmv.h */,
22FACEDE18880933000FDBC1 /* pooln.c */,
22FACEDF18880933000FDBC1 /* pooln.h */,
- 311F2F6D17398B6300C15B6A /* prmci3.h */,
- 311F2F6E17398B6300C15B6A /* prmci6.h */,
- 311F2F6F17398B6300C15B6A /* prmcix.h */,
- 311F2F7017398B6300C15B6A /* prmcw3.h */,
+ 2213454C1DB0386600E14202 /* prmc.h */,
31EEAC0B156AB27B00714D05 /* protocol.c */,
311F2F7117398B7100C15B6A /* protocol.h */,
- 311F2F7217398B7100C15B6A /* pthrdext.h */,
2291A5EB175CB53E001D4920 /* range.c */,
2291A5EC175CB53E001D4920 /* range.h */,
31EEAC1B156AB2B200714D05 /* ref.c */,
@@ -2545,7 +2539,6 @@
22FACEDA1888088A000FDBC1 /* ss.c */,
311F2F7717398B8E00C15B6A /* ss.h */,
311F2F7817398B8E00C15B6A /* th.h */,
- 311F2F7917398B8E00C15B6A /* thw3.h */,
31EEAC1E156AB2B200714D05 /* trace.c */,
31EEAC1F156AB2B200714D05 /* traceanc.c */,
31EEAC0D156AB27B00714D05 /* tract.c */,
@@ -2563,9 +2556,12 @@
31EEAC4B156AB39C00714D05 /* Platform */ = {
isa = PBXGroup;
children = (
- 315B7AFC17834FDB00B097C4 /* prmci3.c */,
- 315B7AFD17834FDB00B097C4 /* prmci6.c */,
31EEAC4C156AB3B000714D05 /* lockix.c */,
+ 315B7AFC17834FDB00B097C4 /* prmci3.c */,
+ 311F2F6D17398B6300C15B6A /* prmci3.h */,
+ 315B7AFD17834FDB00B097C4 /* prmci6.c */,
+ 311F2F6E17398B6300C15B6A /* prmci6.h */,
+ 2213454D1DB038D400E14202 /* prmcxc.c */,
31172ABB177512F6009488E5 /* prmcxci3.c */,
31172ABC1775131C009488E5 /* prmcxci6.c */,
31172ABE1775164F009488E5 /* prmcxc.h */,
diff --git a/mps/code/prmc.h b/mps/code/prmc.h
index 22247154493..f954d2ec311 100644
--- a/mps/code/prmc.h
+++ b/mps/code/prmc.h
@@ -15,7 +15,9 @@
#include "mpmtypes.h"
+#define MutatorContextSig ((Sig)0x519302C0) /* SIGnature MUTator COntext */
+extern Bool MutatorContextCheck(MutatorContext context);
extern Bool MutatorContextCanStepInstruction(MutatorContext context);
extern Res MutatorContextStepInstruction(MutatorContext context);
extern Addr MutatorContextSP(MutatorContext context);
diff --git a/mps/code/prmcfri3.c b/mps/code/prmcfri3.c
index aeda5f8015f..f05988f273f 100644
--- a/mps/code/prmcfri3.c
+++ b/mps/code/prmcfri3.c
@@ -15,10 +15,6 @@
* ASSUMPTIONS
*
* .sp: The stack pointer in the context is ESP.
- *
- * .context.regroots: The root regs are EDI, ESI, EBX, EDX, ECX, EAX,
- * and they are assumed to be recorded in the context at
- * pointer-aligned boundaries.
*/
#include "prmcix.h"
@@ -33,29 +29,11 @@ SRCID(prmcfri3, "$Id$");
Addr MutatorContextSP(MutatorContext context)
{
+ AVERT(MutatorContext, context);
return (Addr)context->ucontext->uc_mcontext.mc_esp; /* .sp */
}
-Res MutatorContextScan(ScanState ss, MutatorContext context,
- mps_area_scan_t scan_area, void *closure)
-{
- Res res;
-
- /* This scans the root registers (.context.regroots). It also unnecessarily
- scans the rest of the context. The optimisation to scan only relevant
- parts would be machine dependent. */
- res = TraceScanArea(
- ss,
- (Word *)context->ucontext,
- (Word *)((char *)context->ucontext + sizeof(*(context->ucontext))),
- scan_area, closure
- );
-
- return res;
-}
-
-
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2016 Ravenbrook Limited .
diff --git a/mps/code/prmcfri6.c b/mps/code/prmcfri6.c
index 1631c9366af..586eec1647a 100644
--- a/mps/code/prmcfri6.c
+++ b/mps/code/prmcfri6.c
@@ -9,10 +9,6 @@
* ASSUMPTIONS
*
* .sp: The stack pointer in the context is RSP.
- *
- * .context.regroots: The root regs are RDI, RSI, RBX, RDX, RCX, RAX,
- * and they are assumed to be recorded in the context at
- * pointer-aligned boundaries.
*/
#include "prmcix.h"
@@ -27,29 +23,11 @@ SRCID(prmcfri6, "$Id$");
Addr MutatorContextSP(MutatorContext context)
{
+ AVERT(MutatorContext, context);
return (Addr)context->ucontext->uc_mcontext.mc_rsp; /* .sp */
}
-Res MutatorContextScan(ScanState ss, MutatorContext context,
- mps_area_scan_t scan_area, void *closure)
-{
- Res res;
-
- /* This scans the root registers (.context.regroots). It also unnecessarily
- scans the rest of the context. The optimisation to scan only relevant
- parts would be machine dependent. */
- res = TraceScanArea(
- ss,
- (Word *)context->ucontext,
- (Word *)((char *)context->ucontext + sizeof(*(context->ucontext))),
- scan_area, closure
- );
-
- return res;
-}
-
-
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2016 Ravenbrook Limited .
diff --git a/mps/code/prmci3.c b/mps/code/prmci3.c
index 26a6b139516..22190251a1f 100644
--- a/mps/code/prmci3.c
+++ b/mps/code/prmci3.c
@@ -216,6 +216,8 @@ Bool MutatorContextCanStepInstruction(MutatorContext context)
MRef src;
MRef dest;
+ AVERT(MutatorContext, context);
+
/* .assume.null */
/* .assume.want */
if(IsSimpleMov(&inslen, &src, &dest, context)) {
@@ -232,6 +234,8 @@ Res MutatorContextStepInstruction(MutatorContext context)
MRef src;
MRef dest;
+ AVERT(MutatorContext, context);
+
/* .assume.null */
/* .assume.want */
if(IsSimpleMov(&inslen, &src, &dest, context)) {
diff --git a/mps/code/prmci6.c b/mps/code/prmci6.c
index 7b98b44fc47..f1df3aec90b 100644
--- a/mps/code/prmci6.c
+++ b/mps/code/prmci6.c
@@ -59,6 +59,8 @@ Bool MutatorContextCanStepInstruction(MutatorContext context)
MRef src;
MRef dest;
+ AVERT(MutatorContext, context);
+
/* .assume.null */
if(IsSimpleMov(&inslen, &src, &dest, context)) {
return TRUE;
@@ -74,6 +76,8 @@ Res MutatorContextStepInstruction(MutatorContext context)
MRef src;
MRef dest;
+ AVERT(MutatorContext, context);
+
/* .assume.null */
if(IsSimpleMov(&inslen, &src, &dest, context)) {
*dest = *src;
diff --git a/mps/code/prmcix.c b/mps/code/prmcix.c
new file mode 100644
index 00000000000..9d9bfea4eff
--- /dev/null
+++ b/mps/code/prmcix.c
@@ -0,0 +1,104 @@
+/* prmcix.c: MUTATOR CONTEXT (POSIX)
+ *
+ * $Id$
+ * Copyright (c) 2016 Ravenbrook Limited. See end of file for license.
+ *
+ * .purpose: Implement the mutator context module. See .
+ *
+ *
+ * ASSUMPTIONS
+ *
+ * .context.regroots: The root registers are assumed to be recorded in
+ * the context at pointer-aligned boundaries.
+ */
+
+#include "prmcix.h"
+
+SRCID(prmcix, "$Id$");
+
+#if !defined(MPS_OS_FR) && !defined(MPS_OS_LI)
+#error "prmcxc.c is specific to MPS_OS_FR and MPS_OS_LI"
+#endif
+
+
+Bool MutatorContextCheck(MutatorContext context)
+{
+ CHECKS(MutatorContext, context);
+ CHECKL(context->ucontext != NULL);
+ return TRUE;
+}
+
+
+void MutatorContextInit(MutatorContext context, siginfo_t *info,
+ ucontext_t *ucontext)
+{
+ AVER(context != NULL);
+ AVER(ucontext != NULL);
+
+ context->info = info;
+ context->ucontext = ucontext;
+ context->sig = MutatorContextSig;
+
+ AVERT(MutatorContext, context);
+}
+
+
+Res MutatorContextScan(ScanState ss, MutatorContext context,
+ mps_area_scan_t scan_area, void *closure)
+{
+ mcontext_t *mc;
+ Res res;
+
+ /* This scans the root registers (.context.regroots). It also
+ unnecessarily scans the rest of the context. The optimisation
+ to scan only relevant parts would be machine dependent. */
+ mc = &context->ucontext->uc_mcontext;
+ res = TraceScanArea(ss,
+ (Word *)mc,
+ (Word *)((char *)mc + sizeof(*mc)),
+ scan_area, closure);
+ return res;
+}
+
+
+/* C. COPYRIGHT AND LICENSE
+ *
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
+ * All rights reserved. This is an open source license. Contact
+ * Ravenbrook for commercial licensing options.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Redistributions in any form must be accompanied by information on how
+ * to obtain complete source code for this software and any accompanying
+ * software that uses this software. The source code must either be
+ * included in the distribution or be available for no more than the cost
+ * of distribution plus a nominal fee, and must be freely redistributable
+ * under reasonable conditions. For an executable file, complete source
+ * code means the source code for all modules it contains. It does not
+ * include source code for modules or files that typically accompany the
+ * major components of the operating system on which the executable file
+ * runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
diff --git a/mps/code/prmcix.h b/mps/code/prmcix.h
index 0ac22e2e5d4..dcca8215141 100644
--- a/mps/code/prmcix.h
+++ b/mps/code/prmcix.h
@@ -15,10 +15,12 @@
#include /* ucontext_t */
typedef struct MutatorContextStruct {
+ Sig sig; /* */
siginfo_t *info;
ucontext_t *ucontext;
} MutatorContextStruct;
+extern void MutatorContextInit(MutatorContext context, siginfo_t *info, ucontext_t *ucontext);
#endif /* prmcix_h */
diff --git a/mps/code/prmclii3.c b/mps/code/prmclii3.c
index c47d4fee0f0..a7a3a675807 100644
--- a/mps/code/prmclii3.c
+++ b/mps/code/prmclii3.c
@@ -18,9 +18,6 @@
*
* .sp: The stack pointer in the context is ESP.
*
- * .context.regroots: The root regs are assumed to be recorded in the context
- * at pointer-aligned boundaries.
- *
* .assume.regref: The registers in the context can be modified by
* storing into an MRef pointer.
*/
@@ -41,10 +38,9 @@ MRef Prmci3AddressHoldingReg(MutatorContext context, unsigned int regnum)
{
MRef gregs;
- AVER(context != NULL);
+ AVERT(MutatorContext, context);
AVER(NONNEGATIVE(regnum));
AVER(regnum <= 7);
- AVER(context->ucontext != NULL);
/* TODO: The current arrangement of the fix operation (taking a Ref *)
forces us to pun these registers (actually `int` on LII3GC). We can
@@ -80,6 +76,10 @@ void Prmci3DecodeFaultContext(MRef *faultmemReturn,
Byte **insvecReturn,
MutatorContext context)
{
+ AVER(faultmemReturn != NULL);
+ AVER(insvecReturn != NULL);
+ AVERT(MutatorContext, context);
+
/* .source.linux.kernel (linux/arch/i386/mm/fault.c). */
*faultmemReturn = (MRef)context->info->si_addr;
*insvecReturn = (Byte*)context->ucontext->uc_mcontext.gregs[REG_EIP];
@@ -90,34 +90,20 @@ void Prmci3DecodeFaultContext(MRef *faultmemReturn,
void Prmci3StepOverIns(MutatorContext context, Size inslen)
{
+ AVERT(MutatorContext, context);
+
context->ucontext->uc_mcontext.gregs[REG_EIP] += (unsigned long)inslen;
}
Addr MutatorContextSP(MutatorContext context)
{
+ AVERT(MutatorContext, context);
+
return (Addr)context->ucontext->uc_mcontext.gregs[REG_ESP];
}
-Res MutatorContextScan(ScanState ss, MutatorContext context,
- mps_area_scan_t scan_area, void *closure)
-{
- mcontext_t *mc;
- Res res;
-
- /* This scans the root registers (.context.regroots). It also
- unnecessarily scans the rest of the context. The optimisation
- to scan only relevant parts would be machine dependent. */
- mc = &context->ucontext->uc_mcontext;
- res = TraceScanArea(ss,
- (Word *)mc,
- (Word *)((char *)mc + sizeof(*mc)),
- scan_area, closure);
- return res;
-}
-
-
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2016 Ravenbrook Limited .
diff --git a/mps/code/prmclii6.c b/mps/code/prmclii6.c
index be2cfe0e3be..67ba1b62160 100644
--- a/mps/code/prmclii6.c
+++ b/mps/code/prmclii6.c
@@ -15,9 +15,6 @@
*
* .sp: The stack pointer in the context is RSP.
*
- * .context.regroots: The root regs are assumed to be recorded in the context
- * at pointer-aligned boundaries.
- *
* .assume.regref: The registers in the context can be modified by
* storing into an MRef pointer.
*/
@@ -38,10 +35,9 @@ MRef Prmci6AddressHoldingReg(MutatorContext context, unsigned int regnum)
{
MRef gregs;
- AVER(context != NULL);
+ AVERT(MutatorContext, context);
AVER(NONNEGATIVE(regnum));
AVER(regnum <= 15);
- AVER(context->ucontext != NULL);
/* TODO: The current arrangement of the fix operation (taking a Ref *)
forces us to pun these registers (actually `int` on LII6GC). We can
@@ -84,6 +80,10 @@ void Prmci6DecodeFaultContext(MRef *faultmemReturn,
Byte **insvecReturn,
MutatorContext context)
{
+ AVER(faultmemReturn != NULL);
+ AVER(insvecReturn != NULL);
+ AVERT(MutatorContext, context);
+
/* .source.linux.kernel (linux/arch/x86/mm/fault.c). */
*faultmemReturn = (MRef)context->info->si_addr;
*insvecReturn = (Byte*)context->ucontext->uc_mcontext.gregs[REG_RIP];
@@ -94,34 +94,20 @@ void Prmci6DecodeFaultContext(MRef *faultmemReturn,
void Prmci6StepOverIns(MutatorContext context, Size inslen)
{
+ AVERT(MutatorContext, context);
+
context->ucontext->uc_mcontext.gregs[REG_RIP] += (Word)inslen;
}
Addr MutatorContextSP(MutatorContext context)
{
+ AVERT(MutatorContext, context);
+
return (Addr)context->ucontext->uc_mcontext.gregs[REG_RSP];
}
-Res MutatorContextScan(ScanState ss, MutatorContext context,
- mps_area_scan_t scan_area, void *closure)
-{
- mcontext_t *mc;
- Res res;
-
- /* This scans the root registers (.context.regroots). It also
- unnecessarily scans the rest of the context. The optimisation
- to scan only relevant parts would be machine dependent. */
- mc = &context->ucontext->uc_mcontext;
- res = TraceScanArea(ss,
- (Word *)mc,
- (Word *)((char *)mc + sizeof(*mc)),
- scan_area, closure);
- return res;
-}
-
-
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2016 Ravenbrook Limited .
diff --git a/mps/code/prmcxc.c b/mps/code/prmcxc.c
new file mode 100644
index 00000000000..d521dcb96ca
--- /dev/null
+++ b/mps/code/prmcxc.c
@@ -0,0 +1,106 @@
+/* prmcxc.c: MUTATOR CONTEXT INTEL 386 (MAC OS X)
+ *
+ * $Id$
+ * Copyright (c) 2016 Ravenbrook Limited. See end of file for license.
+ *
+ * .purpose: Implement the mutator context module. See .
+ *
+ *
+ * ASSUMPTIONS
+ *
+ * .context.regroots: The root registers are assumed to be recorded in
+ * the context at pointer-aligned boundaries.
+ */
+
+#include "prmcxc.h"
+
+SRCID(prmcxc, "$Id$");
+
+#if !defined(MPS_OS_XC)
+#error "prmcxc.c is specific to MPS_OS_XC"
+#endif
+
+
+Bool MutatorContextCheck(MutatorContext context)
+{
+ CHECKS(MutatorContext, context);
+ CHECKL(context->threadState != NULL);
+ return TRUE;
+}
+
+
+void MutatorContextInit(MutatorContext context, Addr address,
+ THREAD_STATE_S *threadState)
+{
+ AVER(context != NULL);
+ AVER(threadState != NULL);
+
+ context->address = address;
+ AVER(sizeof *context->threadState == sizeof(THREAD_STATE_S));
+ context->threadState = threadState;
+ context->sig = MutatorContextSig;
+
+ AVERT(MutatorContext, context);
+}
+
+
+Res MutatorContextScan(ScanState ss, MutatorContext context,
+ mps_area_scan_t scan_area, void *closure)
+{
+ THREAD_STATE_S *mc;
+ Res res;
+
+ AVERT(MutatorContext, context);
+
+ /* This scans the root registers (.context.regroots). It also
+ unnecessarily scans the rest of the context. The optimisation
+ to scan only relevant parts would be architecture dependent. */
+ mc = context->threadState;
+ res = TraceScanArea(ss,
+ (Word *)mc,
+ (Word *)((char *)mc + sizeof(*mc)),
+ scan_area, closure);
+ return res;
+}
+
+
+/* C. COPYRIGHT AND LICENSE
+ *
+ * Copyright (C) 2016 Ravenbrook Limited .
+ * All rights reserved. This is an open source license. Contact
+ * Ravenbrook for commercial licensing options.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Redistributions in any form must be accompanied by information on how
+ * to obtain complete source code for this software and any accompanying
+ * software that uses this software. The source code must either be
+ * included in the distribution or be available for no more than the cost
+ * of distribution plus a nominal fee, and must be freely redistributable
+ * under reasonable conditions. For an executable file, complete source
+ * code means the source code for all modules it contains. It does not
+ * include source code for modules or files that typically accompany the
+ * major components of the operating system on which the executable file
+ * runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/mps/code/prmcxc.h b/mps/code/prmcxc.h
index af145a6e603..832b0c4015a 100644
--- a/mps/code/prmcxc.h
+++ b/mps/code/prmcxc.h
@@ -15,12 +15,14 @@
#include
typedef struct MutatorContextStruct {
+ Sig sig; /* */
Addr address;
THREAD_STATE_S *threadState;
/* FIXME: Might need to get the floats in case the compiler stashes
intermediate values in them. */
} MutatorContextStruct;
+extern void MutatorContextInit(MutatorContext context, Addr address, THREAD_STATE_S *threadState);
#endif /* prmcxc_h */
diff --git a/mps/code/prmcxci3.c b/mps/code/prmcxci3.c
index 03fe3d836f0..1e51dec7aae 100644
--- a/mps/code/prmcxci3.c
+++ b/mps/code/prmcxci3.c
@@ -11,14 +11,9 @@
* .source.i486: Intel486 Microprocessor Family Programmer's
* Reference Manual
*
- * .source.linux.kernel: Linux kernel source files.
- *
*
* ASSUMPTIONS
*
- * .context.regroots: The root regs are assumed to be recorded in the context
- * at pointer-aligned boundaries.
- *
* .assume.regref: The registers in the context can be modified by
* storing into an MRef pointer.
*/
@@ -39,10 +34,10 @@ MRef Prmci3AddressHoldingReg(MutatorContext context, unsigned int regnum)
{
THREAD_STATE_S *threadState;
- AVER(context != NULL);
+ AVERT(MutatorContext, context);
AVER(NONNEGATIVE(regnum));
AVER(regnum <= 7);
- AVER(context->threadState != NULL);
+
threadState = context->threadState;
/* .source.i486 */
@@ -76,6 +71,10 @@ void Prmci3DecodeFaultContext(MRef *faultmemReturn,
Byte **insvecReturn,
MutatorContext context)
{
+ AVER(faultmemReturn != NULL);
+ AVER(insvecReturn != NULL);
+ AVERT(MutatorContext, context);
+
*faultmemReturn = (MRef)context->address;
*insvecReturn = (Byte*)context->threadState->__eip;
}
@@ -85,34 +84,21 @@ void Prmci3DecodeFaultContext(MRef *faultmemReturn,
void Prmci3StepOverIns(MutatorContext context, Size inslen)
{
+ AVERT(MutatorContext, context);
+ AVER(0 < inslen);
+
context->threadState->__eip += (Word)inslen;
}
Addr MutatorContextSP(MutatorContext context)
{
+ AVERT(MutatorContext, context);
+
return (Addr)context->threadState->__esp;
}
-Res MutatorContextScan(ScanState ss, MutatorContext context,
- mps_area_scan_t scan_area, void *closure)
-{
- x86_thread_state32_t *mc;
- Res res;
-
- /* This scans the root registers (.context.regroots). It also
- unnecessarily scans the rest of the context. The optimisation
- to scan only relevant parts would be machine dependent. */
- mc = context->threadState;
- res = TraceScanArea(ss,
- (Word *)mc,
- (Word *)((char *)mc + sizeof(*mc)),
- scan_area, closure);
- return res;
-}
-
-
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2016 Ravenbrook Limited .
diff --git a/mps/code/prmcxci6.c b/mps/code/prmcxci6.c
index 269deb4b275..1c7d6ac5f91 100644
--- a/mps/code/prmcxci6.c
+++ b/mps/code/prmcxci6.c
@@ -13,9 +13,6 @@
*
* .sp: The stack pointer in the context is RSP.
*
- * .context.regroots: The root regs are assumed to be recorded in the context
- * at pointer-aligned boundaries.
- *
* .assume.regref: The registers in the context can be modified by
* storing into an MRef pointer.
*/
@@ -36,10 +33,10 @@ MRef Prmci6AddressHoldingReg(MutatorContext context, unsigned int regnum)
{
THREAD_STATE_S *threadState;
- AVER(context != NULL);
+ AVERT(MutatorContext, context);
AVER(NONNEGATIVE(regnum));
AVER(regnum <= 15);
- AVER(context->threadState != NULL);
+
threadState = context->threadState;
/* .assume.regref */
@@ -79,6 +76,10 @@ void Prmci6DecodeFaultContext(MRef *faultmemReturn,
Byte **insvecReturn,
MutatorContext context)
{
+ AVER(faultmemReturn != NULL);
+ AVER(insvecReturn != NULL);
+ AVERT(MutatorContext, context);
+
*faultmemReturn = (MRef)context->address;
*insvecReturn = (Byte*)context->threadState->__rip;
}
@@ -88,34 +89,21 @@ void Prmci6DecodeFaultContext(MRef *faultmemReturn,
void Prmci6StepOverIns(MutatorContext context, Size inslen)
{
+ AVERT(MutatorContext, context);
+ AVER(0 < inslen);
+
context->threadState->__rip += (Word)inslen;
}
Addr MutatorContextSP(MutatorContext context)
{
+ AVERT(MutatorContext, context);
+
return (Addr)context->threadState->__rsp;
}
-Res MutatorContextScan(ScanState ss, MutatorContext context,
- mps_area_scan_t scan_area, void *closure)
-{
- x86_thread_state64_t *mc;
- Res res;
-
- /* This scans the root registers (.context.regroots). It also
- unnecessarily scans the rest of the context. The optimisation
- to scan only relevant parts would be machine dependent. */
- mc = context->threadState;
- res = TraceScanArea(ss,
- (Word *)mc,
- (Word *)((char *)mc + sizeof(*mc)),
- scan_area, closure);
- return res;
-}
-
-
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2016 Ravenbrook Limited .
diff --git a/mps/code/protix.c b/mps/code/protix.c
index a243b009491..43df9630467 100644
--- a/mps/code/protix.c
+++ b/mps/code/protix.c
@@ -1,15 +1,11 @@
/* protix.c: PROTECTION FOR UNIX
*
* $Id$
- * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2016 Ravenbrook Limited. See end of file for license.
*
* Somewhat generic across different Unix systems. Shared between
* OS X, FreeBSD, and Linux.
*
- * This file does not contain a signal handler. That's in protsgix.c for
- * historical reasons (there used to be separate implementations for the
- * different flavours of Unix).
- *
*
* SOURCES
*
@@ -123,7 +119,7 @@ Size ProtGranularity(void)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2015 Ravenbrook Limited .
+ * Copyright (C) 2001-2016 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/protsgix.c b/mps/code/protsgix.c
index 2b43197e14e..4c266fe877e 100644
--- a/mps/code/protsgix.c
+++ b/mps/code/protsgix.c
@@ -81,12 +81,9 @@ static void sigHandle(int sig, siginfo_t *info, void *uap) /* .sigh.args */
if(info->si_code == SEGV_ACCERR) { /* .sigh.check */
AccessSet mode;
Addr base;
- ucontext_t *ucontext;
MutatorContextStruct context;
- ucontext = (ucontext_t *)uap;
- context.ucontext = ucontext;
- context.info = info;
+ MutatorContextInit(&context, info, (ucontext_t *)uap);
mode = AccessREAD | AccessWRITE; /* .sigh.mode */
diff --git a/mps/code/protxc.c b/mps/code/protxc.c
index adc18acc6d7..2674fd0610e 100644
--- a/mps/code/protxc.c
+++ b/mps/code/protxc.c
@@ -238,9 +238,8 @@ static void protCatchOne(void)
/* The cast via Word suppresses "cast to pointer from integer of
different size" warnings in GCC, for the XCI3GC build. */
- context.address = (Addr)(Word)request.code[1];
- AVER(sizeof(*context.threadState) == sizeof(THREAD_STATE_S));
- context.threadState = (void *)request.old_state;
+ MutatorContextInit(&context, (Addr)(Word)request.code[1],
+ (void *)request.old_state);
if (ArenaAccess(context.address,
AccessREAD | AccessWRITE,
diff --git a/mps/code/pthrdext.c b/mps/code/pthrdext.c
index f0b85903434..35612625d89 100644
--- a/mps/code/pthrdext.c
+++ b/mps/code/pthrdext.c
@@ -80,7 +80,7 @@ static void suspendSignalHandler(int sig,
/* copy the ucontext structure so we definitely have it on our stack,
* not (e.g.) shared with other threads. */
ucontext = *(ucontext_t *)uap;
- context.ucontext = &ucontext;
+ MutatorContextInit(&context, NULL, &ucontext);
suspendingVictim->context = &context;
/* Block all signals except PTHREADEXT_SIGRESUME while suspended. */
sigfillset(&signal_set);
diff --git a/mps/code/thxc.c b/mps/code/thxc.c
index bcac8296b50..0952c75fa08 100644
--- a/mps/code/thxc.c
+++ b/mps/code/thxc.c
@@ -236,8 +236,7 @@ Res ThreadScan(ScanState ss, Thread thread, Word *stackCold,
order to assert that the thread is suspended, but it's probably
unnecessary and is a lot of work to check a static condition. */
- context.address = NULL;
- context.threadState = &threadState;
+ MutatorContextInit(&context, NULL, &threadState);
count = THREAD_STATE_COUNT;
AVER(sizeof(*context.threadState) == count * sizeof(natural_t));
diff --git a/mps/code/xci3gc.gmk b/mps/code/xci3gc.gmk
index 92d398c4e0a..c20e7f43598 100644
--- a/mps/code/xci3gc.gmk
+++ b/mps/code/xci3gc.gmk
@@ -12,6 +12,7 @@ PFM = xci3gc
MPMPF = \
lockix.c \
prmci3.c \
+ prmcxc.c \
prmcxci3.c \
protix.c \
protxc.c \
diff --git a/mps/code/xci3ll.gmk b/mps/code/xci3ll.gmk
index f5aa716fa11..9cabd39de23 100644
--- a/mps/code/xci3ll.gmk
+++ b/mps/code/xci3ll.gmk
@@ -16,6 +16,7 @@ PFM = xci3ll
MPMPF = \
lockix.c \
prmci3.c \
+ prmcxc.c \
prmcxci3.c \
protix.c \
protxc.c \
diff --git a/mps/code/xci6gc.gmk b/mps/code/xci6gc.gmk
index e38613fcdd8..3ff0d778557 100644
--- a/mps/code/xci6gc.gmk
+++ b/mps/code/xci6gc.gmk
@@ -16,6 +16,7 @@ PFM = xci6gc
MPMPF = \
lockix.c \
prmci6.c \
+ prmcxc.c \
prmcxci6.c \
protix.c \
protxc.c \
diff --git a/mps/code/xci6ll.gmk b/mps/code/xci6ll.gmk
index c2ffdc4e9f4..fe10bab67bd 100644
--- a/mps/code/xci6ll.gmk
+++ b/mps/code/xci6ll.gmk
@@ -16,6 +16,7 @@ PFM = xci6ll
MPMPF = \
lockix.c \
prmci6.c \
+ prmcxc.c \
prmcxci6.c \
protix.c \
protxc.c \
diff --git a/mps/design/prmc.txt b/mps/design/prmc.txt
index d16bd3faaa5..64549e9749f 100644
--- a/mps/design/prmc.txt
+++ b/mps/design/prmc.txt
@@ -84,6 +84,13 @@ See design.mps.thread-manager.if.thread_.
.. _design.mps.thread-manager.if.thread: thread-manager#if.thread
+``Bool MutatorContextCheck(MutatorContext context)``
+
+_`.if.check`: The check function for mutator contexts. See
+design.mps.check_.
+
+.. _design.mps.check: check
+
``Bool MutatorContextCanStepInstruction(MutatorContext context)``
_`.if.canstep`: Examine the context to determine whether the
diff --git a/mps/manual/source/code-index.rst b/mps/manual/source/code-index.rst
index 5b754e92fdf..7eb130fdf58 100644
--- a/mps/manual/source/code-index.rst
+++ b/mps/manual/source/code-index.rst
@@ -171,12 +171,14 @@ prmci3.c Mutator context implementation for IA-32.
prmci3.h Mutator context interface for IA-32.
prmci6.c Mutator context implementation for x86-64.
prmci6.h Mutator context interface for x86-64.
+prmcix.c Mutator context implementation for POSIX.
prmcix.h Mutator context interface for POSIX.
prmclii3.c Mutator context implementation for Linux, IA-32.
prmclii6.c Mutator context implementation for Linux, x86-64.
prmcw3.h Mutator context interface for Windows.
prmcw3i3.c Mutator context implementation for Windows, IA-32.
prmcw3i6.c Mutator context implementation for Windows, x86-64.
+prmcxc.c Mutator context implementation for OS X.
prmcxc.h Mutator context interface for OS X.
prmcxci3.c Mutator context implementation for OS X, IA-32.
prmcxci6.c Mutator context implementation for OS X, x86-64.