LCOV - code coverage report
Current view: top level - source/lib/allocators - overrun_protector.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 8 15 53.3 %
Date: 2021-09-24 14:46:47 Functions: 2 5 40.0 %

          Line data    Source code
       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:
      56           1 :     OverrunProtector()
      57             : #if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION
      58             :         : object(new(vm::Allocate(sizeof(T))) T())
      59             : #else
      60           1 :         : object(new T())
      61             : #endif
      62             :     {
      63           1 :         lock();
      64           1 :     }
      65             : 
      66           1 :     ~OverrunProtector()
      67             :     {
      68           1 :         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           1 :         delete object;
      74             : #endif
      75           1 :     }
      76             : 
      77           0 :     T* get() const
      78             :     {
      79           0 :         unlock();
      80           0 :         return object;
      81             :     }
      82             : 
      83           0 :     void lock() const
      84             :     {
      85             : #if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION
      86             :         vm::Protect(object, sizeof(T), PROT_NONE);
      87             : #endif
      88           0 :     }
      89             : 
      90             : private:
      91           0 :     void unlock() const
      92             :     {
      93             : #if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION
      94             :         vm::Protect(object, sizeof(T), PROT_READ|PROT_WRITE);
      95             : #endif
      96           0 :     }
      97             : 
      98             :     T* const object;
      99             : };
     100             : 
     101             : #endif  // #ifndef INCLUDED_ALLOCATORS_OVERRUN_PROTECTOR

Generated by: LCOV version 1.13