2 /*--------------------------------------------------------------------*/
3 /*--- Machine-related things. pub_core_machine.h ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2017 Julian Seward
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.
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.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #ifndef __PUB_CORE_MACHINE_H
30 #define __PUB_CORE_MACHINE_H
32 //--------------------------------------------------------------------
33 // PURPOSE: This module contains code related to the particular
34 // architecture, things like accessing guest state, endianness, word size,
36 //--------------------------------------------------------------------
38 #include "pub_tool_machine.h"
39 #include "pub_core_basics.h" // UnwindStartRegs
41 // XXX: this is *really* the wrong spot for these things
42 #if defined(VGP_x86_linux) || defined(VGP_x86_solaris)
43 # define VG_ELF_DATA2XXX ELFDATA2LSB
44 # define VG_ELF_MACHINE EM_386
45 # define VG_ELF_CLASS ELFCLASS32
46 # undef VG_PLAT_USES_PPCTOC
47 #elif defined(VGP_amd64_linux) || defined(VGP_amd64_solaris)
48 # define VG_ELF_DATA2XXX ELFDATA2LSB
49 # define VG_ELF_MACHINE EM_X86_64
50 # define VG_ELF_CLASS ELFCLASS64
51 # undef VG_PLAT_USES_PPCTOC
52 #elif defined(VGP_ppc32_linux)
53 # define VG_ELF_DATA2XXX ELFDATA2MSB
54 # define VG_ELF_MACHINE EM_PPC
55 # define VG_ELF_CLASS ELFCLASS32
56 # undef VG_PLAT_USES_PPCTOC
57 #elif defined(VGP_ppc64be_linux)
58 # define VG_ELF_DATA2XXX ELFDATA2MSB
59 # define VG_ELF_MACHINE EM_PPC64
60 # define VG_ELF_CLASS ELFCLASS64
61 # define VG_PLAT_USES_PPCTOC 1
62 #elif defined(VGP_ppc64le_linux)
63 # define VG_ELF_DATA2XXX ELFDATA2LSB
64 # define VG_ELF_MACHINE EM_PPC64
65 # define VG_ELF_CLASS ELFCLASS64
66 # undef VG_PLAT_USES_PPCTOC
67 #elif defined(VGP_arm_linux)
68 # define VG_ELF_DATA2XXX ELFDATA2LSB
69 # define VG_ELF_MACHINE EM_ARM
70 # define VG_ELF_CLASS ELFCLASS32
71 # undef VG_PLAT_USES_PPCTOC
72 #elif defined(VGP_arm64_linux)
73 # define VG_ELF_DATA2XXX ELFDATA2LSB
74 # define VG_ELF_MACHINE EM_AARCH64
75 # define VG_ELF_CLASS ELFCLASS64
76 # undef VG_PLAT_USES_PPCTOC
77 #elif defined(VGO_darwin)
78 # undef VG_ELF_DATA2XXX
79 # undef VG_ELF_MACHINE
81 # undef VG_PLAT_USES_PPCTOC
82 #elif defined(VGP_s390x_linux)
83 # define VG_ELF_DATA2XXX ELFDATA2MSB
84 # define VG_ELF_MACHINE EM_S390
85 # define VG_ELF_CLASS ELFCLASS64
86 # undef VG_PLAT_USES_PPCTOC
87 #elif defined(VGP_mips32_linux)
88 # if defined (VG_LITTLEENDIAN)
89 # define VG_ELF_DATA2XXX ELFDATA2LSB
90 # elif defined (VG_BIGENDIAN)
91 # define VG_ELF_DATA2XXX ELFDATA2MSB
93 # error "Unknown endianness"
95 # define VG_ELF_MACHINE EM_MIPS
96 # define VG_ELF_CLASS ELFCLASS32
97 # undef VG_PLAT_USES_PPCTOC
98 #elif defined(VGP_mips64_linux)
99 # if defined (VG_LITTLEENDIAN)
100 # define VG_ELF_DATA2XXX ELFDATA2LSB
101 # elif defined (VG_BIGENDIAN)
102 # define VG_ELF_DATA2XXX ELFDATA2MSB
104 # error "Unknown endianness"
106 # define VG_ELF_MACHINE EM_MIPS
107 # if defined(VGABI_N32)
108 # define VG_ELF_CLASS ELFCLASS32
109 # elif defined(VGABI_64)
110 # define VG_ELF_CLASS ELFCLASS64
112 # error Unknown mips64 abi
114 # undef VG_PLAT_USES_PPCTOC
115 #elif defined(VGP_nanomips_linux)
116 # if defined (VG_LITTLEENDIAN)
117 # define VG_ELF_DATA2XXX ELFDATA2LSB
118 # elif defined (VG_BIGENDIAN)
119 # define VG_ELF_DATA2XXX ELFDATA2MSB
121 # error "Unknown endianness"
123 # if !defined(EM_NANOMIPS)
124 # define EM_NANOMIPS 249 /* MIPS Tech nanoMIPS */
126 # define VG_ELF_MACHINE EM_NANOMIPS
127 # define VG_ELF_CLASS ELFCLASS32
128 # undef VG_PLAT_USES_PPCTOC
130 # error Unknown platform
134 # define VG_INSTR_PTR guest_EIP
135 # define VG_STACK_PTR guest_ESP
136 # define VG_FRAME_PTR guest_EBP
137 #elif defined(VGA_amd64)
138 # define VG_INSTR_PTR guest_RIP
139 # define VG_STACK_PTR guest_RSP
140 # define VG_FRAME_PTR guest_RBP
141 #elif defined(VGA_ppc32)
142 # define VG_INSTR_PTR guest_CIA
143 # define VG_STACK_PTR guest_GPR1
144 # define VG_FRAME_PTR guest_GPR1 // No frame ptr for PPC
145 #elif defined(VGA_ppc64be) || defined(VGA_ppc64le)
146 # define VG_INSTR_PTR guest_CIA
147 # define VG_STACK_PTR guest_GPR1
148 # define VG_FRAME_PTR guest_GPR1 // No frame ptr for PPC
149 #elif defined(VGA_arm)
150 # define VG_INSTR_PTR guest_R15T
151 # define VG_STACK_PTR guest_R13
152 # define VG_FRAME_PTR guest_R11
153 #elif defined(VGA_arm64)
154 # define VG_INSTR_PTR guest_PC
155 # define VG_STACK_PTR guest_XSP
156 # define VG_FRAME_PTR guest_X29 // FIXME: is this right?
157 #elif defined(VGA_s390x)
158 # define VG_INSTR_PTR guest_IA
159 # define VG_STACK_PTR guest_SP
160 # define VG_FRAME_PTR guest_FP
161 # define VG_FPC_REG guest_fpc
162 #elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips)
163 # define VG_INSTR_PTR guest_PC
164 # define VG_STACK_PTR guest_r29
165 # define VG_FRAME_PTR guest_r30
171 // Offsets for the Vex state
172 #define VG_O_STACK_PTR (offsetof(VexGuestArchState, VG_STACK_PTR))
173 #define VG_O_INSTR_PTR (offsetof(VexGuestArchState, VG_INSTR_PTR))
174 #define VG_O_FRAME_PTR (offsetof(VexGuestArchState, VG_FRAME_PTR))
175 #define VG_O_FPC_REG (offsetof(VexGuestArchState, VG_FPC_REG))
178 //-------------------------------------------------------------
179 // Guest state accessors that are not visible to tools. The only
180 // ones that are visible are get_IP and get_SP.
182 //Addr VG_(get_IP) ( ThreadId tid ); // in pub_tool_machine.h
183 //Addr VG_(get_SP) ( ThreadId tid ); // in pub_tool_machine.h
184 Addr
VG_(get_FP
) ( ThreadId tid
);
186 void VG_(set_IP
) ( ThreadId tid
, Addr encip
);
187 void VG_(set_SP
) ( ThreadId tid
, Addr sp
);
190 //-------------------------------------------------------------
191 // Get hold of the values needed for a stack unwind, for the specified
193 void VG_(get_UnwindStartRegs
) ( /*OUT*/UnwindStartRegs
* regs
,
197 //-------------------------------------------------------------
198 /* Details about the capabilities of the underlying (host) CPU. These
199 details are acquired by (1) enquiring with the CPU at startup, or
200 (2) from the AT_SYSINFO entries the kernel gave us (ppc cache
201 line size). It's a bit nasty in the sense that there's no obvious
202 way to stop uses of some of this info before it's ready to go.
204 Current dependencies are:
206 x86: initially: call VG_(machine_get_hwcaps)
208 then safe to use VG_(machine_get_VexArchInfo)
209 and VG_(machine_x86_have_mxcsr)
211 amd64: initially: call VG_(machine_get_hwcaps)
213 then safe to use VG_(machine_get_VexArchInfo)
215 ppc32: initially: call VG_(machine_get_hwcaps)
216 call VG_(machine_ppc32_set_clszB)
218 then safe to use VG_(machine_get_VexArchInfo)
219 and VG_(machine_ppc32_has_FP)
220 and VG_(machine_ppc32_has_VMX)
222 ppc64: initially: call VG_(machine_get_hwcaps)
223 call VG_(machine_ppc64_set_clszB)
225 then safe to use VG_(machine_get_VexArchInfo)
226 and VG_(machine_ppc64_has_VMX)
228 arm: initially: call VG_(machine_get_hwcaps)
229 call VG_(machine_arm_set_has_NEON)
231 then safe to use VG_(machine_get_VexArchInfo)
233 s390x: initially: call VG_(machine_get_hwcaps)
235 then safe to use VG_(machine_get_VexArchInfo)
237 VG_(machine_get_hwcaps) may use signals (although it attempts to
238 leave signal state unchanged) and therefore should only be
239 called before m_main sets up the client's signal state.
242 /* Determine what insn set and insn set variant the host has, and
243 record it. To be called once at system startup. Returns False if
244 this a CPU incapable of running Valgrind. */
245 extern Bool
VG_(machine_get_hwcaps
)( void );
247 /* Determine information about the cache system this host has and
248 record it. Returns False, if cache information cannot be auto-detected. */
249 extern Bool
VG_(machine_get_cache_info
)( VexArchInfo
* );
251 /* Notify host cpu cache line size, as per above comment. */
252 #if defined(VGA_ppc32)
253 extern void VG_(machine_ppc32_set_clszB
)( Int
);
256 #if defined(VGA_ppc64be) || defined(VGA_ppc64le)
257 extern void VG_(machine_ppc64_set_clszB
)( Int
);
261 extern void VG_(machine_arm_set_has_NEON
)( Bool
);
264 /* X86: set to 1 if the host is able to do {ld,st}mxcsr (load/store
265 the SSE control/status register), else zero. Is referenced from
266 assembly code, so do not change from a 32-bit int. */
268 extern UInt
VG_(machine_x86_have_mxcsr
);
271 /* PPC32: set to 1 if FP instructions are supported in user-space,
272 else 0. Is referenced from assembly code, so do not change from a
274 #if defined(VGA_ppc32)
275 extern UInt
VG_(machine_ppc32_has_FP
);
278 /* PPC32: set to 1 if Altivec instructions are supported in
279 user-space, else 0. Is referenced from assembly code, so do not
280 change from a 32-bit int. */
281 #if defined(VGA_ppc32)
282 extern UInt
VG_(machine_ppc32_has_VMX
);
285 /* PPC64: set to 1 if Altivec instructions are supported in
286 user-space, else 0. Is referenced from assembly code, so do not
287 change from a 64-bit int. */
288 #if defined(VGA_ppc64be) || defined(VGA_ppc64le)
289 extern ULong
VG_(machine_ppc64_has_VMX
);
293 extern Int
VG_(machine_arm_archlevel
);
296 #endif // __PUB_CORE_MACHINE_H
298 /*--------------------------------------------------------------------*/
300 /*--------------------------------------------------------------------*/