1 // errors.cc -- handle errors 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 #include "gold.h" 24 25 #include <cstdarg> 26 #include <cstdio> 27 28 #include "gold-threads.h" 29 #include "parameters.h" 30 #include "object.h" 31 #include "symtab.h" 32 #include "errors.h" 33 34 namespace gold 35 { 36 37 // Class Errors. 38 39 const int Errors::max_undefined_error_report; 40 41 Errors::Errors(const char* program_name) 42 : program_name_(program_name), lock_(NULL), initialize_lock_(&this->lock_), 43 error_count_(0), warning_count_(0), undefined_symbols_() 44 { 45 } 46 47 // Initialize the lock_ field. If we have not yet processed the 48 // parameters, then we can't initialize, since we don't yet know 49 // whether we are using threads. That is OK, since if we haven't 50 // processed the parameters, we haven't created any threads, and we 51 // don't need a lock. Return true if the lock is now initialized. 52 53 bool 54 Errors::initialize_lock() 55 { 56 return this->initialize_lock_.initialize(); 57 } 58 59 // Increment a counter, holding the lock if available. 60 61 void 62 Errors::increment_counter(int *counter) 63 { 64 if (!this->initialize_lock()) 65 { 66 // The lock does not exist, which means that we don't need it. 67 ++*counter; 68 } 69 else 70 { 71 Hold_lock h(*this->lock_); 72 ++*counter; 73 } 74 } 75 76 // Report a fatal error. 77 78 void 79 Errors::fatal(const char* format, va_list args) 80 { 81 fprintf(stderr, _("%s: fatal error: "), this->program_name_); 82 vfprintf(stderr, format, args); 83 fputc('\n', stderr); 84 gold_exit(GOLD_ERR); 85 } 86 87 // Report a fallback error. 88 89 void 90 Errors::fallback(const char* format, va_list args) 91 { 92 fprintf(stderr, _("%s: fatal error: "), this->program_name_); 93 vfprintf(stderr, format, args); 94 fputc('\n', stderr); 95 gold_exit(GOLD_FALLBACK); 96 } 97 98 // Report an error. 99 100 void 101 Errors::error(const char* format, va_list args) 102 { 103 fprintf(stderr, _("%s: error: "), this->program_name_); 104 vfprintf(stderr, format, args); 105 fputc('\n', stderr); 106 107 this->increment_counter(&this->error_count_); 108 } 109 110 // Report a warning. 111 112 void 113 Errors::warning(const char* format, va_list args) 114 { 115 fprintf(stderr, _("%s: warning: "), this->program_name_); 116 vfprintf(stderr, format, args); 117 fputc('\n', stderr); 118 119 this->increment_counter(&this->warning_count_); 120 } 121 122 // Print an informational message. 123 124 void 125 Errors::info(const char* format, va_list args) 126 { 127 vfprintf(stderr, format, args); 128 fputc('\n', stderr); 129 } 130 131 // Report an error at a reloc location. 132 133 template<int size, bool big_endian> 134 void 135 Errors::error_at_location(const Relocate_info<size, big_endian>* relinfo, 136 size_t relnum, off_t reloffset, 137 const char* format, va_list args) 138 { 139 fprintf(stderr, _("%s: error: "), 140 relinfo->location(relnum, reloffset).c_str()); 141 vfprintf(stderr, format, args); 142 fputc('\n', stderr); 143 144 this->increment_counter(&this->error_count_); 145 } 146 147 // Report a warning at a reloc location. 148 149 template<int size, bool big_endian> 150 void 151 Errors::warning_at_location(const Relocate_info<size, big_endian>* relinfo, 152 size_t relnum, off_t reloffset, 153 const char* format, va_list args) 154 { 155 fprintf(stderr, _("%s: warning: "), 156 relinfo->location(relnum, reloffset).c_str()); 157 vfprintf(stderr, format, args); 158 fputc('\n', stderr); 159 160 this->increment_counter(&this->warning_count_); 161 } 162 163 // Issue an undefined symbol error with a caller-supplied location string. 164 165 void 166 Errors::undefined_symbol(const Symbol* sym, const std::string& location) 167 { 168 bool initialized = this->initialize_lock(); 169 gold_assert(initialized); 170 171 const char* zmsg; 172 { 173 Hold_lock h(*this->lock_); 174 if (++this->undefined_symbols_[sym] >= max_undefined_error_report) 175 return; 176 if (parameters->options().warn_unresolved_symbols()) 177 { 178 ++this->warning_count_; 179 zmsg = _("warning"); 180 } 181 else 182 { 183 ++this->error_count_; 184 zmsg = _("error"); 185 } 186 } 187 188 const char* const version = sym->version(); 189 if (version == NULL) 190 fprintf(stderr, _("%s: %s: undefined reference to '%s'\n"), 191 location.c_str(), zmsg, sym->demangled_name().c_str()); 192 else 193 fprintf(stderr, 194 _("%s: %s: undefined reference to '%s', version '%s'\n"), 195 location.c_str(), zmsg, sym->demangled_name().c_str(), version); 196 197 if (sym->is_cxx_vtable()) 198 gold_info(_("%s: the vtable symbol may be undefined because " 199 "the class is missing its key function" 200 " (see go/missingkeymethod)"), 201 program_name); 202 } 203 204 // Issue a debugging message. 205 206 void 207 Errors::debug(const char* format, ...) 208 { 209 fprintf(stderr, _("%s: "), this->program_name_); 210 211 va_list args; 212 va_start(args, format); 213 vfprintf(stderr, format, args); 214 va_end(args); 215 216 fputc('\n', stderr); 217 } 218 219 // The functions which the rest of the code actually calls. 220 221 // Report a fatal error. 222 223 void 224 gold_fatal(const char* format, ...) 225 { 226 va_list args; 227 va_start(args, format); 228 parameters->errors()->fatal(format, args); 229 va_end(args); 230 } 231 232 // Report a fallback error. 233 234 void 235 gold_fallback(const char* format, ...) 236 { 237 va_list args; 238 va_start(args, format); 239 parameters->errors()->fallback(format, args); 240 va_end(args); 241 } 242 243 // Report an error. 244 245 void 246 gold_error(const char* format, ...) 247 { 248 va_list args; 249 va_start(args, format); 250 parameters->errors()->error(format, args); 251 va_end(args); 252 } 253 254 // Report a warning. 255 256 void 257 gold_warning(const char* format, ...) 258 { 259 va_list args; 260 va_start(args, format); 261 parameters->errors()->warning(format, args); 262 va_end(args); 263 } 264 265 // Print an informational message. 266 267 void 268 gold_info(const char* format, ...) 269 { 270 va_list args; 271 va_start(args, format); 272 parameters->errors()->info(format, args); 273 va_end(args); 274 } 275 276 // Report an error at a location. 277 278 template<int size, bool big_endian> 279 void 280 gold_error_at_location(const Relocate_info<size, big_endian>* relinfo, 281 size_t relnum, off_t reloffset, 282 const char* format, ...) 283 { 284 va_list args; 285 va_start(args, format); 286 parameters->errors()->error_at_location(relinfo, relnum, reloffset, 287 format, args); 288 va_end(args); 289 } 290 291 // Report a warning at a location. 292 293 template<int size, bool big_endian> 294 void 295 gold_warning_at_location(const Relocate_info<size, big_endian>* relinfo, 296 size_t relnum, off_t reloffset, 297 const char* format, ...) 298 { 299 va_list args; 300 va_start(args, format); 301 parameters->errors()->warning_at_location(relinfo, relnum, reloffset, 302 format, args); 303 va_end(args); 304 } 305 306 // Report an undefined symbol. 307 308 void 309 gold_undefined_symbol(const Symbol* sym) 310 { 311 parameters->errors()->undefined_symbol(sym, sym->object()->name().c_str()); 312 } 313 314 // Report an undefined symbol at a reloc location 315 316 template<int size, bool big_endian> 317 void 318 gold_undefined_symbol_at_location(const Symbol* sym, 319 const Relocate_info<size, big_endian>* relinfo, 320 size_t relnum, off_t reloffset) 321 { 322 parameters->errors()->undefined_symbol(sym, 323 relinfo->location(relnum, reloffset)); 324 } 325 326 #ifdef HAVE_TARGET_32_LITTLE 327 template 328 void 329 gold_error_at_location<32, false>(const Relocate_info<32, false>* relinfo, 330 size_t relnum, off_t reloffset, 331 const char* format, ...); 332 #endif 333 334 #ifdef HAVE_TARGET_32_BIG 335 template 336 void 337 gold_error_at_location<32, true>(const Relocate_info<32, true>* relinfo, 338 size_t relnum, off_t reloffset, 339 const char* format, ...); 340 #endif 341 342 #ifdef HAVE_TARGET_64_LITTLE 343 template 344 void 345 gold_error_at_location<64, false>(const Relocate_info<64, false>* relinfo, 346 size_t relnum, off_t reloffset, 347 const char* format, ...); 348 #endif 349 350 #ifdef HAVE_TARGET_64_BIG 351 template 352 void 353 gold_error_at_location<64, true>(const Relocate_info<64, true>* relinfo, 354 size_t relnum, off_t reloffset, 355 const char* format, ...); 356 #endif 357 358 #ifdef HAVE_TARGET_32_LITTLE 359 template 360 void 361 gold_warning_at_location<32, false>(const Relocate_info<32, false>* relinfo, 362 size_t relnum, off_t reloffset, 363 const char* format, ...); 364 #endif 365 366 #ifdef HAVE_TARGET_32_BIG 367 template 368 void 369 gold_warning_at_location<32, true>(const Relocate_info<32, true>* relinfo, 370 size_t relnum, off_t reloffset, 371 const char* format, ...); 372 #endif 373 374 #ifdef HAVE_TARGET_64_LITTLE 375 template 376 void 377 gold_warning_at_location<64, false>(const Relocate_info<64, false>* relinfo, 378 size_t relnum, off_t reloffset, 379 const char* format, ...); 380 #endif 381 382 #ifdef HAVE_TARGET_64_BIG 383 template 384 void 385 gold_warning_at_location<64, true>(const Relocate_info<64, true>* relinfo, 386 size_t relnum, off_t reloffset, 387 const char* format, ...); 388 #endif 389 390 #ifdef HAVE_TARGET_32_LITTLE 391 template 392 void 393 gold_undefined_symbol_at_location<32, false>( 394 const Symbol* sym, 395 const Relocate_info<32, false>* relinfo, 396 size_t relnum, off_t reloffset); 397 #endif 398 399 #ifdef HAVE_TARGET_32_BIG 400 template 401 void 402 gold_undefined_symbol_at_location<32, true>( 403 const Symbol* sym, 404 const Relocate_info<32, true>* relinfo, 405 size_t relnum, off_t reloffset); 406 #endif 407 408 #ifdef HAVE_TARGET_64_LITTLE 409 template 410 void 411 gold_undefined_symbol_at_location<64, false>( 412 const Symbol* sym, 413 const Relocate_info<64, false>* relinfo, 414 size_t relnum, off_t reloffset); 415 #endif 416 417 #ifdef HAVE_TARGET_64_BIG 418 template 419 void 420 gold_undefined_symbol_at_location<64, true>( 421 const Symbol* sym, 422 const Relocate_info<64, true>* relinfo, 423 size_t relnum, off_t reloffset); 424 #endif 425 426 } // End namespace gold. 427