1 // basic_test.cc -- a test case 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 // 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. 49 int t1 = 11; 50 51 // 2 Code reference to static data. 52 static int t2 = 22; 53 54 // 3 Code reference to BSS data (initialized after program starts, to 55 // 33). 56 int t3; 57 58 // 4 Code reference to offset within global data. 59 char t4[] = "Hello, world"; 60 61 // 5 Code reference to offset within static data. 62 static char t5[] = "Hello, world"; 63 64 // 6 Code reference to offset within BSS data (initialized after 65 // program starts, to contents of t4). 66 char t6[13]; 67 68 // Test cases 1 through 6. 69 70 bool 71 t1_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 83 int 84 t7(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 115 int 116 t8(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 138 int 139 t9a(int (*pfn)(int)) 140 { 141 return (*pfn)(10) - 10; 142 } 143 144 int 145 t9(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. 160 int* t10 = &t1; 161 162 // 11 Data reference to static data. 163 int* t11 = &t2; 164 165 // 12 Data reference to BSS data. 166 int* t12 = &t3; 167 168 // 13 Data reference to offset within global data. 169 char* t13 = &t4[6]; 170 171 // 14 Data reference to offset within static data. 172 char* t14 = &t5[8]; 173 174 // 15 Data reference to offset within BSS data. 175 char* t15 = &t6[10]; 176 177 // Test cases 10 through 15. 178 179 bool 180 t10_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 192 class t16a 193 { 194 public: 195 virtual 196 ~t16a() 197 { } 198 virtual int 199 t() 200 { return 83; } 201 }; 202 203 class t16b : public t16a 204 { 205 public: 206 virtual int 207 t() 208 { return 92; } 209 }; 210 211 t16b t16v; 212 213 bool 214 t16() 215 { 216 return t16v.t() == 92; 217 } 218 219 // 17 Inline function. 220 221 inline int 222 t17a() 223 { 224 return 74; 225 } 226 227 bool 228 t17() 229 { 230 return t17a() == 74; 231 } 232 233 // 18 Call through pointer to method. 234 235 class t18a 236 { 237 public: 238 int 239 ta() 240 { return 65; } 241 242 int 243 tb() 244 { return 90; } 245 }; 246 247 t18a t18v; 248 249 int 250 t18f(int (t18a::* p)()) 251 { 252 return (t18v.*p)(); 253 } 254 255 bool 256 t18() 257 { 258 return t18f(&t18a::ta) == 65; 259 } 260 261 // 19 Initialize variable to pointer to method. 262 263 int (t18a::* t19v)() = &t18a::tb; 264 265 bool 266 t19() 267 { 268 return (t18v.*t19v)() == 90; 269 } 270 271 // 20 Global constructor and destructor. 272 273 class 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 288 t20a t20v; 289 290 bool 291 t20() 292 { 293 return t20v.get() == 96; 294 } 295 296 // Main function. Initialize variables and call test functions. 297 298 int 299 main() 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