From bcfbaaf3e471874b9d841f00a781bdae159b955d Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 13 Oct 2016 23:13:40 +0100 Subject: [PATCH] Initialization and checking of mutatorcontext data structures. New files prmcix.c and prmcxc.c avoid duplicated code. Copied from Perforce Change: 192562 ServerID: perforce.ravenbrook.com --- mps/code/fri3gc.gmk | 1 + mps/code/fri3ll.gmk | 1 + mps/code/fri6gc.gmk | 1 + mps/code/fri6ll.gmk | 1 + mps/code/lii3gc.gmk | 1 + mps/code/lii6gc.gmk | 1 + mps/code/lii6ll.gmk | 1 + mps/code/mpmtypes.h | 2 +- mps/code/mps.c | 6 ++ mps/code/mps.xcodeproj/project.pbxproj | 22 +++-- mps/code/prmc.h | 2 + mps/code/prmcfri3.c | 24 +----- mps/code/prmcfri6.c | 24 +----- mps/code/prmci3.c | 4 + mps/code/prmci6.c | 4 + mps/code/prmcix.c | 104 ++++++++++++++++++++++++ mps/code/prmcix.h | 2 + mps/code/prmclii3.c | 32 +++----- mps/code/prmclii6.c | 32 +++----- mps/code/prmcxc.c | 106 +++++++++++++++++++++++++ mps/code/prmcxc.h | 2 + mps/code/prmcxci3.c | 36 +++------ mps/code/prmcxci6.c | 34 +++----- mps/code/protix.c | 8 +- mps/code/protsgix.c | 5 +- mps/code/protxc.c | 5 +- mps/code/pthrdext.c | 2 +- mps/code/thxc.c | 3 +- mps/code/xci3gc.gmk | 1 + mps/code/xci3ll.gmk | 1 + mps/code/xci6gc.gmk | 1 + mps/code/xci6ll.gmk | 1 + mps/design/prmc.txt | 7 ++ mps/manual/source/code-index.rst | 2 + 34 files changed, 309 insertions(+), 170 deletions(-) create mode 100644 mps/code/prmcix.c create mode 100644 mps/code/prmcxc.c 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.