]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/coregrind/m_machine.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / coregrind / m_machine.c
1
2 /*--------------------------------------------------------------------*/
3 /*--- Machine-related stuff.                           m_machine.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9
10    Copyright (C) 2000-2010 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 #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"
40
41
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)
45
46 Addr VG_(get_IP) ( ThreadId tid ) {
47    return INSTR_PTR( VG_(threads)[tid].arch );
48 }
49 Addr VG_(get_SP) ( ThreadId tid ) {
50    return STACK_PTR( VG_(threads)[tid].arch );
51 }
52 Addr VG_(get_FP) ( ThreadId tid ) {
53    return FRAME_PTR( VG_(threads)[tid].arch );
54 }
55
56 void VG_(set_IP) ( ThreadId tid, Addr ip ) {
57    INSTR_PTR( VG_(threads)[tid].arch ) = ip;
58 }
59 void VG_(set_SP) ( ThreadId tid, Addr sp ) {
60    STACK_PTR( VG_(threads)[tid].arch ) = sp;
61 }
62
63 void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs,
64                                 ThreadId tid )
65 {
66 #  if defined(VGA_x86)
67    regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_EIP;
68    regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_ESP;
69    regs->misc.X86.r_ebp
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;
79    regs->misc.PPC32.r_lr
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;
84    regs->misc.PPC64.r_lr
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;
89    regs->misc.ARM.r14
90       = VG_(threads)[tid].arch.vex.guest_R14;
91    regs->misc.ARM.r12
92       = VG_(threads)[tid].arch.vex.guest_R12;
93    regs->misc.ARM.r11
94       = VG_(threads)[tid].arch.vex.guest_R11;
95 #  else
96 #    error "Unknown arch"
97 #  endif
98 }
99
100
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 )
106 {
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)
126 #  else
127 #    error "Unknown plat"
128 #  endif
129 }
130
131 void
132 VG_(get_shadow_regs_area) ( ThreadId tid, 
133                             /*DST*/UChar* dst,
134                             /*SRC*/Int shadowNo, PtrdiffT offset, SizeT size )
135 {
136    void*        src;
137    ThreadState* tst;
138    vg_assert(shadowNo == 0 || shadowNo == 1 || shadowNo == 2);
139    vg_assert(VG_(is_valid_tid)(tid));
140    // Bounds check
141    vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
142    vg_assert(offset + size <= sizeof(VexGuestArchState));
143    // Copy
144    tst = & VG_(threads)[tid];
145    src = NULL;
146    switch (shadowNo) {
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;
150    }
151    tl_assert(src != NULL);
152    VG_(memcpy)( dst, src, size);
153 }
154
155 void
156 VG_(set_shadow_regs_area) ( ThreadId tid, 
157                             /*DST*/Int shadowNo, PtrdiffT offset, SizeT size,
158                             /*SRC*/const UChar* src )
159 {
160    void*        dst;
161    ThreadState* tst;
162    vg_assert(shadowNo == 0 || shadowNo == 1 || shadowNo == 2);
163    vg_assert(VG_(is_valid_tid)(tid));
164    // Bounds check
165    vg_assert(0 <= offset && offset < sizeof(VexGuestArchState));
166    vg_assert(offset + size <= sizeof(VexGuestArchState));
167    // Copy
168    tst = & VG_(threads)[tid];
169    dst = NULL;
170    switch (shadowNo) {
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;
174    }
175    tl_assert(dst != NULL);
176    VG_(memcpy)( dst, src, size);
177 }
178
179
180 static void apply_to_GPs_of_tid(VexGuestArchState* vex, void (*f)(Addr))
181 {
182 #if defined(VGA_x86)
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);
200    (*f)(vex->guest_R8);
201    (*f)(vex->guest_R9);
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);
242    (*f)(vex->guest_LR);
243 #elif defined(VGA_arm)
244    (*f)(vex->guest_R0);
245    (*f)(vex->guest_R1);
246    (*f)(vex->guest_R2);
247    (*f)(vex->guest_R3);
248    (*f)(vex->guest_R4);
249    (*f)(vex->guest_R5);
250    (*f)(vex->guest_R6);
251    (*f)(vex->guest_R8);
252    (*f)(vex->guest_R9);
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);
258 #else
259 #  error Unknown arch
260 #endif
261 }
262
263
264 void VG_(apply_to_GP_regs)(void (*f)(UWord))
265 {
266    ThreadId tid;
267
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);
272       }
273    }
274 }
275
276 void VG_(thread_stack_reset_iter)(/*OUT*/ThreadId* tid)
277 {
278    *tid = (ThreadId)(-1);
279 }
280
281 Bool VG_(thread_stack_next)(/*MOD*/ThreadId* tid,
282                             /*OUT*/Addr* stack_min, 
283                             /*OUT*/Addr* stack_max)
284 {
285    ThreadId i;
286    for (i = (*tid)+1; i < VG_N_THREADS; i++) {
287       if (i == VG_INVALID_THREADID)
288          continue;
289       if (VG_(threads)[i].status != VgTs_Empty) {
290          *tid       = i;
291          *stack_min = VG_(get_SP)(i);
292          *stack_max = VG_(threads)[i].client_stack_highest_word;
293          return True;
294       }
295    }
296    return False;
297 }
298
299 Addr VG_(thread_get_stack_max)(ThreadId tid)
300 {
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;
304 }
305
306 SizeT VG_(thread_get_stack_size)(ThreadId tid)
307 {
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;
311 }
312
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.
319
320    Current dependencies are:
321
322    x86:   initially:  call VG_(machine_get_hwcaps)
323
324           then safe to use VG_(machine_get_VexArchInfo) 
325                        and VG_(machine_x86_have_mxcsr)
326    -------------
327    amd64: initially:  call VG_(machine_get_hwcaps)
328
329           then safe to use VG_(machine_get_VexArchInfo) 
330    -------------
331    ppc32: initially:  call VG_(machine_get_hwcaps)
332                       call VG_(machine_ppc32_set_clszB)
333
334           then safe to use VG_(machine_get_VexArchInfo) 
335                        and VG_(machine_ppc32_has_FP)
336                        and VG_(machine_ppc32_has_VMX)
337    -------------
338    ppc64: initially:  call VG_(machine_get_hwcaps)
339                       call VG_(machine_ppc64_set_clszB)
340
341           then safe to use VG_(machine_get_VexArchInfo) 
342                        and VG_(machine_ppc64_has_VMX)
343
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.
347 */
348
349 /* --------- State --------- */
350 static Bool hwcaps_done = False;
351
352 /* --- all archs --- */
353 static VexArch     va;
354 static VexArchInfo vai;
355
356 #if defined(VGA_x86)
357 UInt VG_(machine_x86_have_mxcsr) = 0;
358 #endif
359 #if defined(VGA_ppc32)
360 UInt VG_(machine_ppc32_has_FP)  = 0;
361 UInt VG_(machine_ppc32_has_VMX) = 0;
362 #endif
363 #if defined(VGA_ppc64)
364 ULong VG_(machine_ppc64_has_VMX) = 0;
365 #endif
366 #if defined(VGA_arm)
367 Int VG_(machine_arm_archlevel) = 4;
368 #endif
369
370
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. */
374
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); }
379 #endif
380
381 Bool VG_(machine_get_hwcaps)( void )
382 {
383    vg_assert(hwcaps_done == False);
384    hwcaps_done = True;
385
386    // Whack default settings into vai, so that we only need to fill in
387    // any interesting bits.
388    LibVEX_default_VexArchInfo(&vai);
389
390 #if defined(VGA_x86)
391    { Bool have_sse1, have_sse2, have_cx8, have_lzcnt;
392      UInt eax, ebx, ecx, edx, max_basic, max_extended;
393      UChar vstr[13];
394      vstr[0] = 0;
395
396      if (!VG_(has_cpuid)())
397         /* we can't do cpuid at all.  Give up. */
398         return False;
399
400      VG_(cpuid)(0, &eax, &ebx, &ecx, &edx);
401      if (eax < 1)
402         /* we can't ask for cpuid(x) for x > 0.  Give up. */
403         return False;
404
405      /* Get processor ID string, and max basic/extended index
406         values. */
407      max_basic = eax;
408      VG_(memcpy)(&vstr[0], &ebx, 4);
409      VG_(memcpy)(&vstr[4], &edx, 4);
410      VG_(memcpy)(&vstr[8], &ecx, 4);
411      vstr[12] = 0;
412
413      VG_(cpuid)(0x80000000, &eax, &ebx, &ecx, &edx);
414      max_extended = eax;
415
416      /* get capabilities bits into edx */
417      VG_(cpuid)(1, &eax, &ebx, &ecx, &edx);
418
419      have_sse1 = (edx & (1<<25)) != 0; /* True => have sse insns */
420      have_sse2 = (edx & (1<<26)) != 0; /* True => have sse2 insns */
421
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 */
426      if (!have_cx8)
427         return False;
428
429      /* Figure out if this is an AMD that can do LZCNT. */
430      have_lzcnt = False;
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 */
435      }
436
437      if (have_sse2 && have_sse1) {
438         va          = VexArchX86;
439         vai.hwcaps  = VEX_HWCAPS_X86_SSE1;
440         vai.hwcaps |= VEX_HWCAPS_X86_SSE2;
441         if (have_lzcnt)
442            vai.hwcaps |= VEX_HWCAPS_X86_LZCNT;
443         VG_(machine_x86_have_mxcsr) = 1;
444         return True;
445      }
446
447      if (have_sse1) {
448         va          = VexArchX86;
449         vai.hwcaps  = VEX_HWCAPS_X86_SSE1;
450         VG_(machine_x86_have_mxcsr) = 1;
451         return True;
452      }
453
454      va         = VexArchX86;
455      vai.hwcaps = 0; /*baseline - no sse at all*/
456      VG_(machine_x86_have_mxcsr) = 0;
457      return True;
458    }
459
460 #elif defined(VGA_amd64)
461    { Bool have_sse1, have_sse2, have_sse3, have_cx8, have_cx16;
462      Bool have_lzcnt;
463      UInt eax, ebx, ecx, edx, max_basic, max_extended;
464      UChar vstr[13];
465      vstr[0] = 0;
466
467      if (!VG_(has_cpuid)())
468         /* we can't do cpuid at all.  Give up. */
469         return False;
470
471      VG_(cpuid)(0, &eax, &ebx, &ecx, &edx);
472      if (eax < 1)
473         /* we can't ask for cpuid(x) for x > 0.  Give up. */
474         return False;
475
476      /* Get processor ID string, and max basic/extended index
477         values. */
478       max_basic = eax;
479      VG_(memcpy)(&vstr[0], &ebx, 4);
480      VG_(memcpy)(&vstr[4], &edx, 4);
481      VG_(memcpy)(&vstr[8], &ecx, 4);
482      vstr[12] = 0;
483
484      VG_(cpuid)(0x80000000, &eax, &ebx, &ecx, &edx);
485      max_extended = eax;
486
487      /* get capabilities bits into edx */
488      VG_(cpuid)(1, &eax, &ebx, &ecx, &edx);
489
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 */
493      // ssse3  is ecx:9
494      // sse41  is ecx:19
495      // sse42  is ecx:20
496
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 */
501      if (!have_cx8)
502         return False;
503
504      /* on amd64 we tolerate older cpus, which don't have cmpxchg16b */
505      have_cx16 = (ecx & (1<<13)) != 0; /* True => have cmpxchg16b */
506
507      /* Figure out if this is an AMD that can do LZCNT. */
508      have_lzcnt = False;
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 */
513      }
514
515      va         = VexArchAMD64;
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);
519      return True;
520    }
521
522 #elif defined(VGA_ppc32)
523    {
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.
529       */
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;
533
534      volatile Bool have_F, have_V, have_FX, have_GX;
535      Int r;
536
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
541         sanity check: */
542      vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
543
544      VG_(sigemptyset)(&tmp_set);
545      VG_(sigaddset)(&tmp_set, VKI_SIGILL);
546      VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
547
548      r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
549      vg_assert(r == 0);
550
551      r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
552      vg_assert(r == 0);
553      tmp_sigill_act = saved_sigill_act;
554
555      r = VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
556      vg_assert(r == 0);
557      tmp_sigfpe_act = saved_sigfpe_act;
558
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);
567      vg_assert(r == 0);
568
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);
574      vg_assert(r == 0);
575
576      /* standard FP insns */
577      have_F = True;
578      if (__builtin_setjmp(env_unsup_insn)) {
579         have_F = False;
580      } else {
581         __asm__ __volatile__(".long 0xFC000090"); /*fmr 0,0 */
582      }
583
584      /* Altivec insns */
585      have_V = True;
586      if (__builtin_setjmp(env_unsup_insn)) {
587         have_V = False;
588      } else {
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*/
595      }
596
597      /* General-Purpose optional (fsqrt, fsqrts) */
598      have_FX = True;
599      if (__builtin_setjmp(env_unsup_insn)) {
600         have_FX = False;
601      } else {
602         __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0 */
603      }
604
605      /* Graphics optional (stfiwx, fres, frsqrte, fsel) */
606      have_GX = True;
607      if (__builtin_setjmp(env_unsup_insn)) {
608         have_GX = False;
609      } else {
610         __asm__ __volatile__(".long 0xFC000034"); /* frsqrte 0,0 */
611      }
612
613      r = VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL);
614      vg_assert(r == 0);
615      r = VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL);
616      vg_assert(r == 0);
617      r = VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
618      vg_assert(r == 0);
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)
623         have_V = False;
624      if (have_FX && !have_F)
625         have_FX = False;
626      if (have_GX && !have_F)
627         have_GX = False;
628
629      VG_(machine_ppc32_has_FP)  = have_F ? 1 : 0;
630      VG_(machine_ppc32_has_VMX) = have_V ? 1 : 0;
631
632      va = VexArchPPC32;
633
634      vai.hwcaps = 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;
639
640      /* But we're not done yet: VG_(machine_ppc32_set_clszB) must be
641         called before we're ready to go. */
642      return True;
643    }
644
645 #elif defined(VGA_ppc64)
646    {
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;
651
652      volatile Bool have_F, have_V, have_FX, have_GX;
653      Int r;
654
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
659         sanity check: */
660      vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
661
662      VG_(sigemptyset)(&tmp_set);
663      VG_(sigaddset)(&tmp_set, VKI_SIGILL);
664      VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
665
666      r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
667      vg_assert(r == 0);
668
669      r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
670      vg_assert(r == 0);
671      tmp_sigill_act = saved_sigill_act;
672
673      VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
674      tmp_sigfpe_act = saved_sigfpe_act;
675
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);
684
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);
690
691      /* standard FP insns */
692      have_F = True;
693      if (__builtin_setjmp(env_unsup_insn)) {
694         have_F = False;
695      } else {
696         __asm__ __volatile__("fmr 0,0");
697      }
698
699      /* Altivec insns */
700      have_V = True;
701      if (__builtin_setjmp(env_unsup_insn)) {
702         have_V = False;
703      } else {
704         __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/
705      }
706
707      /* General-Purpose optional (fsqrt, fsqrts) */
708      have_FX = True;
709      if (__builtin_setjmp(env_unsup_insn)) {
710         have_FX = False;
711      } else {
712         __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0*/
713      }
714
715      /* Graphics optional (stfiwx, fres, frsqrte, fsel) */
716      have_GX = True;
717      if (__builtin_setjmp(env_unsup_insn)) {
718         have_GX = False;
719      } else {
720         __asm__ __volatile__(".long 0xFC000034"); /*frsqrte 0,0*/
721      }
722
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. */
729      if (!have_F)
730         return False;
731
732      VG_(machine_ppc64_has_VMX) = have_V ? 1 : 0;
733
734      va = VexArchPPC64;
735
736      vai.hwcaps = 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;
740
741      /* But we're not done yet: VG_(machine_ppc64_set_clszB) must be
742         called before we're ready to go. */
743      return True;
744    }
745
746 #elif defined(VGA_arm)
747    {
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;
752
753      volatile Bool have_VFP, have_VFP2, have_VFP3, have_NEON;
754      volatile Int archlevel;
755      Int r;
756
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
761         sanity check: */
762      vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
763
764      VG_(sigemptyset)(&tmp_set);
765      VG_(sigaddset)(&tmp_set, VKI_SIGILL);
766      VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
767
768      r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
769      vg_assert(r == 0);
770
771      r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
772      vg_assert(r == 0);
773      tmp_sigill_act = saved_sigill_act;
774
775      VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
776      tmp_sigfpe_act = saved_sigfpe_act;
777
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);
786
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);
792
793      /* VFP insns */
794      have_VFP = True;
795      if (__builtin_setjmp(env_unsup_insn)) {
796         have_VFP = False;
797      } else {
798         __asm__ __volatile__(".word 0xEEB02B42"); /* VMOV.F64 d2, d2 */
799      }
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;
804
805      /* NEON insns */
806      have_NEON = True;
807      if (__builtin_setjmp(env_unsup_insn)) {
808         have_NEON = False;
809      } else {
810         __asm__ __volatile__(".word 0xF2244154"); /* VMOV q2, q2 */
811      }
812
813      /* ARM architecture level */
814      archlevel = 5; /* v5 will be base level */
815      if (archlevel < 7) {
816         archlevel = 7;
817         if (__builtin_setjmp(env_unsup_insn)) {
818            archlevel = 5;
819         } else {
820            __asm__ __volatile__(".word 0xF45FF000"); /* PLI [PC,#-0] */
821         }
822      }
823      if (archlevel < 6) {
824         archlevel = 6;
825         if (__builtin_setjmp(env_unsup_insn)) {
826            archlevel = 5;
827         } else {
828            __asm__ __volatile__(".word 0xE6822012"); /* PKHBT r2, r2, r2 */
829         }
830      }
831
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);
837
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,
840            (Int)have_NEON);
841
842      VG_(machine_arm_archlevel) = archlevel;
843
844      va = VexArchARM;
845
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;
851
852      return True;
853    }
854
855 #else
856 #  error "Unknown arch"
857 #endif
858 }
859
860 /* Notify host cpu cache line size. */
861 #if defined(VGA_ppc32)
862 void VG_(machine_ppc32_set_clszB)( Int szB )
863 {
864    vg_assert(hwcaps_done);
865
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);
871
872    vg_assert(szB == 32 || szB == 64 || szB == 128);
873    vai.ppc_cache_line_szB = szB;
874 }
875 #endif
876
877
878 /* Notify host cpu cache line size. */
879 #if defined(VGA_ppc64)
880 void VG_(machine_ppc64_set_clszB)( Int szB )
881 {
882    vg_assert(hwcaps_done);
883
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);
889
890    vg_assert(szB == 32 || szB == 64 || szB == 128);
891    vai.ppc_cache_line_szB = szB;
892 }
893 #endif
894
895
896 /* Fetch host cpu info, once established. */
897 void VG_(machine_get_VexArchInfo)( /*OUT*/VexArch* pVa,
898                                    /*OUT*/VexArchInfo* pVai )
899 {
900    vg_assert(hwcaps_done);
901    if (pVa)  *pVa  = va;
902    if (pVai) *pVai = vai;
903 }
904
905
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 )
909 {
910 #if defined(VGP_x86_linux) || defined(VGP_amd64_linux)  \
911     || defined(VGP_arm_linux)                           \
912     || defined(VGP_ppc32_linux) || defined(VGO_darwin)  \
913         || defined(VGO_l4re)
914    return f;
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]);
922 #else
923 #  error "Unknown platform"
924 #endif
925 }
926
927 /*--------------------------------------------------------------------*/
928 /*--- end                                                          ---*/
929 /*--------------------------------------------------------------------*/