LCOV - code coverage report
Current view: top level - vm/jit/x86_64/linux - md-os.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 73 80 91.2 %
Date: 2017-07-14 10:03:36 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /* src/vm/jit/x86_64/linux/md-os.cpp - machine dependent x86_64 Linux functions
       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             : 
      26             : #ifndef _GNU_SOURCE
      27             : # define _GNU_SOURCE
      28             : #endif
      29             : 
      30             : #include "config.h"
      31             : 
      32             : #include <cassert>
      33             : #include <cstdlib>
      34             : #include <stdint.h>
      35             : #include <ucontext.h>
      36             : 
      37             : #include "vm/types.hpp"
      38             : 
      39             : #include "vm/jit/x86_64/codegen.hpp"
      40             : #include "vm/jit/x86_64/md.hpp"
      41             : 
      42             : #include "threads/thread.hpp"
      43             : 
      44             : #include "vm/signallocal.hpp"
      45             : 
      46             : #include "vm/jit/executionstate.hpp"
      47             : #include "vm/jit/trap.hpp"
      48             : 
      49             : 
      50             : /**
      51             :  * Signal handler for hardware exception.
      52             :  */
      53      147223 : void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
      54             : {
      55      147223 :         ucontext_t* _uc = (ucontext_t *) _p;
      56      147223 :         mcontext_t* _mc = &_uc->uc_mcontext;
      57             : 
      58             :         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
      59             :            different to the ones in <ucontext.h>. */
      60             : 
      61      147223 :         void* xpc = (void*) _mc->gregs[REG_RIP];
      62             : 
      63             :         // Handle the trap.
      64      147223 :         trap_handle(TRAP_SIGSEGV, xpc, _p);
      65      147223 : }
      66             : 
      67             : 
      68             : /**
      69             :  * ArithmeticException signal handler for hardware divide by zero
      70             :  * check.
      71             :  */
      72           8 : void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
      73             : {
      74           8 :         ucontext_t* _uc = (ucontext_t *) _p;
      75           8 :         mcontext_t* _mc = &_uc->uc_mcontext;
      76             : 
      77             :         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
      78             :            different to the ones in <ucontext.h>. */
      79             : 
      80           8 :         void* xpc = (void*) _mc->gregs[REG_RIP];
      81             : 
      82             :         // Handle the trap.
      83           8 :         trap_handle(TRAP_SIGFPE, xpc, _p);
      84           8 : }
      85             : 
      86             : 
      87             : /**
      88             :  * Signal handler for patchers.
      89             :  */
      90       71147 : void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
      91             : {
      92       71147 :         ucontext_t* _uc = (ucontext_t *) _p;
      93       71147 :         mcontext_t* _mc = &_uc->uc_mcontext;
      94             : 
      95             :         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
      96             :            different to the ones in <ucontext.h>. */
      97             : 
      98       71147 :         void* xpc = (void*) _mc->gregs[REG_RIP];
      99             : 
     100             :         // Handle the trap.
     101       71147 :         trap_handle(TRAP_SIGILL, xpc, _p);
     102       71147 : }
     103             : 
     104             : 
     105             : /* md_signal_handler_sigusr2 ***************************************************
     106             : 
     107             :    Signal handler for profiling sampling.
     108             : 
     109             : *******************************************************************************/
     110             : 
     111           0 : void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
     112             : {
     113             :         threadobject *t;
     114             :         ucontext_t   *_uc;
     115             :         mcontext_t   *_mc;
     116             :         u1           *pc;
     117             : 
     118           0 :         t = THREADOBJECT;
     119             : 
     120           0 :         _uc = (ucontext_t *) _p;
     121           0 :         _mc = &_uc->uc_mcontext;
     122             : 
     123             :         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
     124             :            different to the ones in <ucontext.h>. */
     125             : 
     126           0 :         pc = (u1 *) _mc->gregs[REG_RIP];
     127             : 
     128           0 :         t->pc = pc;
     129           0 : }
     130             : 
     131             : 
     132             : /* md_executionstate_read ******************************************************
     133             : 
     134             :    Read the given context into an executionstate.
     135             : 
     136             : *******************************************************************************/
     137             : 
     138      655134 : void md_executionstate_read(executionstate_t *es, void *context)
     139             : {
     140             :         ucontext_t *_uc;
     141             :         mcontext_t *_mc;
     142             :         s4          i;
     143             :         s4          d;
     144             : 
     145      655134 :         _uc = (ucontext_t *) context;
     146      655134 :         _mc = &_uc->uc_mcontext;
     147             : 
     148             :         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
     149             :            different to the ones in <ucontext.h>. */
     150             : 
     151             :         /* read special registers */
     152      655134 :         es->pc = (u1 *) _mc->gregs[REG_RIP];
     153      655134 :         es->sp = (u1 *) _mc->gregs[REG_RSP];
     154      655134 :         es->pv = NULL;
     155             : 
     156             :         /* read integer registers */
     157    11137217 :         for (i = 0; i < INT_REG_CNT; i++) {
     158             :                 /* XXX FIX ME! */
     159             : 
     160    10482083 :                 switch (i) {
     161             :                 case 0:  /* REG_RAX == 13 */
     162      655133 :                         d = REG_RAX;
     163      655133 :                         break;
     164             :                 case 1:  /* REG_RCX == 14 */
     165      655133 :                         d = REG_RCX;
     166      655133 :                         break;
     167             :                 case 2:  /* REG_RDX == 12 */
     168      655132 :                         d = REG_RDX;
     169      655132 :                         break;
     170             :                 case 3:  /* REG_RBX == 11 */
     171      655132 :                         d = REG_RBX;
     172      655132 :                         break;
     173             :                 case 4:  /* REG_RSP == 15 */
     174      655133 :                         d = REG_RSP;
     175      655133 :                         break;
     176             :                 case 5:  /* REG_RBP == 10 */
     177      655133 :                         d = REG_RBP;
     178      655133 :                         break;
     179             :                 case 6:  /* REG_RSI == 9  */
     180      655133 :                         d = REG_RSI;
     181      655133 :                         break;
     182             :                 case 7:  /* REG_RDI == 8  */
     183      655133 :                         d = REG_RDI;
     184      655133 :                         break;
     185             :                 case 8:  /* REG_R8  == 0  */
     186             :                 case 9:  /* REG_R9  == 1  */
     187             :                 case 10: /* REG_R10 == 2  */
     188             :                 case 11: /* REG_R11 == 3  */
     189             :                 case 12: /* REG_R12 == 4  */
     190             :                 case 13: /* REG_R13 == 5  */
     191             :                 case 14: /* REG_R14 == 6  */
     192             :                 case 15: /* REG_R15 == 7  */
     193     5241063 :                         d = i - 8;
     194             :                         break;
     195             :                 }
     196             : 
     197    10482083 :                 es->intregs[i] = _mc->gregs[d];
     198             :         }
     199             : 
     200             :         /* read float registers */
     201    11137268 :         for (i = 0; i < FLT_REG_CNT; i++)
     202    10482134 :                 es->fltregs[i] = 0xdeadbeefdeadbeefL;
     203      655134 : }
     204             : 
     205             : 
     206             : /* md_executionstate_write *****************************************************
     207             : 
     208             :    Write the given executionstate back to the context.
     209             : 
     210             : *******************************************************************************/
     211             : 
     212      436755 : void md_executionstate_write(executionstate_t *es, void *context)
     213             : {
     214             :         ucontext_t *_uc;
     215             :         mcontext_t *_mc;
     216             :         s4          i;
     217             :         s4          d;
     218             : 
     219      436755 :         _uc = (ucontext_t *) context;
     220      436755 :         _mc = &_uc->uc_mcontext;
     221             : 
     222             :         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
     223             :            different to the ones in <ucontext.h>. */
     224             : 
     225             :         /* write integer registers */
     226     7424810 :         for (i = 0; i < INT_REG_CNT; i++) {
     227             :                 /* XXX FIX ME! */
     228             : 
     229     6988055 :                 switch (i) {
     230             :                 case 0:  /* REG_RAX == 13 */
     231      436755 :                         d = REG_RAX;
     232      436755 :                         break;
     233             :                 case 1:  /* REG_RCX == 14 */
     234      436755 :                         d = REG_RCX;
     235      436755 :                         break;
     236             :                 case 2:  /* REG_RDX == 12 */
     237      436755 :                         d = REG_RDX;
     238      436755 :                         break;
     239             :                 case 3:  /* REG_RBX == 11 */
     240      436755 :                         d = REG_RBX;
     241      436755 :                         break;
     242             :                 case 4:  /* REG_RSP == 15 */
     243      436755 :                         d = REG_RSP;
     244      436755 :                         break;
     245             :                 case 5:  /* REG_RBP == 10 */
     246      436755 :                         d = REG_RBP;
     247      436755 :                         break;
     248             :                 case 6:  /* REG_RSI == 9  */
     249      436755 :                         d = REG_RSI;
     250      436755 :                         break;
     251             :                 case 7:  /* REG_RDI == 8  */
     252      436755 :                         d = REG_RDI;
     253      436755 :                         break;
     254             :                 case 8:  /* REG_R8  == 0  */
     255             :                 case 9:  /* REG_R9  == 1  */
     256             :                 case 10: /* REG_R10 == 2  */
     257             :                 case 11: /* REG_R11 == 3  */
     258             :                 case 12: /* REG_R12 == 4  */
     259             :                 case 13: /* REG_R13 == 5  */
     260             :                 case 14: /* REG_R14 == 6  */
     261             :                 case 15: /* REG_R15 == 7  */
     262     3494033 :                         d = i - 8;
     263             :                         break;
     264             :                 }
     265             : 
     266     6988055 :                 _mc->gregs[d] = es->intregs[i];
     267             :         }
     268             : 
     269             :         /* write special registers */
     270      436755 :         _mc->gregs[REG_RIP] = (ptrint) es->pc;
     271      436755 :         _mc->gregs[REG_RSP] = (ptrint) es->sp;
     272      436755 : }
     273             : 
     274             : 
     275             : /*
     276             :  * These are local overrides for various environment variables in Emacs.
     277             :  * Please do not remove this and leave it at the end of the file, where
     278             :  * Emacs will automagically detect them.
     279             :  * ---------------------------------------------------------------------
     280             :  * Local variables:
     281             :  * mode: c++
     282             :  * indent-tabs-mode: t
     283             :  * c-basic-offset: 4
     284             :  * tab-width: 4
     285             :  * End:
     286             :  * vim:noexpandtab:sw=4:ts=4:
     287             :  */

Generated by: LCOV version 1.11