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-2013 OpenWorks LLP
12      info@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-linux determines page size at startup, hence m_vki is
43   the logical place to store that info. */
44
45#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
46    || defined(VGP_arm64_linux)
47unsigned long VKI_PAGE_SHIFT = 12;
48unsigned long VKI_PAGE_SIZE  = 1UL << 12;
49#endif
50
51
52/* Do initial consistency checks on some of the definitions to do with
53   signals (vki_sigset_t and vki_sigaction_{toK,fromK}_t).  This stuff
54   is fragile enough that it's important to check at startup that
55   the world looks like what we expect it to look like.
56
57   The most important thing is to check that the definition of signal
58   sets for this platform is right.  A signal set consists of some
59   number _VKI_NSIG_WORDS of 32- or 64-bit words.  Because the kernel
60   itself has some indexing scheme to set/clear individual bits in the
61   set, we must make sure we use the same layout/scheme: where this
62   requirement bites us is in the VG_(sigfillset) etc functions in
63   m_libcsignal.c.  So we check carefully here that it's all sensible.
64*/
65void VG_(vki_do_initial_consistency_checks) ( void )
66{
67   /* --- Platform-independent checks on signal sets --- */
68
69   vki_sigset_t set;
70   // Set's size must agree with _VKI_NSIG
71   vg_assert( 8 * sizeof(set) == _VKI_NSIG );
72   // Set's word size must agree with _VKI_NSIG_BPW
73   vg_assert( 8 * sizeof(set.sig[0]) == _VKI_NSIG_BPW );
74   // The set elements are 32- or 64-bit
75   vg_assert( _VKI_NSIG_BPW == 32 || _VKI_NSIG_BPW == 64 );
76
77   /* --- Platform-specific checks on signal sets --- */
78
79#  if defined(VGO_linux)
80   /* nothing to check */
81#  elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
82   vg_assert(_VKI_NSIG == NSIG);
83   vg_assert(_VKI_NSIG == 32);
84   vg_assert(_VKI_NSIG_WORDS == 1);
85   vg_assert(sizeof(sigset_t) /* defined by Darwin */
86             == sizeof(vki_sigset_t) /* what we actually use */);
87#  else
88#    error "Unknown plat"
89#  endif
90
91   /* --- Platform-specific checks on sigactions --- */
92
93#  if defined(VGO_linux)
94   /* the toK- and fromK- forms are identical */
95   vg_assert( sizeof(vki_sigaction_toK_t)
96              == sizeof(vki_sigaction_fromK_t) );
97#  elif defined(VGO_darwin)
98   /* the toK- and fromK- forms differ by one function-pointer field
99      (sa_tramp) */
100   vg_assert( sizeof(vki_sigaction_toK_t)
101              == sizeof(vki_sigaction_fromK_t) + sizeof(void*) );
102
103   vg_assert(sizeof(struct sigaction) == sizeof(vki_sigaction_fromK_t));
104   vg_assert(sizeof(struct __sigaction) == sizeof(vki_sigaction_toK_t));
105   { struct __sigaction    t1;
106     vki_sigaction_toK_t   t2;
107     struct sigaction      f1;
108     vki_sigaction_fromK_t f2;
109     vg_assert(sizeof(t1.sa_handler) == sizeof(t2.ksa_handler));
110     vg_assert(sizeof(t1.sa_tramp)   == sizeof(t2.sa_tramp));
111     vg_assert(sizeof(t1.sa_mask)    == sizeof(t2.sa_mask));
112     vg_assert(sizeof(t1.sa_flags)   == sizeof(t2.sa_flags));
113     vg_assert(sizeof(f1.sa_handler) == sizeof(f2.ksa_handler));
114     vg_assert(sizeof(f1.sa_mask)    == sizeof(f2.sa_mask));
115     vg_assert(sizeof(f1.sa_flags)   == sizeof(f2.sa_flags));
116#    if 0
117     vg_assert(offsetof(t1,sa_handler) == offsetof(t2.ksa_handler));
118     vg_assert(offsetof(t1.sa_tramp)   == offsetof(t2.sa_tramp));
119     vg_assert(offsetof(t1.sa_mask)    == offsetof(t2.sa_mask));
120     vg_assert(offsetof(t1.sa_flags)   == offsetof(t2.sa_flags));
121     vg_assert(offsetof(f1.sa_handler) == offsetof(f2.ksa_handler));
122     vg_assert(offsetof(f1.sa_mask)    == offsetof(f2.sa_mask));
123     vg_assert(offsetof(f1.sa_flags)   == offsetof(f2.sa_flags));
124#    endif
125   }
126   /* also .. */
127   /* VKI_SET_SIGMASK is hardwired into syscall-x86-darwin.S and
128      syscall-amd64-darwin.S */
129   vg_assert(VKI_SIG_SETMASK == 3);
130
131#  else
132#     error "Unknown OS"
133#  endif
134}
135
136
137/*--------------------------------------------------------------------*/
138/*--- end                                                  m_vki.c ---*/
139/*--------------------------------------------------------------------*/
140