Home | History | Annotate | Download | only in coregrind
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Notional "implementation" for m_vki.                         ---*/
      4 /*---                                                      m_vki.c ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright (C) 2006-2017 OpenWorks LLP
     12       info (at) open-works.co.uk
     13 
     14    This program is free software; you can redistribute it and/or
     15    modify it under the terms of the GNU General Public License as
     16    published by the Free Software Foundation; either version 2 of the
     17    License, or (at your option) any later version.
     18 
     19    This program is distributed in the hope that it will be useful, but
     20    WITHOUT ANY WARRANTY; without even the implied warranty of
     21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22    General Public License for more details.
     23 
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     27    02111-1307, USA.
     28 
     29    The GNU General Public License is contained in the file COPYING.
     30 */
     31 
     32 #include "pub_core_basics.h"
     33 #include "pub_core_libcassert.h"
     34 #include "pub_core_vki.h"     /* self */
     35 
     36 /* We have pub_{core,tool}_vki.h.  This is the matching implementation
     37    for that interface.  In fact there is no implementation, as the
     38    sole purpose of the module is to export types and constants
     39    describing the kernel interface, so this file is nearly empty. */
     40 
     41 
     42 /* ppc32/64, arm64 and mips32/64 (linux) determine page size at startup,
     43    hence m_vki is the logical place to store that info. */
     44 
     45 #if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
     46     || defined(VGP_ppc64le_linux) || defined(VGP_arm64_linux) \
     47     || defined(VGP_mips32_linux)  || defined(VGP_mips64_linux)
     48 unsigned long VKI_PAGE_SHIFT = 12;
     49 unsigned long VKI_PAGE_SIZE  = 1UL << 12;
     50 #endif
     51 
     52 
     53 /* Do initial consistency checks on some of the definitions to do with
     54    signals (vki_sigset_t and vki_sigaction_{toK,fromK}_t).  This stuff
     55    is fragile enough that it's important to check at startup that
     56    the world looks like what we expect it to look like.
     57 
     58    The most important thing is to check that the definition of signal
     59    sets for this platform is right.  A signal set consists of some
     60    number _VKI_NSIG_WORDS of 32- or 64-bit words.  Because the kernel
     61    itself has some indexing scheme to set/clear individual bits in the
     62    set, we must make sure we use the same layout/scheme: where this
     63    requirement bites us is in the VG_(sigfillset) etc functions in
     64    m_libcsignal.c.  So we check carefully here that it's all sensible.
     65 */
     66 void VG_(vki_do_initial_consistency_checks) ( void )
     67 {
     68    /* --- Platform-independent checks on signal sets --- */
     69 
     70    vki_sigset_t set;
     71    // Set's size must agree with _VKI_NSIG
     72    vg_assert( 8 * sizeof(set) == _VKI_NSIG );
     73    // Set's word size must agree with _VKI_NSIG_BPW
     74    vg_assert( 8 * sizeof(set.sig[0]) == _VKI_NSIG_BPW );
     75    // The set elements are 32- or 64-bit
     76    vg_assert( _VKI_NSIG_BPW == 32 || _VKI_NSIG_BPW == 64 );
     77 
     78    /* --- Platform-specific checks on signal sets --- */
     79 
     80 #  if defined(VGO_linux) || defined(VGO_solaris)
     81    /* nothing to check */
     82 #  elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
     83    vg_assert(_VKI_NSIG == NSIG);
     84    vg_assert(_VKI_NSIG == 32);
     85    vg_assert(_VKI_NSIG_WORDS == 1);
     86    vg_assert(sizeof(sigset_t) /* defined by Darwin */
     87              == sizeof(vki_sigset_t) /* what we actually use */);
     88 #  else
     89 #    error "Unknown plat"
     90 #  endif
     91 
     92    /* --- Platform-specific checks on sigactions --- */
     93 
     94 #  if defined(VGO_linux)
     95    /* the toK- and fromK- forms are identical */
     96    vg_assert( sizeof(vki_sigaction_toK_t)
     97               == sizeof(vki_sigaction_fromK_t) );
     98 #  elif defined(VGO_darwin)
     99    /* the toK- and fromK- forms differ by one function-pointer field
    100       (sa_tramp) */
    101    vg_assert( sizeof(vki_sigaction_toK_t)
    102               == sizeof(vki_sigaction_fromK_t) + sizeof(void*) );
    103 
    104    vg_assert(sizeof(struct sigaction) == sizeof(vki_sigaction_fromK_t));
    105    vg_assert(sizeof(struct __sigaction) == sizeof(vki_sigaction_toK_t));
    106    { struct __sigaction    t1;
    107      vki_sigaction_toK_t   t2;
    108      struct sigaction      f1;
    109      vki_sigaction_fromK_t f2;
    110      vg_assert(sizeof(t1.sa_handler) == sizeof(t2.ksa_handler));
    111      vg_assert(sizeof(t1.sa_tramp)   == sizeof(t2.sa_tramp));
    112      vg_assert(sizeof(t1.sa_mask)    == sizeof(t2.sa_mask));
    113      vg_assert(sizeof(t1.sa_flags)   == sizeof(t2.sa_flags));
    114      vg_assert(sizeof(f1.sa_handler) == sizeof(f2.ksa_handler));
    115      vg_assert(sizeof(f1.sa_mask)    == sizeof(f2.sa_mask));
    116      vg_assert(sizeof(f1.sa_flags)   == sizeof(f2.sa_flags));
    117 #    if 0
    118      vg_assert(offsetof(t1,sa_handler) == offsetof(t2.ksa_handler));
    119      vg_assert(offsetof(t1.sa_tramp)   == offsetof(t2.sa_tramp));
    120      vg_assert(offsetof(t1.sa_mask)    == offsetof(t2.sa_mask));
    121      vg_assert(offsetof(t1.sa_flags)   == offsetof(t2.sa_flags));
    122      vg_assert(offsetof(f1.sa_handler) == offsetof(f2.ksa_handler));
    123      vg_assert(offsetof(f1.sa_mask)    == offsetof(f2.sa_mask));
    124      vg_assert(offsetof(f1.sa_flags)   == offsetof(f2.sa_flags));
    125 #    endif
    126    }
    127    /* also .. */
    128    /* VKI_SET_SIGMASK is hardwired into syscall-x86-darwin.S and
    129       syscall-amd64-darwin.S */
    130    vg_assert(VKI_SIG_SETMASK == 3);
    131 
    132 #  elif defined(VGO_solaris)
    133    /* the toK- and fromK- forms are identical */
    134    vg_assert(sizeof(vki_sigaction_toK_t)
    135              == sizeof(vki_sigaction_fromK_t));
    136    /* VKI_SET_SIGMASK is hardwired into syscall-x86-solaris.S
    137       and syscall-amd64-solaris.S */
    138    vg_assert(VKI_SIG_SETMASK == 3);
    139 
    140 #  else
    141 #     error "Unknown OS"
    142 #  endif
    143 }
    144 
    145 
    146 /*--------------------------------------------------------------------*/
    147 /*--- end                                                  m_vki.c ---*/
    148 /*--------------------------------------------------------------------*/
    149