LCOV - code coverage report
Current view: top level - vm/jit - PatcherNew.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 20 37 54.1 %
Date: 2017-07-14 10:03:36 Functions: 7 21 33.3 %

          Line data    Source code
       1             : /* src/vm/jit/PatcherNew.hpp - Patcher class
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             : 
       6             :    This file is part of CACAO.
       7             : 
       8             :    This program is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU General Public License as
      10             :    published by the Free Software Foundation; either version 2, or (at
      11             :    your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful, but
      14             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program; if not, write to the Free Software
      20             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      21             :    02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #ifndef _PATCHERNEW_HPP
      26             : #define _PATCHERNEW_HPP
      27             : 
      28             : #include "vm/jit/patcher-common.hpp"
      29             : 
      30             : namespace cacao {
      31             : 
      32             : // forward declaration
      33             : class OStream;
      34             : 
      35             : /**
      36             :  * Patcher super class
      37             :  *
      38             :  * This class is intended to replace the patchref_t patcher references.
      39             :  * The goal is to replace function pointers by virtual functions and
      40             :  * void pointers by member variables. Although we need a vtbl_ptr for
      41             :  * virtual functions and a smart pointer for list storage this might even
      42             :  * reduce the overall memory consumption because not all fields of patchref_t
      43             :  * are needed by all patchers. But the main focus is on encapsulation and
      44             :  * usability.
      45             :  *
      46             :  * @todo Remove/adopt the text above if the legacy patchref_t framework has
      47             :  * been removed.
      48             :  */
      49             : class Patcher {
      50             : private:
      51             :         bool done;
      52             :         /**
      53             :          * This function performs the patching.
      54             :          */
      55             :         virtual bool patch_impl() = 0;
      56             : public:
      57             :         Patcher();
      58             :         virtual ~Patcher();
      59             : 
      60             :         /**
      61             :          * This a wrapper to set the done flag.
      62             :          */
      63       71142 :         bool patch() {
      64       71142 :                 if (patch_impl()) {
      65       71129 :                         done = true;
      66       71129 :                         return true;
      67             :                 }
      68          13 :                 return false;
      69             :         }
      70             :         /**
      71             :          * get the absolute position in code segment
      72             :          *
      73             :          * @deprecated
      74             :          */
      75             :         virtual uintptr_t get_mpc() const = 0;
      76             :         /**
      77             :          * Generates the code for the patcher traps.
      78             :          */
      79             :         virtual void emit() = 0;
      80             :         /**
      81             :          * reposition to another base
      82             :          */
      83             :         virtual void reposition(intptr_t base) = 0;
      84             :         /**
      85             :          * Check already patched
      86             :          *
      87             :          * In contrast to check_is_patched this method simply
      88             :          * queries a boolean variable whereas check_is_patched
      89             :          * inspects to machine code.
      90             :          *
      91             :          * @see check_is_patched
      92             :          */
      93       71146 :         bool is_patched() const {
      94       71146 :                 return done;
      95             :         }
      96             :         /**
      97             :          * Check if the patcher is already patched.
      98             :          *
      99             :          * This is done by comparing the machine instruction.
     100             :          *
     101             :          * @return true if patched, false otherwise.
     102             :          * @see is_patched
     103             :          */
     104             :         virtual bool check_is_patched() const = 0;
     105             :         /**
     106             :          * print patcher information
     107             :          */
     108             :         virtual const char* get_name() const;
     109             :         /**
     110             :          * print patcher information
     111             :          */
     112             :         virtual OStream& print(OStream &OS) const;
     113             : };
     114             : 
     115           0 : class LegacyPatcher : public Patcher {
     116             : private:
     117             :         jitdata *jd;
     118             :         patchref_t pr;
     119             : 
     120             :         /**
     121             :          * Call the legacy patching function
     122             :          */
     123       71142 :         virtual bool patch_impl() {
     124             :                 // define the patcher function
     125             :                 bool (*patcher_function)(patchref_t *);
     126             :                 // cast the passed function to a patcher function
     127       71142 :                 patcher_function = (bool (*)(patchref_t *)) (ptrint) pr.patcher;
     128             : 
     129       71142 :                 return (patcher_function)(&pr);
     130             :         }
     131             : 
     132             : public:
     133             : 
     134      142524 :         LegacyPatcher(jitdata *jd, const patchref_t &pr)
     135      142524 :                 : Patcher(), jd(jd), pr(pr) {}
     136             : 
     137             :         /**
     138             :          * return the raw resource
     139             :          */
     140      142524 :         patchref_t* get() {
     141      142524 :                 return ≺
     142             :         }
     143             : 
     144     5755676 :         virtual uintptr_t get_mpc() const {
     145     5755676 :                 return pr.mpc;
     146             :         }
     147             :         virtual void emit();
     148      142524 :         virtual void reposition(intptr_t base) {
     149      142524 :                 pr.mpc   += base;
     150      142524 :                 pr.datap  = (intptr_t) (pr.disp + base);
     151      142524 :         }
     152             :         /**
     153             :          * Check if the patcher is already patched.
     154             :          *
     155             :          * This is done by comparing the machine instruction.
     156             :          *
     157             :          * @return true if patched, false otherwise.
     158             :          */
     159             :         virtual bool check_is_patched() const;
     160             : 
     161             :         virtual const char* get_name() const;
     162             :         virtual OStream& print(OStream &OS) const;
     163             : };
     164             : 
     165             : /**
     166             :  * Base class for all (non-legacy) patcher
     167             :  */
     168           0 : class PatcherBase : public Patcher {
     169             : private:
     170             :         uint32_t  mcode;
     171             :         uintptr_t mpc;
     172             : public:
     173           0 :         PatcherBase() : Patcher(), mcode(0), mpc(0) {}
     174             :         explicit PatcherBase(uintptr_t mpc) : Patcher(), mcode(0), mpc(mpc) {}
     175             : 
     176           0 :         virtual void set_mcode(uint32_t mcode) {
     177           0 :                 this->mcode = mcode;
     178           0 :         }
     179             :         #if 0
     180             :         virtual uintptr_t get_mcode() const {
     181             :                 return mcode;
     182             :         }
     183             :         #endif
     184           0 :         virtual uintptr_t get_mpc() const {
     185           0 :                 return mpc;
     186             :         }
     187           0 :         virtual void reposition(intptr_t base) {
     188           0 :                 this->mpc   += base;
     189           0 :         }
     190           0 :         virtual const char* get_name() const {
     191           0 :                 return "PatcherBase";
     192             :         }
     193             : };
     194             : 
     195           0 : class InitializeClassPatcher : public PatcherBase {
     196             : private:
     197             :         classinfo *c;
     198             : 
     199             :         virtual bool patch_impl();
     200             : public:
     201             :         virtual void emit();
     202             :         virtual bool check_is_patched() const;
     203           0 :         InitializeClassPatcher(classinfo *c) : c(c) {}
     204           0 :         virtual const char* get_name() const {
     205           0 :                 return "InitializeClassPatcher";
     206             :         }
     207             : };
     208             : 
     209             : } // end namespace cacao
     210             : 
     211             : #endif // _PATCHERNEW_HPP
     212             : 
     213             : 
     214             : /*
     215             :  * These are local overrides for various environment variables in Emacs.
     216             :  * Please do not remove this and leave it at the end of the file, where
     217             :  * Emacs will automagically detect them.
     218             :  * ---------------------------------------------------------------------
     219             :  * Local variables:
     220             :  * mode: c++
     221             :  * indent-tabs-mode: t
     222             :  * c-basic-offset: 4
     223             :  * tab-width: 4
     224             :  * End:
     225             :  * vim:noexpandtab:sw=4:ts=4:
     226             :  */

Generated by: LCOV version 1.11