2 /*--------------------------------------------------------------------*/
3 /*--- Machine-related stuff. m_machine.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2010 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, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_threadstate.h"
34 #include "pub_core_libcassert.h"
35 #include "pub_core_libcbase.h"
36 #include "pub_core_machine.h"
37 #include "pub_core_cpuid.h"
38 #include "pub_core_libcsignal.h" // for ppc32 messing with SIGILL and SIGFPE
39 #include "pub_core_debuglog.h"
42 #define INSTR_PTR(regs) ((regs).vex.VG_INSTR_PTR)
43 #define STACK_PTR(regs) ((regs).vex.VG_STACK_PTR)
44 #define FRAME_PTR(regs) ((regs).vex.VG_FRAME_PTR)
46 Addr VG_(get_IP) ( ThreadId tid ) {
47 return INSTR_PTR( VG_(threads)[tid].arch );
49 Addr VG_(get_SP) ( ThreadId tid ) {
50 return STACK_PTR( VG_(threads)[tid].arch );
52 Addr VG_(get_FP) ( ThreadId tid ) {
53 return FRAME_PTR( VG_(threads)[tid].arch );
56 void VG_(set_IP) ( ThreadId tid, Addr ip ) {
57 INSTR_PTR( VG_(threads)[tid].arch ) = ip;
59 void VG_(set_SP) ( ThreadId tid, Addr sp ) {
60 STACK_PTR( VG_(threads)[tid].arch ) = sp;
63 void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs,
67 regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_EIP;
68 regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_ESP;
70 = VG_(threads)[tid].arch.vex.guest_EBP;
71 # elif defined(VGA_amd64)
72 regs->r_pc = VG_(threads)[tid].arch.vex.guest_RIP;
73 regs->r_sp = VG_(threads)[tid].arch.vex.guest_RSP;
74 regs->misc.AMD64.r_rbp
75 = VG_(threads)[tid].arch.vex.guest_RBP;
76 # elif defined(VGA_ppc32)
77 regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_CIA;
78 regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_GPR1;
80 = VG_(threads)[tid].arch.vex.guest_LR;
81 # elif defined(VGA_ppc64)
82 regs->r_pc = VG_(threads)[tid].arch.vex.guest_CIA;
83 regs->r_sp = VG_(threads)[tid].arch.vex.guest_GPR1;
85 = VG_(threads)[tid].arch.vex.guest_LR;
86 # elif defined(VGA_arm)
87 regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_R15T;
88 regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_R13;
90 = VG_(threads)[tid].arch.vex.guest_R14;
92 = VG_(threads)[tid].arch.vex.guest_R12;
94 = VG_(threads)[tid].arch.vex.guest_R11;
96 # error "Unknown arch"
101 void VG_(set_syscall_return_shadows) ( ThreadId tid,
102 /* shadow vals for the result */
103 UWord s1res, UWord s2res,
104 /* shadow vals for the error val */
105 UWord s1err, UWord s2err )
107 # if defined(VGP_x86_linux) || defined (VGP_x86_l4re)
108 VG_(threads)[tid].arch.vex_shadow1.guest_EAX = s1res;
109 VG_(threads)[tid].arch.vex_shadow2.guest_EAX = s2res;
110 # elif defined(VGP_amd64_linux)
111 VG_(threads)[tid].arch.vex_shadow1.guest_RAX = s1res;
112 VG_(threads)[tid].arch.vex_shadow2.guest_RAX = s2res;
113 # elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
114 VG_(threads)[tid].arch.vex_shadow1.guest_GPR3 = s1res;
115 VG_(threads)[tid].arch.vex_shadow2.guest_GPR3 = s2res;
116 # elif defined(VGP_arm_linux)
117 VG_(threads)[tid].arch.vex_shadow1.guest_R0 = s1res;
118 VG_(threads)[tid].arch.vex_shadow2.guest_R0 = s2res;
119 # elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
120 VG_(threads)[tid].arch.vex_shadow1.guest_GPR3 = s1res;
121 VG_(threads)[tid].arch.vex_shadow2.guest_GPR3 = s2res;
122 VG_(threads)[tid].arch.vex_shadow1.guest_GPR4 = s1err;
123 VG_(threads)[tid].arch.vex_shadow2.guest_GPR4 = s2err;
124 # elif defined(VGO_darwin)
125 // GrP fixme darwin syscalls may return more values (2 registers plus error)
127 # error "Unknown plat"
132 VG_(get_shadow_regs_area) ( ThreadId tid,
134 /*SRC*/Int shadowNo, PtrdiffT offset, SizeT size )
138 vg_assert(shadowNo == 0 || shadowNo == 1 || shadowNo == 2);
139 vg_assert(VG_(is_valid_tid)(tid));
141 vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
142 vg_assert(offset + size <= sizeof(VexGuestArchState));
144 tst = & VG_(threads)[tid];
147 case 0: src = (void*)(((Addr)&(tst->arch.vex)) + offset); break;
148 case 1: src = (void*)(((Addr)&(tst->arch.vex_shadow1)) + offset); break;
149 case 2: src = (void*)(((Addr)&(tst->arch.vex_shadow2)) + offset); break;
151 tl_assert(src != NULL);
152 VG_(memcpy)( dst, src, size);
156 VG_(set_shadow_regs_area) ( ThreadId tid,
157 /*DST*/Int shadowNo, PtrdiffT offset, SizeT size,
158 /*SRC*/const UChar* src )
162 vg_assert(shadowNo == 0 || shadowNo == 1 || shadowNo == 2);
163 vg_assert(VG_(is_valid_tid)(tid));
165 vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
166 vg_assert(offset + size <= sizeof(VexGuestArchState));
168 tst = & VG_(threads)[tid];
171 case 0: dst = (void*)(((Addr)&(tst->arch.vex)) + offset); break;
172 case 1: dst = (void*)(((Addr)&(tst->arch.vex_shadow1)) + offset); break;
173 case 2: dst = (void*)(((Addr)&(tst->arch.vex_shadow2)) + offset); break;
175 tl_assert(dst != NULL);
176 VG_(memcpy)( dst, src, size);
180 static void apply_to_GPs_of_tid(VexGuestArchState* vex, void (*f)(Addr))
183 (*f)(vex->guest_EAX);
184 (*f)(vex->guest_ECX);
185 (*f)(vex->guest_EDX);
186 (*f)(vex->guest_EBX);
187 (*f)(vex->guest_ESI);
188 (*f)(vex->guest_EDI);
189 (*f)(vex->guest_ESP);
190 (*f)(vex->guest_EBP);
191 #elif defined(VGA_amd64)
192 (*f)(vex->guest_RAX);
193 (*f)(vex->guest_RCX);
194 (*f)(vex->guest_RDX);
195 (*f)(vex->guest_RBX);
196 (*f)(vex->guest_RSI);
197 (*f)(vex->guest_RDI);
198 (*f)(vex->guest_RSP);
199 (*f)(vex->guest_RBP);
202 (*f)(vex->guest_R10);
203 (*f)(vex->guest_R11);
204 (*f)(vex->guest_R12);
205 (*f)(vex->guest_R13);
206 (*f)(vex->guest_R14);
207 (*f)(vex->guest_R15);
208 #elif defined(VGA_ppc32) || defined(VGA_ppc64)
209 (*f)(vex->guest_GPR0);
210 (*f)(vex->guest_GPR1);
211 (*f)(vex->guest_GPR2);
212 (*f)(vex->guest_GPR3);
213 (*f)(vex->guest_GPR4);
214 (*f)(vex->guest_GPR5);
215 (*f)(vex->guest_GPR6);
216 (*f)(vex->guest_GPR7);
217 (*f)(vex->guest_GPR8);
218 (*f)(vex->guest_GPR9);
219 (*f)(vex->guest_GPR10);
220 (*f)(vex->guest_GPR11);
221 (*f)(vex->guest_GPR12);
222 (*f)(vex->guest_GPR13);
223 (*f)(vex->guest_GPR14);
224 (*f)(vex->guest_GPR15);
225 (*f)(vex->guest_GPR16);
226 (*f)(vex->guest_GPR17);
227 (*f)(vex->guest_GPR18);
228 (*f)(vex->guest_GPR19);
229 (*f)(vex->guest_GPR20);
230 (*f)(vex->guest_GPR21);
231 (*f)(vex->guest_GPR22);
232 (*f)(vex->guest_GPR23);
233 (*f)(vex->guest_GPR24);
234 (*f)(vex->guest_GPR25);
235 (*f)(vex->guest_GPR26);
236 (*f)(vex->guest_GPR27);
237 (*f)(vex->guest_GPR28);
238 (*f)(vex->guest_GPR29);
239 (*f)(vex->guest_GPR30);
240 (*f)(vex->guest_GPR31);
241 (*f)(vex->guest_CTR);
243 #elif defined(VGA_arm)
253 (*f)(vex->guest_R10);
254 (*f)(vex->guest_R11);
255 (*f)(vex->guest_R12);
256 (*f)(vex->guest_R13);
257 (*f)(vex->guest_R14);
264 void VG_(apply_to_GP_regs)(void (*f)(UWord))
268 for (tid = 1; tid < VG_N_THREADS; tid++) {
269 if (VG_(is_valid_tid)(tid)) {
270 ThreadState* tst = VG_(get_ThreadState)(tid);
271 apply_to_GPs_of_tid(&(tst->arch.vex), f);
276 void VG_(thread_stack_reset_iter)(/*OUT*/ThreadId* tid)
278 *tid = (ThreadId)(-1);
281 Bool VG_(thread_stack_next)(/*MOD*/ThreadId* tid,
282 /*OUT*/Addr* stack_min,
283 /*OUT*/Addr* stack_max)
286 for (i = (*tid)+1; i < VG_N_THREADS; i++) {
287 if (i == VG_INVALID_THREADID)
289 if (VG_(threads)[i].status != VgTs_Empty) {
291 *stack_min = VG_(get_SP)(i);
292 *stack_max = VG_(threads)[i].client_stack_highest_word;
299 Addr VG_(thread_get_stack_max)(ThreadId tid)
301 vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID);
302 vg_assert(VG_(threads)[tid].status != VgTs_Empty);
303 return VG_(threads)[tid].client_stack_highest_word;
306 SizeT VG_(thread_get_stack_size)(ThreadId tid)
308 vg_assert(0 <= tid && tid < VG_N_THREADS && tid != VG_INVALID_THREADID);
309 vg_assert(VG_(threads)[tid].status != VgTs_Empty);
310 return VG_(threads)[tid].client_stack_szB;
313 //-------------------------------------------------------------
314 /* Details about the capabilities of the underlying (host) CPU. These
315 details are acquired by (1) enquiring with the CPU at startup, or
316 (2) from the AT_SYSINFO entries the kernel gave us (ppc32 cache
317 line size). It's a bit nasty in the sense that there's no obvious
318 way to stop uses of some of this info before it's ready to go.
320 Current dependencies are:
322 x86: initially: call VG_(machine_get_hwcaps)
324 then safe to use VG_(machine_get_VexArchInfo)
325 and VG_(machine_x86_have_mxcsr)
327 amd64: initially: call VG_(machine_get_hwcaps)
329 then safe to use VG_(machine_get_VexArchInfo)
331 ppc32: initially: call VG_(machine_get_hwcaps)
332 call VG_(machine_ppc32_set_clszB)
334 then safe to use VG_(machine_get_VexArchInfo)
335 and VG_(machine_ppc32_has_FP)
336 and VG_(machine_ppc32_has_VMX)
338 ppc64: initially: call VG_(machine_get_hwcaps)
339 call VG_(machine_ppc64_set_clszB)
341 then safe to use VG_(machine_get_VexArchInfo)
342 and VG_(machine_ppc64_has_VMX)
344 VG_(machine_get_hwcaps) may use signals (although it attempts to
345 leave signal state unchanged) and therefore should only be
346 called before m_main sets up the client's signal state.
349 /* --------- State --------- */
350 static Bool hwcaps_done = False;
352 /* --- all archs --- */
354 static VexArchInfo vai;
357 UInt VG_(machine_x86_have_mxcsr) = 0;
359 #if defined(VGA_ppc32)
360 UInt VG_(machine_ppc32_has_FP) = 0;
361 UInt VG_(machine_ppc32_has_VMX) = 0;
363 #if defined(VGA_ppc64)
364 ULong VG_(machine_ppc64_has_VMX) = 0;
367 Int VG_(machine_arm_archlevel) = 4;
371 /* Determine what insn set and insn set variant the host has, and
372 record it. To be called once at system startup. Returns False if
373 this a CPU incapable of running Valgrind. */
375 #if defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_arm)
376 #include <setjmp.h> // For jmp_buf
377 static jmp_buf env_unsup_insn;
378 static void handler_unsup_insn ( Int x ) { __builtin_longjmp(env_unsup_insn,1); }
381 Bool VG_(machine_get_hwcaps)( void )
383 vg_assert(hwcaps_done == False);
386 // Whack default settings into vai, so that we only need to fill in
387 // any interesting bits.
388 LibVEX_default_VexArchInfo(&vai);
391 { Bool have_sse1, have_sse2, have_cx8, have_lzcnt;
392 UInt eax, ebx, ecx, edx, max_basic, max_extended;
396 if (!VG_(has_cpuid)())
397 /* we can't do cpuid at all. Give up. */
400 VG_(cpuid)(0, &eax, &ebx, &ecx, &edx);
402 /* we can't ask for cpuid(x) for x > 0. Give up. */
405 /* Get processor ID string, and max basic/extended index
408 VG_(memcpy)(&vstr[0], &ebx, 4);
409 VG_(memcpy)(&vstr[4], &edx, 4);
410 VG_(memcpy)(&vstr[8], &ecx, 4);
413 VG_(cpuid)(0x80000000, &eax, &ebx, &ecx, &edx);
416 /* get capabilities bits into edx */
417 VG_(cpuid)(1, &eax, &ebx, &ecx, &edx);
419 have_sse1 = (edx & (1<<25)) != 0; /* True => have sse insns */
420 have_sse2 = (edx & (1<<26)) != 0; /* True => have sse2 insns */
422 /* cmpxchg8b is a minimum requirement now; if we don't have it we
423 must simply give up. But all CPUs since Pentium-I have it, so
424 that doesn't seem like much of a restriction. */
425 have_cx8 = (edx & (1<<8)) != 0; /* True => have cmpxchg8b */
429 /* Figure out if this is an AMD that can do LZCNT. */
431 if (0 == VG_(strcmp)(vstr, "AuthenticAMD")
432 && max_extended >= 0x80000001) {
433 VG_(cpuid)(0x80000001, &eax, &ebx, &ecx, &edx);
434 have_lzcnt = (ecx & (1<<5)) != 0; /* True => have LZCNT */
437 if (have_sse2 && have_sse1) {
439 vai.hwcaps = VEX_HWCAPS_X86_SSE1;
440 vai.hwcaps |= VEX_HWCAPS_X86_SSE2;
442 vai.hwcaps |= VEX_HWCAPS_X86_LZCNT;
443 VG_(machine_x86_have_mxcsr) = 1;
449 vai.hwcaps = VEX_HWCAPS_X86_SSE1;
450 VG_(machine_x86_have_mxcsr) = 1;
455 vai.hwcaps = 0; /*baseline - no sse at all*/
456 VG_(machine_x86_have_mxcsr) = 0;
460 #elif defined(VGA_amd64)
461 { Bool have_sse1, have_sse2, have_sse3, have_cx8, have_cx16;
463 UInt eax, ebx, ecx, edx, max_basic, max_extended;
467 if (!VG_(has_cpuid)())
468 /* we can't do cpuid at all. Give up. */
471 VG_(cpuid)(0, &eax, &ebx, &ecx, &edx);
473 /* we can't ask for cpuid(x) for x > 0. Give up. */
476 /* Get processor ID string, and max basic/extended index
479 VG_(memcpy)(&vstr[0], &ebx, 4);
480 VG_(memcpy)(&vstr[4], &edx, 4);
481 VG_(memcpy)(&vstr[8], &ecx, 4);
484 VG_(cpuid)(0x80000000, &eax, &ebx, &ecx, &edx);
487 /* get capabilities bits into edx */
488 VG_(cpuid)(1, &eax, &ebx, &ecx, &edx);
490 have_sse1 = (edx & (1<<25)) != 0; /* True => have sse insns */
491 have_sse2 = (edx & (1<<26)) != 0; /* True => have sse2 insns */
492 have_sse3 = (ecx & (1<<0)) != 0; /* True => have sse3 insns */
497 /* cmpxchg8b is a minimum requirement now; if we don't have it we
498 must simply give up. But all CPUs since Pentium-I have it, so
499 that doesn't seem like much of a restriction. */
500 have_cx8 = (edx & (1<<8)) != 0; /* True => have cmpxchg8b */
504 /* on amd64 we tolerate older cpus, which don't have cmpxchg16b */
505 have_cx16 = (ecx & (1<<13)) != 0; /* True => have cmpxchg16b */
507 /* Figure out if this is an AMD that can do LZCNT. */
509 if (0 == VG_(strcmp)(vstr, "AuthenticAMD")
510 && max_extended >= 0x80000001) {
511 VG_(cpuid)(0x80000001, &eax, &ebx, &ecx, &edx);
512 have_lzcnt = (ecx & (1<<5)) != 0; /* True => have LZCNT */
516 vai.hwcaps = (have_sse3 ? VEX_HWCAPS_AMD64_SSE3 : 0)
517 | (have_cx16 ? VEX_HWCAPS_AMD64_CX16 : 0)
518 | (have_lzcnt ? VEX_HWCAPS_AMD64_LZCNT : 0);
522 #elif defined(VGA_ppc32)
524 /* Find out which subset of the ppc32 instruction set is supported by
525 verifying whether various ppc32 instructions generate a SIGILL
526 or a SIGFPE. An alternative approach is to check the AT_HWCAP and
527 AT_PLATFORM entries in the ELF auxiliary table -- see also
528 the_iifii.client_auxv in m_main.c.
530 vki_sigset_t saved_set, tmp_set;
531 vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
532 vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act;
534 volatile Bool have_F, have_V, have_FX, have_GX;
537 /* This is a kludge. Really we ought to back-convert saved_act
538 into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
539 since that's a no-op on all ppc32 platforms so far supported,
540 it's not worth the typing effort. At least include most basic
542 vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
544 VG_(sigemptyset)(&tmp_set);
545 VG_(sigaddset)(&tmp_set, VKI_SIGILL);
546 VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
548 r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
551 r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
553 tmp_sigill_act = saved_sigill_act;
555 r = VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
557 tmp_sigfpe_act = saved_sigfpe_act;
559 /* NODEFER: signal handler does not return (from the kernel's point of
560 view), hence if it is to successfully catch a signal more than once,
561 we need the NODEFER flag. */
562 tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
563 tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
564 tmp_sigill_act.sa_flags |= VKI_SA_NODEFER;
565 tmp_sigill_act.ksa_handler = handler_unsup_insn;
566 r = VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
569 tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND;
570 tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO;
571 tmp_sigfpe_act.sa_flags |= VKI_SA_NODEFER;
572 tmp_sigfpe_act.ksa_handler = handler_unsup_insn;
573 r = VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
576 /* standard FP insns */
578 if (__builtin_setjmp(env_unsup_insn)) {
581 __asm__ __volatile__(".long 0xFC000090"); /*fmr 0,0 */
586 if (__builtin_setjmp(env_unsup_insn)) {
589 /* Unfortunately some older assemblers don't speak Altivec (or
590 choose not to), so to be safe we directly emit the 32-bit
591 word corresponding to "vor 0,0,0". This fixes a build
592 problem that happens on Debian 3.1 (ppc32), and probably
593 various other places. */
594 __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/
597 /* General-Purpose optional (fsqrt, fsqrts) */
599 if (__builtin_setjmp(env_unsup_insn)) {
602 __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0 */
605 /* Graphics optional (stfiwx, fres, frsqrte, fsel) */
607 if (__builtin_setjmp(env_unsup_insn)) {
610 __asm__ __volatile__(".long 0xFC000034"); /* frsqrte 0,0 */
613 r = VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL);
615 r = VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL);
617 r = VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
619 VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d\n",
620 (Int)have_F, (Int)have_V, (Int)have_FX, (Int)have_GX);
621 /* Make FP a prerequisite for VMX (bogusly so), and for FX and GX. */
622 if (have_V && !have_F)
624 if (have_FX && !have_F)
626 if (have_GX && !have_F)
629 VG_(machine_ppc32_has_FP) = have_F ? 1 : 0;
630 VG_(machine_ppc32_has_VMX) = have_V ? 1 : 0;
635 if (have_F) vai.hwcaps |= VEX_HWCAPS_PPC32_F;
636 if (have_V) vai.hwcaps |= VEX_HWCAPS_PPC32_V;
637 if (have_FX) vai.hwcaps |= VEX_HWCAPS_PPC32_FX;
638 if (have_GX) vai.hwcaps |= VEX_HWCAPS_PPC32_GX;
640 /* But we're not done yet: VG_(machine_ppc32_set_clszB) must be
641 called before we're ready to go. */
645 #elif defined(VGA_ppc64)
647 /* Same instruction set detection algorithm as for ppc32. */
648 vki_sigset_t saved_set, tmp_set;
649 vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
650 vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act;
652 volatile Bool have_F, have_V, have_FX, have_GX;
655 /* This is a kludge. Really we ought to back-convert saved_act
656 into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
657 since that's a no-op on all ppc64 platforms so far supported,
658 it's not worth the typing effort. At least include most basic
660 vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
662 VG_(sigemptyset)(&tmp_set);
663 VG_(sigaddset)(&tmp_set, VKI_SIGILL);
664 VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
666 r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
669 r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
671 tmp_sigill_act = saved_sigill_act;
673 VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
674 tmp_sigfpe_act = saved_sigfpe_act;
676 /* NODEFER: signal handler does not return (from the kernel's point of
677 view), hence if it is to successfully catch a signal more than once,
678 we need the NODEFER flag. */
679 tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
680 tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
681 tmp_sigill_act.sa_flags |= VKI_SA_NODEFER;
682 tmp_sigill_act.ksa_handler = handler_unsup_insn;
683 VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
685 tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND;
686 tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO;
687 tmp_sigfpe_act.sa_flags |= VKI_SA_NODEFER;
688 tmp_sigfpe_act.ksa_handler = handler_unsup_insn;
689 VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
691 /* standard FP insns */
693 if (__builtin_setjmp(env_unsup_insn)) {
696 __asm__ __volatile__("fmr 0,0");
701 if (__builtin_setjmp(env_unsup_insn)) {
704 __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/
707 /* General-Purpose optional (fsqrt, fsqrts) */
709 if (__builtin_setjmp(env_unsup_insn)) {
712 __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0*/
715 /* Graphics optional (stfiwx, fres, frsqrte, fsel) */
717 if (__builtin_setjmp(env_unsup_insn)) {
720 __asm__ __volatile__(".long 0xFC000034"); /*frsqrte 0,0*/
723 VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL);
724 VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL);
725 VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
726 VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d\n",
727 (Int)have_F, (Int)have_V, (Int)have_FX, (Int)have_GX);
728 /* on ppc64, if we don't even have FP, just give up. */
732 VG_(machine_ppc64_has_VMX) = have_V ? 1 : 0;
737 if (have_V) vai.hwcaps |= VEX_HWCAPS_PPC64_V;
738 if (have_FX) vai.hwcaps |= VEX_HWCAPS_PPC64_FX;
739 if (have_GX) vai.hwcaps |= VEX_HWCAPS_PPC64_GX;
741 /* But we're not done yet: VG_(machine_ppc64_set_clszB) must be
742 called before we're ready to go. */
746 #elif defined(VGA_arm)
748 /* Same instruction set detection algorithm as for ppc32. */
749 vki_sigset_t saved_set, tmp_set;
750 vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
751 vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act;
753 volatile Bool have_VFP, have_VFP2, have_VFP3, have_NEON;
754 volatile Int archlevel;
757 /* This is a kludge. Really we ought to back-convert saved_act
758 into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
759 since that's a no-op on all ppc64 platforms so far supported,
760 it's not worth the typing effort. At least include most basic
762 vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
764 VG_(sigemptyset)(&tmp_set);
765 VG_(sigaddset)(&tmp_set, VKI_SIGILL);
766 VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
768 r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
771 r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
773 tmp_sigill_act = saved_sigill_act;
775 VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
776 tmp_sigfpe_act = saved_sigfpe_act;
778 /* NODEFER: signal handler does not return (from the kernel's point of
779 view), hence if it is to successfully catch a signal more than once,
780 we need the NODEFER flag. */
781 tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
782 tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
783 tmp_sigill_act.sa_flags |= VKI_SA_NODEFER;
784 tmp_sigill_act.ksa_handler = handler_unsup_insn;
785 VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
787 tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND;
788 tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO;
789 tmp_sigfpe_act.sa_flags |= VKI_SA_NODEFER;
790 tmp_sigfpe_act.ksa_handler = handler_unsup_insn;
791 VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
795 if (__builtin_setjmp(env_unsup_insn)) {
798 __asm__ __volatile__(".word 0xEEB02B42"); /* VMOV.F64 d2, d2 */
800 /* There are several generation of VFP extension but they differs very
801 little so for now we will not distinguish them. */
802 have_VFP2 = have_VFP;
803 have_VFP3 = have_VFP;
807 if (__builtin_setjmp(env_unsup_insn)) {
810 __asm__ __volatile__(".word 0xF2244154"); /* VMOV q2, q2 */
813 /* ARM architecture level */
814 archlevel = 5; /* v5 will be base level */
817 if (__builtin_setjmp(env_unsup_insn)) {
820 __asm__ __volatile__(".word 0xF45FF000"); /* PLI [PC,#-0] */
825 if (__builtin_setjmp(env_unsup_insn)) {
828 __asm__ __volatile__(".word 0xE6822012"); /* PKHBT r2, r2, r2 */
832 VG_(convert_sigaction_fromK_to_toK)(&saved_sigill_act, &tmp_sigill_act);
833 VG_(convert_sigaction_fromK_to_toK)(&saved_sigfpe_act, &tmp_sigfpe_act);
834 VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
835 VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
836 VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
838 VG_(debugLog)(1, "machine", "ARMv%d VFP %d VFP2 %d VFP3 %d NEON %d\n",
839 archlevel, (Int)have_VFP, (Int)have_VFP2, (Int)have_VFP3,
842 VG_(machine_arm_archlevel) = archlevel;
846 vai.hwcaps = VEX_ARM_ARCHLEVEL(archlevel);
847 if (have_VFP3) vai.hwcaps |= VEX_HWCAPS_ARM_VFP3;
848 if (have_VFP2) vai.hwcaps |= VEX_HWCAPS_ARM_VFP2;
849 if (have_VFP) vai.hwcaps |= VEX_HWCAPS_ARM_VFP;
850 if (have_NEON) vai.hwcaps |= VEX_HWCAPS_ARM_NEON;
856 # error "Unknown arch"
860 /* Notify host cpu cache line size. */
861 #if defined(VGA_ppc32)
862 void VG_(machine_ppc32_set_clszB)( Int szB )
864 vg_assert(hwcaps_done);
866 /* Either the value must not have been set yet (zero) or we can
867 tolerate it being set to the same value multiple times, as the
868 stack scanning logic in m_main is a bit stupid. */
869 vg_assert(vai.ppc_cache_line_szB == 0
870 || vai.ppc_cache_line_szB == szB);
872 vg_assert(szB == 32 || szB == 64 || szB == 128);
873 vai.ppc_cache_line_szB = szB;
878 /* Notify host cpu cache line size. */
879 #if defined(VGA_ppc64)
880 void VG_(machine_ppc64_set_clszB)( Int szB )
882 vg_assert(hwcaps_done);
884 /* Either the value must not have been set yet (zero) or we can
885 tolerate it being set to the same value multiple times, as the
886 stack scanning logic in m_main is a bit stupid. */
887 vg_assert(vai.ppc_cache_line_szB == 0
888 || vai.ppc_cache_line_szB == szB);
890 vg_assert(szB == 32 || szB == 64 || szB == 128);
891 vai.ppc_cache_line_szB = szB;
896 /* Fetch host cpu info, once established. */
897 void VG_(machine_get_VexArchInfo)( /*OUT*/VexArch* pVa,
898 /*OUT*/VexArchInfo* pVai )
900 vg_assert(hwcaps_done);
902 if (pVai) *pVai = vai;
906 // Given a pointer to a function as obtained by "& functionname" in C,
907 // produce a pointer to the actual entry point for the function.
908 void* VG_(fnptr_to_fnentry)( void* f )
910 #if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
911 || defined(VGP_arm_linux) \
912 || defined(VGP_ppc32_linux) || defined(VGO_darwin) \
915 #elif defined(VGP_ppc64_linux) || defined(VGP_ppc32_aix5) \
916 || defined(VGP_ppc64_aix5)
917 /* All other ppc variants use the AIX scheme, in which f is a
918 pointer to a 3-word function descriptor, of which the first word
919 is the entry address. */
920 UWord* descr = (UWord*)f;
921 return (void*)(descr[0]);
923 # error "Unknown platform"
927 /*--------------------------------------------------------------------*/
929 /*--------------------------------------------------------------------*/