1// basic_test.cc -- a test case 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// The goal of this program is to produce as many different types of 24// relocations as we can in a stand-alone program that does not use 25// TLS. This program is compiled without optimization. 26 27// 1 Code reference to global data. 28// 2 Code reference to static data. 29// 3 Code reference to BSS data. 30// 4 Code reference to offset within global data. 31// 5 Code reference to offset within static data. 32// 6 Code reference to offset within BSS data. 33// 7 Switch statement with a table of destinations. 34// 8 Taking the address of a label (a gcc extension). 35// 9 Taking the address of a nested function (a gcc extension). 36// 10 Data reference to global data. 37// 11 Data reference to static data. 38// 12 Data reference to BSS data. 39// 13 Data reference to offset within global data. 40// 14 Data reference to offset within static data. 41// 15 Data reference to offset within BSS data. 42// 16 Virtual table. 43// 17 Inline function. 44// 18 Call through pointer to method. 45// 19 Initialize variable to pointer to method. 46// 20 Global constructor and destructor. 47 48// 1 Code reference to global data. 49int t1 = 11; 50 51// 2 Code reference to static data. 52static int t2 = 22; 53 54// 3 Code reference to BSS data (initialized after program starts, to 55// 33). 56int t3; 57 58// 4 Code reference to offset within global data. 59char t4[] = "Hello, world"; 60 61// 5 Code reference to offset within static data. 62static char t5[] = "Hello, world"; 63 64// 6 Code reference to offset within BSS data (initialized after 65// program starts, to contents of t4). 66char t6[13]; 67 68// Test cases 1 through 6. 69 70bool 71t1_6() 72{ 73 return (t1 == 11 74 && t2 == 22 75 && t3 == 33 76 && t4[5] == ',' 77 && t5[7] == 'w' 78 && t6[9] == 'r'); 79} 80 81// 7 Switch statement with a table of destinations. 82 83int 84t7(int i) 85{ 86 switch (i) 87 { 88 case 0: 89 return 12; 90 case 1: 91 return 34; 92 case 2: 93 return 56; 94 case 3: 95 return 78; 96 case 4: 97 return 90; 98 case 5: 99 return 13; 100 case 6: 101 return 0; 102 case 7: 103 return 57; 104 case 8: 105 return 79; 106 case 9: 107 return 81; 108 default: 109 return 144; 110 } 111} 112 113// 8 Taking the address of a label (a gcc extension). 114 115int 116t8(int i) 117{ 118 for (int j = 0; j < 10; ++j) 119 { 120 void* p; 121 if (i + j > 6) 122 p = &&lab1; 123 else 124 p = &&lab2; 125 if (j == 7) 126 goto *p; 127 } 128 return 15; 129 lab1: 130 return 0; 131 lab2: 132 return 12; 133} 134 135// 9 Taking the address of a nested function (a gcc extension). 136// Disabled because this is only supported in C, not C++. 137 138int 139t9a(int (*pfn)(int)) 140{ 141 return (*pfn)(10) - 10; 142} 143 144int 145t9(int i) 146{ 147#if 0 148 int 149 t9c(int j) 150 { 151 return i + j; 152 } 153 return t9a(&t9c); 154#else 155 return i; 156#endif 157} 158 159// 10 Data reference to global data. 160int* t10 = &t1; 161 162// 11 Data reference to static data. 163int* t11 = &t2; 164 165// 12 Data reference to BSS data. 166int* t12 = &t3; 167 168// 13 Data reference to offset within global data. 169char* t13 = &t4[6]; 170 171// 14 Data reference to offset within static data. 172char* t14 = &t5[8]; 173 174// 15 Data reference to offset within BSS data. 175char* t15 = &t6[10]; 176 177// Test cases 10 through 15. 178 179bool 180t10_15() 181{ 182 return (*t10 == 11 183 && *t11 == 22 184 && *t12 == 33 185 && *t13 == ' ' 186 && *t14 == 'o' 187 && *t15 == 'l'); 188} 189 190// 16 Virtual table. 191 192class t16a 193{ 194 public: 195 virtual 196 ~t16a() 197 { } 198 virtual int 199 t() 200 { return 83; } 201}; 202 203class t16b : public t16a 204{ 205 public: 206 virtual int 207 t() 208 { return 92; } 209}; 210 211t16b t16v; 212 213bool 214t16() 215{ 216 return t16v.t() == 92; 217} 218 219// 17 Inline function. 220 221inline int 222t17a() 223{ 224 return 74; 225} 226 227bool 228t17() 229{ 230 return t17a() == 74; 231} 232 233// 18 Call through pointer to method. 234 235class t18a 236{ 237 public: 238 int 239 ta() 240 { return 65; } 241 242 int 243 tb() 244 { return 90; } 245}; 246 247t18a t18v; 248 249int 250t18f(int (t18a::* p)()) 251{ 252 return (t18v.*p)(); 253} 254 255bool 256t18() 257{ 258 return t18f(&t18a::ta) == 65; 259} 260 261// 19 Initialize variable to pointer to method. 262 263int (t18a::* t19v)() = &t18a::tb; 264 265bool 266t19() 267{ 268 return (t18v.*t19v)() == 90; 269} 270 271// 20 Global constructor and destructor. 272 273class t20a 274{ 275 public: 276 t20a() 277 : i(96) 278 { } 279 ~t20a() 280 { } 281 int 282 get() const 283 { return this->i; } 284 private: 285 int i; 286}; 287 288t20a t20v; 289 290bool 291t20() 292{ 293 return t20v.get() == 96; 294} 295 296// Main function. Initialize variables and call test functions. 297 298int 299main() 300{ 301 t3 = 33; 302 for (int i = 0; i < 13; ++i) 303 t6[i] = t4[i]; 304 305 if (t1_6() 306 && t7(6) == 0 307 && t8(0) == 0 308 && t9(5) == 5 309 && t10_15() 310 && t16() 311 && t17() 312 && t18() 313 && t19() 314 && t20()) 315 return 0; 316 else 317 return 1; 318} 319