// tls_test.cc -- test TLS variables for gold// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.// Written by Ian Lance Taylor <iant@google.com>.// This file is part of gold.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 3 of the License, or// (at your option) any later version.// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,// MA 02110-1301, USA.// This provides a set of test functions for TLS variables. The// functions are called by a main function in tls_test_main.cc. This// lets us test TLS access from a shared library. We currently don't// bother to test TLS access between two different files, on the// theory that that is no more complicated than ordinary variable// access between files.// We start two threads, and stop the second one. Then we run the// first thread through the following cases. Then we let the second// thread continue, and run it through the same set of cases. All the// actual thread manipulation is in tls_test_main.cc.// 1 Access to an uninitialized global thread variable.// 2 Access to an uninitialized static thread variable.// 3 Access to an initialized global thread variable.// 4 Access to an initialized static thread variable.// 5 Taking the address of a global thread variable.// 6 Taking the address of a static thread variable.// 8 Like test 1, but with the thread variable defined in another file.// 9 Like test 3, but with the thread variable defined in another file.// 10 Like test 5, but with the thread variable defined in another file.// last Verify that the above tests left the variables set correctly.#include <cstdio>#include "config.h"#include "tls_test.h"#define CHECK_EQ_OR_RETURN(var, expected) \do \{ \if ((var) != (expected)) \{ \printf(#var ": expected %d, found %d\n", expected, var); \return false; \} \} \while (0)__thread int v1;static __thread int v2;// We don't use these pointers, but putting them in tests alignment on// a 64-bit target.__thread char* p1;char dummy;__thread char* p2 = &dummy;__thread int v3 = 3;static __thread int v4 = 4;__thread int v5;static __thread int v6;struct int128{long long hi;long long lo;};static __thread struct int128 v12 = { 115, 125 };boolt1(){CHECK_EQ_OR_RETURN(v1, 0);v1 = 10;return true;}boolt2(){CHECK_EQ_OR_RETURN(v2, 0);v2 = 20;return true;}boolt3(){CHECK_EQ_OR_RETURN(v3, 3);v3 = 30;return true;}boolt4(){CHECK_EQ_OR_RETURN(v4, 4);v4 = 40;return true;}// For test 5 the main function calls f5b(f5a()), then calls t5().int*f5a(){return &v5;}voidf5b(int* p){*p = 50;}boolt5(){CHECK_EQ_OR_RETURN(v5, 50);return true;}// For test 6 the main function calls f6b(f6a()), then calls t6().int*f6a(){return &v6;}voidf6b(int* p){*p = 60;}boolt6(){CHECK_EQ_OR_RETURN(v6, 60);return true;}// The slot for t7() is unused.boolt8(){CHECK_EQ_OR_RETURN(o1, 0);o1 = -10;return true;}boolt9(){CHECK_EQ_OR_RETURN(o2, -2);o2 = -20;return true;}// For test 10 the main function calls f10b(f10a()), then calls t10().int*f10a(){return &o3;}voidf10b(int* p){*p = -30;}boolt10(){CHECK_EQ_OR_RETURN(o3, -30);return true;}boolt12(){struct int128 newval = { 335, 345 };CHECK_EQ_OR_RETURN((int) v12.hi, 115);CHECK_EQ_OR_RETURN((int) v12.lo, 125);v12 = newval;return true;}boolt_last(){CHECK_EQ_OR_RETURN(v1, 10);CHECK_EQ_OR_RETURN(v2, 20);CHECK_EQ_OR_RETURN(v3, 30);CHECK_EQ_OR_RETURN(v4, 40);CHECK_EQ_OR_RETURN(v5, 50);CHECK_EQ_OR_RETURN(v6, 60);CHECK_EQ_OR_RETURN((int) v12.hi, 335);CHECK_EQ_OR_RETURN((int) v12.lo, 345);CHECK_EQ_OR_RETURN(o1, -10);CHECK_EQ_OR_RETURN(o2, -20);CHECK_EQ_OR_RETURN(o3, -30);int check = t11_last();CHECK_EQ_OR_RETURN(check, 1);return true;}