Pyrogenesis  trunk
overrun_protector.h
Go to the documentation of this file.
1 /* Copyright (c) 2011 Wildfire Games
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining
4  * a copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to
8  * permit persons to whom the Software is furnished to do so, subject to
9  * the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #ifndef INCLUDED_ALLOCATORS_OVERRUN_PROTECTOR
24 #define INCLUDED_ALLOCATORS_OVERRUN_PROTECTOR
25 
26 #include "lib/config2.h" // CONFIG2_ALLOCATORS_OVERRUN_PROTECTION
27 #include "lib/sysdep/vm.h"
28 
29 /**
30 OverrunProtector wraps an arbitrary object in isolated page(s) and
31 can detect inadvertent writes to it. this is useful for
32 tracking down memory overruns.
33 
34 the basic idea is to require users to request access to the object and
35 notify us when done; memory access permission is temporarily granted.
36 (similar in principle to Software Transaction Memory).
37 
38 since this is quite slow, the protection is disabled unless
39 CONFIG2_ALLOCATORS_OVERRUN_PROTECTION == 1; this avoids having to remove the
40 wrapper code in release builds and re-write when looking for overruns.
41 
42 example usage:
43 OverrunProtector<T> wrapper;
44 ..
45 T* p = wrapper.get(); // unlock, make ready for use
46 if(!p) // wrapper's one-time alloc of a T-
47  abort(); // instance had failed - can't continue.
48 DoSomethingWith(p); // (read/write access)
49 wrapper.lock(); // disallow further access until next .get()
50 ..
51 **/
52 template<class T> class OverrunProtector
53 {
54  NONCOPYABLE(OverrunProtector); // const member
55 public:
57 #if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION
58  : object(new(vm::Allocate(sizeof(T))) T())
59 #else
60  : object(new T())
61 #endif
62  {
63  lock();
64  }
65 
67  {
68  unlock();
69 #if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION
70  object->~T(); // call dtor (since we used placement new)
71  vm::Free(object, sizeof(T));
72 #else
73  delete object;
74 #endif
75  }
76 
77  T* get() const
78  {
79  unlock();
80  return object;
81  }
82 
83  void lock() const
84  {
85 #if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION
86  vm::Protect(object, sizeof(T), PROT_NONE);
87 #endif
88  }
89 
90 private:
91  void unlock() const
92  {
93 #if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION
94  vm::Protect(object, sizeof(T), PROT_READ|PROT_WRITE);
95 #endif
96  }
97 
98  T* const object;
99 };
100 
101 #endif // #ifndef INCLUDED_ALLOCATORS_OVERRUN_PROTECTOR
#define PROT_WRITE
Definition: wmman.h:33
OverrunProtector wraps an arbitrary object in isolated page(s) and can detect inadvertent writes to i...
Definition: overrun_protector.h:52
T *const object
Definition: overrun_protector.h:98
~OverrunProtector()
Definition: overrun_protector.h:66
void lock() const
Definition: overrun_protector.h:83
OverrunProtector()
Definition: overrun_protector.h:56
bool Protect(uintptr_t address, size_t size, int prot)
set the memory protection flags for all pages that intersect the given interval.
Definition: uvm.cpp:86
void unlock() const
Definition: overrun_protector.h:91
#define T(string_literal)
Definition: secure_crt.cpp:76
NONCOPYABLE(OverrunProtector)
#define PROT_READ
Definition: wmman.h:32
void * Allocate(size_t size, PageType pageType, int prot)
reserve address space and commit memory.
Definition: uvm.cpp:98
void Free(void *p, size_t size)
decommit memory and release address space.
Definition: uvm.cpp:113
#define PROT_NONE
Definition: wmman.h:31