1// tls_test.cc -- test TLS variables for gold 2 3// Copyright (C) 2006-2017 Free Software Foundation, Inc. 4// Written by Ian Lance Taylor <iant@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; 63static __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; 68char dummy; 69__thread char* p2 = &dummy; 70 71__thread int v3 = 3; 72static __thread int v4 = 4; 73__thread int v5; 74static __thread int v6; 75 76struct int128 77{ 78 long long hi; 79 long long lo; 80}; 81 82static __thread struct int128 v12 = { 115, 125 }; 83 84bool 85t1() 86{ 87 CHECK_EQ_OR_RETURN(v1, 0); 88 v1 = 10; 89 return true; 90} 91 92bool 93t2() 94{ 95 CHECK_EQ_OR_RETURN(v2, 0); 96 v2 = 20; 97 return true; 98} 99 100bool 101t3() 102{ 103 CHECK_EQ_OR_RETURN(v3, 3); 104 v3 = 30; 105 return true; 106} 107 108bool 109t4() 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 118int* 119f5a() 120{ 121 return &v5; 122} 123 124void 125f5b(int* p) 126{ 127 *p = 50; 128} 129 130bool 131t5() 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 139int* 140f6a() 141{ 142 return &v6; 143} 144 145void 146f6b(int* p) 147{ 148 *p = 60; 149} 150 151bool 152t6() 153{ 154 CHECK_EQ_OR_RETURN(v6, 60); 155 return true; 156} 157 158// The slot for t7() is unused. 159 160bool 161t8() 162{ 163 CHECK_EQ_OR_RETURN(o1, 0); 164 o1 = -10; 165 return true; 166} 167 168bool 169t9() 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 178int* 179f10a() 180{ 181 return &o3; 182} 183 184void 185f10b(int* p) 186{ 187 *p = -30; 188} 189 190bool 191t10() 192{ 193 CHECK_EQ_OR_RETURN(o3, -30); 194 return true; 195} 196 197bool 198t12() 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 207bool 208t_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