1 // tls_test.cc -- test TLS variables for gold 2 3 // Copyright (C) 2006-2014 Free Software Foundation, Inc. 4 // Written by Ian Lance Taylor <iant (at) google.com>. 5 6 // This file is part of gold. 7 8 // This program is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as published by 10 // the Free Software Foundation; either version 3 of the License, or 11 // (at your option) any later version. 12 13 // This program is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // You should have received a copy of the GNU General Public License 19 // along with this program; if not, write to the Free Software 20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 // MA 02110-1301, USA. 22 23 // This provides a set of test functions for TLS variables. The 24 // functions are called by a main function in tls_test_main.cc. This 25 // lets us test TLS access from a shared library. We currently don't 26 // bother to test TLS access between two different files, on the 27 // theory that that is no more complicated than ordinary variable 28 // access between files. 29 30 // We start two threads, and stop the second one. Then we run the 31 // first thread through the following cases. Then we let the second 32 // thread continue, and run it through the same set of cases. All the 33 // actual thread manipulation is in tls_test_main.cc. 34 35 // 1 Access to an uninitialized global thread variable. 36 // 2 Access to an uninitialized static thread variable. 37 // 3 Access to an initialized global thread variable. 38 // 4 Access to an initialized static thread variable. 39 // 5 Taking the address of a global thread variable. 40 // 6 Taking the address of a static thread variable. 41 // 8 Like test 1, but with the thread variable defined in another file. 42 // 9 Like test 3, but with the thread variable defined in another file. 43 // 10 Like test 5, but with the thread variable defined in another file. 44 // last Verify that the above tests left the variables set correctly. 45 46 47 #include "config.h" 48 #include <cstdio> 49 #include "tls_test.h" 50 51 #define CHECK_EQ_OR_RETURN(var, expected) \ 52 do \ 53 { \ 54 if ((var) != (expected)) \ 55 { \ 56 printf(#var ": expected %d, found %d\n", expected, var); \ 57 return false; \ 58 } \ 59 } \ 60 while (0) 61 62 __thread int v1; 63 static __thread int v2; 64 65 // We don't use these pointers, but putting them in tests alignment on 66 // a 64-bit target. 67 __thread char* p1; 68 char dummy; 69 __thread char* p2 = &dummy; 70 71 __thread int v3 = 3; 72 static __thread int v4 = 4; 73 __thread int v5; 74 static __thread int v6; 75 76 struct int128 77 { 78 long long hi; 79 long long lo; 80 }; 81 82 static __thread struct int128 v12 = { 115, 125 }; 83 84 bool 85 t1() 86 { 87 CHECK_EQ_OR_RETURN(v1, 0); 88 v1 = 10; 89 return true; 90 } 91 92 bool 93 t2() 94 { 95 CHECK_EQ_OR_RETURN(v2, 0); 96 v2 = 20; 97 return true; 98 } 99 100 bool 101 t3() 102 { 103 CHECK_EQ_OR_RETURN(v3, 3); 104 v3 = 30; 105 return true; 106 } 107 108 bool 109 t4() 110 { 111 CHECK_EQ_OR_RETURN(v4, 4); 112 v4 = 40; 113 return true; 114 } 115 116 // For test 5 the main function calls f5b(f5a()), then calls t5(). 117 118 int* 119 f5a() 120 { 121 return &v5; 122 } 123 124 void 125 f5b(int* p) 126 { 127 *p = 50; 128 } 129 130 bool 131 t5() 132 { 133 CHECK_EQ_OR_RETURN(v5, 50); 134 return true; 135 } 136 137 // For test 6 the main function calls f6b(f6a()), then calls t6(). 138 139 int* 140 f6a() 141 { 142 return &v6; 143 } 144 145 void 146 f6b(int* p) 147 { 148 *p = 60; 149 } 150 151 bool 152 t6() 153 { 154 CHECK_EQ_OR_RETURN(v6, 60); 155 return true; 156 } 157 158 // The slot for t7() is unused. 159 160 bool 161 t8() 162 { 163 CHECK_EQ_OR_RETURN(o1, 0); 164 o1 = -10; 165 return true; 166 } 167 168 bool 169 t9() 170 { 171 CHECK_EQ_OR_RETURN(o2, -2); 172 o2 = -20; 173 return true; 174 } 175 176 // For test 10 the main function calls f10b(f10a()), then calls t10(). 177 178 int* 179 f10a() 180 { 181 return &o3; 182 } 183 184 void 185 f10b(int* p) 186 { 187 *p = -30; 188 } 189 190 bool 191 t10() 192 { 193 CHECK_EQ_OR_RETURN(o3, -30); 194 return true; 195 } 196 197 bool 198 t12() 199 { 200 struct int128 newval = { 335, 345 }; 201 CHECK_EQ_OR_RETURN((int) v12.hi, 115); 202 CHECK_EQ_OR_RETURN((int) v12.lo, 125); 203 v12 = newval; 204 return true; 205 } 206 207 bool 208 t_last() 209 { 210 CHECK_EQ_OR_RETURN(v1, 10); 211 CHECK_EQ_OR_RETURN(v2, 20); 212 CHECK_EQ_OR_RETURN(v3, 30); 213 CHECK_EQ_OR_RETURN(v4, 40); 214 CHECK_EQ_OR_RETURN(v5, 50); 215 CHECK_EQ_OR_RETURN(v6, 60); 216 CHECK_EQ_OR_RETURN((int) v12.hi, 335); 217 CHECK_EQ_OR_RETURN((int) v12.lo, 345); 218 CHECK_EQ_OR_RETURN(o1, -10); 219 CHECK_EQ_OR_RETURN(o2, -20); 220 CHECK_EQ_OR_RETURN(o3, -30); 221 int check = t11_last(); 222 CHECK_EQ_OR_RETURN(check, 1); 223 return true; 224 } 225