Home | History | Annotate | Download | only in testsuite
      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