1
2/*--------------------------------------------------------------------*/
3/*--- Machine-related things.                   pub_core_machine.h ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2013 Julian Seward
11      jseward@acm.org
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31#ifndef __PUB_CORE_MACHINE_H
32#define __PUB_CORE_MACHINE_H
33
34//--------------------------------------------------------------------
35// PURPOSE: This module contains code related to the particular
36// architecture, things like accessing guest state, endianness, word size,
37// etc.
38//--------------------------------------------------------------------
39
40#include "pub_tool_machine.h"
41#include "pub_core_basics.h"      // UnwindStartRegs
42
43// XXX: this is *really* the wrong spot for these things
44#if defined(VGP_x86_linux)
45#  define VG_ELF_DATA2XXX     ELFDATA2LSB
46#  define VG_ELF_MACHINE      EM_386
47#  define VG_ELF_CLASS        ELFCLASS32
48#  undef  VG_PLAT_USES_PPCTOC
49#elif defined(VGP_amd64_linux)
50#  define VG_ELF_DATA2XXX     ELFDATA2LSB
51#  define VG_ELF_MACHINE      EM_X86_64
52#  define VG_ELF_CLASS        ELFCLASS64
53#  undef  VG_PLAT_USES_PPCTOC
54#elif defined(VGP_ppc32_linux)
55#  define VG_ELF_DATA2XXX     ELFDATA2MSB
56#  define VG_ELF_MACHINE      EM_PPC
57#  define VG_ELF_CLASS        ELFCLASS32
58#  undef  VG_PLAT_USES_PPCTOC
59#elif defined(VGP_ppc64_linux)
60#  define VG_ELF_DATA2XXX     ELFDATA2MSB
61#  define VG_ELF_MACHINE      EM_PPC64
62#  define VG_ELF_CLASS        ELFCLASS64
63#  define VG_PLAT_USES_PPCTOC 1
64#elif defined(VGP_arm_linux)
65#  define VG_ELF_DATA2XXX     ELFDATA2LSB
66#  define VG_ELF_MACHINE      EM_ARM
67#  define VG_ELF_CLASS        ELFCLASS32
68#  undef  VG_PLAT_USES_PPCTOC
69#elif defined(VGP_arm64_linux)
70#  define VG_ELF_DATA2XXX     ELFDATA2LSB
71#  define VG_ELF_MACHINE      EM_AARCH64
72#  define VG_ELF_CLASS        ELFCLASS64
73#  undef  VG_PLAT_USES_PPCTOC
74#elif defined(VGO_darwin)
75#  undef  VG_ELF_DATA2XXX
76#  undef  VG_ELF_MACHINE
77#  undef  VG_ELF_CLASS
78#  undef  VG_PLAT_USES_PPCTOC
79#elif defined(VGP_s390x_linux)
80#  define VG_ELF_DATA2XXX     ELFDATA2MSB
81#  define VG_ELF_MACHINE      EM_S390
82#  define VG_ELF_CLASS        ELFCLASS64
83#  undef  VG_PLAT_USES_PPCTOC
84#elif defined(VGP_mips32_linux)
85#  if defined (VG_LITTLEENDIAN)
86#    define VG_ELF_DATA2XXX   ELFDATA2LSB
87#  elif defined (VG_BIGENDIAN)
88#    define VG_ELF_DATA2XXX   ELFDATA2MSB
89#  else
90#    error "Unknown endianness"
91#  endif
92#  define VG_ELF_MACHINE      EM_MIPS
93#  define VG_ELF_CLASS        ELFCLASS32
94#  undef  VG_PLAT_USES_PPCTOC
95#elif defined(VGP_mips64_linux)
96#  if defined (VG_LITTLEENDIAN)
97#    define VG_ELF_DATA2XXX     ELFDATA2LSB
98#  elif defined (VG_BIGENDIAN)
99#    define VG_ELF_DATA2XXX     ELFDATA2MSB
100#  else
101#    error "Unknown endianness"
102#  endif
103#  define VG_ELF_MACHINE      EM_MIPS
104#  define VG_ELF_CLASS        ELFCLASS64
105#  undef  VG_PLAT_USES_PPCTOC
106#else
107#  error Unknown platform
108#endif
109
110#if defined(VGA_x86)
111#  define VG_INSTR_PTR        guest_EIP
112#  define VG_STACK_PTR        guest_ESP
113#  define VG_FRAME_PTR        guest_EBP
114#elif defined(VGA_amd64)
115#  define VG_INSTR_PTR        guest_RIP
116#  define VG_STACK_PTR        guest_RSP
117#  define VG_FRAME_PTR        guest_RBP
118#elif defined(VGA_ppc32)
119#  define VG_INSTR_PTR        guest_CIA
120#  define VG_STACK_PTR        guest_GPR1
121#  define VG_FRAME_PTR        guest_GPR1   // No frame ptr for PPC
122#elif defined(VGA_ppc64)
123#  define VG_INSTR_PTR        guest_CIA
124#  define VG_STACK_PTR        guest_GPR1
125#  define VG_FRAME_PTR        guest_GPR1   // No frame ptr for PPC
126#elif defined(VGA_arm)
127#  define VG_INSTR_PTR        guest_R15T
128#  define VG_STACK_PTR        guest_R13
129#  define VG_FRAME_PTR        guest_R11
130#elif defined(VGA_arm64)
131#  define VG_INSTR_PTR        guest_PC
132#  define VG_STACK_PTR        guest_XSP
133#  define VG_FRAME_PTR        guest_X29   // FIXME: is this right?
134#elif defined(VGA_s390x)
135#  define VG_INSTR_PTR        guest_IA
136#  define VG_STACK_PTR        guest_SP
137#  define VG_FRAME_PTR        guest_FP
138#  define VG_FPC_REG          guest_fpc
139#elif defined(VGA_mips32)
140#  define VG_INSTR_PTR        guest_PC
141#  define VG_STACK_PTR        guest_r29
142#  define VG_FRAME_PTR        guest_r30
143#elif defined(VGA_mips64)
144#  define VG_INSTR_PTR        guest_PC
145#  define VG_STACK_PTR        guest_r29
146#  define VG_FRAME_PTR        guest_r30
147#else
148#  error Unknown arch
149#endif
150
151
152// Offsets for the Vex state
153#define VG_O_STACK_PTR        (offsetof(VexGuestArchState, VG_STACK_PTR))
154#define VG_O_INSTR_PTR        (offsetof(VexGuestArchState, VG_INSTR_PTR))
155#define VG_O_FPC_REG          (offsetof(VexGuestArchState, VG_FPC_REG))
156
157
158//-------------------------------------------------------------
159// Guest state accessors that are not visible to tools.  The only
160// ones that are visible are get_IP and get_SP.
161
162//Addr VG_(get_IP) ( ThreadId tid );  // in pub_tool_machine.h
163//Addr VG_(get_SP) ( ThreadId tid );  // in pub_tool_machine.h
164Addr VG_(get_FP) ( ThreadId tid );
165
166void VG_(set_IP) ( ThreadId tid, Addr encip );
167void VG_(set_SP) ( ThreadId tid, Addr sp );
168
169
170//-------------------------------------------------------------
171// Get hold of the values needed for a stack unwind, for the specified
172// (client) thread.
173void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs,
174                                ThreadId tid );
175
176
177//-------------------------------------------------------------
178/* Details about the capabilities of the underlying (host) CPU.  These
179   details are acquired by (1) enquiring with the CPU at startup, or
180   (2) from the AT_SYSINFO entries the kernel gave us (ppc cache
181   line size).  It's a bit nasty in the sense that there's no obvious
182   way to stop uses of some of this info before it's ready to go.
183
184   Current dependencies are:
185
186   x86:   initially:  call VG_(machine_get_hwcaps)
187
188          then safe to use VG_(machine_get_VexArchInfo)
189                       and VG_(machine_x86_have_mxcsr)
190   -------------
191   amd64: initially:  call VG_(machine_get_hwcaps)
192
193          then safe to use VG_(machine_get_VexArchInfo)
194   -------------
195   ppc32: initially:  call VG_(machine_get_hwcaps)
196                      call VG_(machine_ppc32_set_clszB)
197
198          then safe to use VG_(machine_get_VexArchInfo)
199                       and VG_(machine_ppc32_has_FP)
200                       and VG_(machine_ppc32_has_VMX)
201   -------------
202   ppc64: initially:  call VG_(machine_get_hwcaps)
203                      call VG_(machine_ppc64_set_clszB)
204
205          then safe to use VG_(machine_get_VexArchInfo)
206                       and VG_(machine_ppc64_has_VMX)
207   -------------
208   arm:   initially:  call VG_(machine_get_hwcaps)
209                      call VG_(machine_arm_set_has_NEON)
210
211          then safe to use VG_(machine_get_VexArchInfo)
212   -------------
213   s390x: initially:  call VG_(machine_get_hwcaps)
214
215          then safe to use VG_(machine_get_VexArchInfo)
216
217   VG_(machine_get_hwcaps) may use signals (although it attempts to
218   leave signal state unchanged) and therefore should only be
219   called before m_main sets up the client's signal state.
220*/
221
222/* Determine what insn set and insn set variant the host has, and
223   record it.  To be called once at system startup.  Returns False if
224   this a CPU incapable of running Valgrind. */
225extern Bool VG_(machine_get_hwcaps)( void );
226
227/* Determine information about the cache system this host has and
228   record it. Returns False, if cache information cannot be auto-detected. */
229extern Bool VG_(machine_get_cache_info)( VexArchInfo * );
230
231/* Notify host cpu cache line size, as per above comment. */
232#if defined(VGA_ppc32)
233extern void VG_(machine_ppc32_set_clszB)( Int );
234#endif
235
236#if defined(VGA_ppc64)
237extern void VG_(machine_ppc64_set_clszB)( Int );
238#endif
239
240#if defined(VGA_arm)
241extern void VG_(machine_arm_set_has_NEON)( Bool );
242#endif
243
244/* X86: set to 1 if the host is able to do {ld,st}mxcsr (load/store
245   the SSE control/status register), else zero.  Is referenced from
246   assembly code, so do not change from a 32-bit int. */
247#if defined(VGA_x86)
248extern UInt VG_(machine_x86_have_mxcsr);
249#endif
250
251/* PPC32: set to 1 if FP instructions are supported in user-space,
252   else 0.  Is referenced from assembly code, so do not change from a
253   32-bit int. */
254#if defined(VGA_ppc32)
255extern UInt VG_(machine_ppc32_has_FP);
256#endif
257
258/* PPC32: set to 1 if Altivec instructions are supported in
259   user-space, else 0.  Is referenced from assembly code, so do not
260   change from a 32-bit int. */
261#if defined(VGA_ppc32)
262extern UInt VG_(machine_ppc32_has_VMX);
263#endif
264
265/* PPC64: set to 1 if Altivec instructions are supported in
266   user-space, else 0.  Is referenced from assembly code, so do not
267   change from a 64-bit int. */
268#if defined(VGA_ppc64)
269extern ULong VG_(machine_ppc64_has_VMX);
270#endif
271
272#if defined(VGA_arm)
273extern Int VG_(machine_arm_archlevel);
274#endif
275
276#endif   // __PUB_CORE_MACHINE_H
277
278/*--------------------------------------------------------------------*/
279/*--- end                                                          ---*/
280/*--------------------------------------------------------------------*/
281