1 // errors.cc -- handle errors for gold 2 3 // Copyright 2006, 2007, 2008, 2009, 2010, 2011 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 #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 198 // Issue a debugging message. 199 200 void 201 Errors::debug(const char* format, ...) 202 { 203 fprintf(stderr, _("%s: "), this->program_name_); 204 205 va_list args; 206 va_start(args, format); 207 vfprintf(stderr, format, args); 208 va_end(args); 209 210 fputc('\n', stderr); 211 } 212 213 // The functions which the rest of the code actually calls. 214 215 // Report a fatal error. 216 217 void 218 gold_fatal(const char* format, ...) 219 { 220 va_list args; 221 va_start(args, format); 222 parameters->errors()->fatal(format, args); 223 va_end(args); 224 } 225 226 // Report a fallback error. 227 228 void 229 gold_fallback(const char* format, ...) 230 { 231 va_list args; 232 va_start(args, format); 233 parameters->errors()->fallback(format, args); 234 va_end(args); 235 } 236 237 // Report an error. 238 239 void 240 gold_error(const char* format, ...) 241 { 242 va_list args; 243 va_start(args, format); 244 parameters->errors()->error(format, args); 245 va_end(args); 246 } 247 248 // Report a warning. 249 250 void 251 gold_warning(const char* format, ...) 252 { 253 va_list args; 254 va_start(args, format); 255 parameters->errors()->warning(format, args); 256 va_end(args); 257 } 258 259 // Print an informational message. 260 261 void 262 gold_info(const char* format, ...) 263 { 264 va_list args; 265 va_start(args, format); 266 parameters->errors()->info(format, args); 267 va_end(args); 268 } 269 270 // Report an error at a location. 271 272 template<int size, bool big_endian> 273 void 274 gold_error_at_location(const Relocate_info<size, big_endian>* relinfo, 275 size_t relnum, off_t reloffset, 276 const char* format, ...) 277 { 278 va_list args; 279 va_start(args, format); 280 parameters->errors()->error_at_location(relinfo, relnum, reloffset, 281 format, args); 282 va_end(args); 283 } 284 285 // Report a warning at a location. 286 287 template<int size, bool big_endian> 288 void 289 gold_warning_at_location(const Relocate_info<size, big_endian>* relinfo, 290 size_t relnum, off_t reloffset, 291 const char* format, ...) 292 { 293 va_list args; 294 va_start(args, format); 295 parameters->errors()->warning_at_location(relinfo, relnum, reloffset, 296 format, args); 297 va_end(args); 298 } 299 300 // Report an undefined symbol. 301 302 void 303 gold_undefined_symbol(const Symbol* sym) 304 { 305 parameters->errors()->undefined_symbol(sym, sym->object()->name().c_str()); 306 } 307 308 // Report an undefined symbol at a reloc location 309 310 template<int size, bool big_endian> 311 void 312 gold_undefined_symbol_at_location(const Symbol* sym, 313 const Relocate_info<size, big_endian>* relinfo, 314 size_t relnum, off_t reloffset) 315 { 316 parameters->errors()->undefined_symbol(sym, 317 relinfo->location(relnum, reloffset)); 318 } 319 320 #ifdef HAVE_TARGET_32_LITTLE 321 template 322 void 323 gold_error_at_location<32, false>(const Relocate_info<32, false>* relinfo, 324 size_t relnum, off_t reloffset, 325 const char* format, ...); 326 #endif 327 328 #ifdef HAVE_TARGET_32_BIG 329 template 330 void 331 gold_error_at_location<32, true>(const Relocate_info<32, true>* relinfo, 332 size_t relnum, off_t reloffset, 333 const char* format, ...); 334 #endif 335 336 #ifdef HAVE_TARGET_64_LITTLE 337 template 338 void 339 gold_error_at_location<64, false>(const Relocate_info<64, false>* relinfo, 340 size_t relnum, off_t reloffset, 341 const char* format, ...); 342 #endif 343 344 #ifdef HAVE_TARGET_64_BIG 345 template 346 void 347 gold_error_at_location<64, true>(const Relocate_info<64, true>* relinfo, 348 size_t relnum, off_t reloffset, 349 const char* format, ...); 350 #endif 351 352 #ifdef HAVE_TARGET_32_LITTLE 353 template 354 void 355 gold_warning_at_location<32, false>(const Relocate_info<32, false>* relinfo, 356 size_t relnum, off_t reloffset, 357 const char* format, ...); 358 #endif 359 360 #ifdef HAVE_TARGET_32_BIG 361 template 362 void 363 gold_warning_at_location<32, true>(const Relocate_info<32, true>* relinfo, 364 size_t relnum, off_t reloffset, 365 const char* format, ...); 366 #endif 367 368 #ifdef HAVE_TARGET_64_LITTLE 369 template 370 void 371 gold_warning_at_location<64, false>(const Relocate_info<64, false>* relinfo, 372 size_t relnum, off_t reloffset, 373 const char* format, ...); 374 #endif 375 376 #ifdef HAVE_TARGET_64_BIG 377 template 378 void 379 gold_warning_at_location<64, true>(const Relocate_info<64, true>* relinfo, 380 size_t relnum, off_t reloffset, 381 const char* format, ...); 382 #endif 383 384 #ifdef HAVE_TARGET_32_LITTLE 385 template 386 void 387 gold_undefined_symbol_at_location<32, false>( 388 const Symbol* sym, 389 const Relocate_info<32, false>* relinfo, 390 size_t relnum, off_t reloffset); 391 #endif 392 393 #ifdef HAVE_TARGET_32_BIG 394 template 395 void 396 gold_undefined_symbol_at_location<32, true>( 397 const Symbol* sym, 398 const Relocate_info<32, true>* relinfo, 399 size_t relnum, off_t reloffset); 400 #endif 401 402 #ifdef HAVE_TARGET_64_LITTLE 403 template 404 void 405 gold_undefined_symbol_at_location<64, false>( 406 const Symbol* sym, 407 const Relocate_info<64, false>* relinfo, 408 size_t relnum, off_t reloffset); 409 #endif 410 411 #ifdef HAVE_TARGET_64_BIG 412 template 413 void 414 gold_undefined_symbol_at_location<64, true>( 415 const Symbol* sym, 416 const Relocate_info<64, true>* relinfo, 417 size_t relnum, off_t reloffset); 418 #endif 419 420 } // End namespace gold. 421