1 : /*
2 : * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 :
8 : #include <stdio.h>
9 :
10 : #include "native_client/src/include/portability.h"
11 : uint64_t test_tls_asm(void);
12 :
13 1 : int loop_ffs(int v) {
14 1 : int rv = 1;
15 1 : int mask = 1;
16 :
17 1 : while (0 != mask) {
18 1 : if (v & mask) {
19 1 : return rv;
20 : }
21 1 : mask <<= 1;
22 1 : ++rv;
23 1 : }
24 1 : return 0;
25 1 : }
26 :
27 : /*
28 : * Selectively test FFS by checking every bit while enabling every other bit.
29 : */
30 1 : int TestFFS(void) {
31 1 : unsigned int errors = 0;
32 : uint32_t x;
33 : uint32_t bits;
34 :
35 1 : bits = 0;
36 1 : for (x = 0; x <= 32; ++x) {
37 1 : bits <<= 1;
38 1 : if (x & 1) bits |= 1;
39 1 : if (loop_ffs(x) != ffs(x)) {
40 0 : printf("ERROR: differs at %d (0x%x)\n", x, x);
41 0 : errors = 1; /* if fail everywhere, errors would be UINT_MAX */
42 : }
43 1 : }
44 1 : if (loop_ffs(0) != ffs(0)) {
45 0 : printf("ERROR: differs at 0\n");
46 0 : errors = 1;
47 : }
48 1 : return errors;
49 1 : }
50 :
51 : /*
52 : * Since the Win64 version of nacl_syscall.S uses handcoded assembly to
53 : * retrieve TLS values, we need to test that assembly to ensure we don't
54 : * get surprised by undocumented changes.
55 : *
56 : * This small test is only adequate to verify that the linker trick we use in
57 : * nacl_syscal_64.S is still valid. See
58 : * src/trusted/service_runtime/nacl_tls_unittest.c for a full (and
59 : * cross-platform) test of TLS behavior.
60 : */
61 : #ifdef _WIN64
62 : THREAD uint64_t tlsValue;
63 :
64 : uint64_t test_tls_c(void) {
65 : return tlsValue;
66 : }
67 :
68 : int TestTlsAccess(void) {
69 : int errors = 0;
70 : const uint64_t kFoo = 0xF000F000F000F000;
71 : const uint64_t kBar = 0xBAAABAAABAAABAAA;
72 : uint64_t testValue;
73 :
74 : tlsValue = kFoo;
75 :
76 : testValue = test_tls_c();
77 : if (kFoo != testValue) {
78 : ++errors;
79 : }
80 :
81 : tlsValue = kBar;
82 :
83 : testValue = test_tls_asm();
84 : if (kBar != testValue) {
85 : ++errors;
86 : }
87 : return errors;
88 : }
89 : #endif
|