123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 |
- // errors.cc -- handle errors for gold
- // Copyright (C) 2006-2015 Free Software Foundation, Inc.
- // Written by Ian Lance Taylor <iant@google.com>.
- // This file is part of gold.
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; either version 3 of the License, or
- // (at your option) any later version.
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- // MA 02110-1301, USA.
- #include "gold.h"
- #include <cstdarg>
- #include <cstdio>
- #include "gold-threads.h"
- #include "parameters.h"
- #include "object.h"
- #include "symtab.h"
- #include "errors.h"
- namespace gold
- {
- // Class Errors.
- const int Errors::max_undefined_error_report;
- Errors::Errors(const char* program_name)
- : program_name_(program_name), lock_(NULL), initialize_lock_(&this->lock_),
- error_count_(0), warning_count_(0), undefined_symbols_()
- {
- }
- // Initialize the lock_ field. If we have not yet processed the
- // parameters, then we can't initialize, since we don't yet know
- // whether we are using threads. That is OK, since if we haven't
- // processed the parameters, we haven't created any threads, and we
- // don't need a lock. Return true if the lock is now initialized.
- bool
- Errors::initialize_lock()
- {
- return this->initialize_lock_.initialize();
- }
- // Increment a counter, holding the lock if available.
- void
- Errors::increment_counter(int *counter)
- {
- if (!this->initialize_lock())
- {
- // The lock does not exist, which means that we don't need it.
- ++*counter;
- }
- else
- {
- Hold_lock h(*this->lock_);
- ++*counter;
- }
- }
- // Report a fatal error.
- void
- Errors::fatal(const char* format, va_list args)
- {
- fprintf(stderr, _("%s: fatal error: "), this->program_name_);
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
- gold_exit(GOLD_ERR);
- }
- // Report a fallback error.
- void
- Errors::fallback(const char* format, va_list args)
- {
- fprintf(stderr, _("%s: fatal error: "), this->program_name_);
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
- gold_exit(GOLD_FALLBACK);
- }
- // Report an error.
- void
- Errors::error(const char* format, va_list args)
- {
- fprintf(stderr, _("%s: error: "), this->program_name_);
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
- this->increment_counter(&this->error_count_);
- }
- // Report a warning.
- void
- Errors::warning(const char* format, va_list args)
- {
- fprintf(stderr, _("%s: warning: "), this->program_name_);
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
- this->increment_counter(&this->warning_count_);
- }
- // Print an informational message.
- void
- Errors::info(const char* format, va_list args)
- {
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
- }
- // Report an error at a reloc location.
- template<int size, bool big_endian>
- void
- Errors::error_at_location(const Relocate_info<size, big_endian>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, va_list args)
- {
- fprintf(stderr, _("%s: error: "),
- relinfo->location(relnum, reloffset).c_str());
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
- this->increment_counter(&this->error_count_);
- }
- // Report a warning at a reloc location.
- template<int size, bool big_endian>
- void
- Errors::warning_at_location(const Relocate_info<size, big_endian>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, va_list args)
- {
- fprintf(stderr, _("%s: warning: "),
- relinfo->location(relnum, reloffset).c_str());
- vfprintf(stderr, format, args);
- fputc('\n', stderr);
- this->increment_counter(&this->warning_count_);
- }
- // Issue an undefined symbol error with a caller-supplied location string.
- void
- Errors::undefined_symbol(const Symbol* sym, const std::string& location)
- {
- bool initialized = this->initialize_lock();
- gold_assert(initialized);
- const char* zmsg;
- {
- Hold_lock h(*this->lock_);
- if (++this->undefined_symbols_[sym] >= max_undefined_error_report)
- return;
- if (parameters->options().warn_unresolved_symbols())
- {
- ++this->warning_count_;
- zmsg = _("warning");
- }
- else
- {
- ++this->error_count_;
- zmsg = _("error");
- }
- }
- const char* const version = sym->version();
- if (version == NULL)
- fprintf(stderr, _("%s: %s: undefined reference to '%s'\n"),
- location.c_str(), zmsg, sym->demangled_name().c_str());
- else
- fprintf(stderr,
- _("%s: %s: undefined reference to '%s', version '%s'\n"),
- location.c_str(), zmsg, sym->demangled_name().c_str(), version);
- if (sym->is_cxx_vtable())
- gold_info(_("%s: the vtable symbol may be undefined because "
- "the class is missing its key function"),
- program_name);
- }
- // Issue a debugging message.
- void
- Errors::debug(const char* format, ...)
- {
- fprintf(stderr, _("%s: "), this->program_name_);
- va_list args;
- va_start(args, format);
- vfprintf(stderr, format, args);
- va_end(args);
- fputc('\n', stderr);
- }
- // The functions which the rest of the code actually calls.
- // Report a fatal error.
- void
- gold_fatal(const char* format, ...)
- {
- va_list args;
- va_start(args, format);
- parameters->errors()->fatal(format, args);
- va_end(args);
- }
- // Report a fallback error.
- void
- gold_fallback(const char* format, ...)
- {
- va_list args;
- va_start(args, format);
- parameters->errors()->fallback(format, args);
- va_end(args);
- }
- // Report an error.
- void
- gold_error(const char* format, ...)
- {
- va_list args;
- va_start(args, format);
- parameters->errors()->error(format, args);
- va_end(args);
- }
- // Report a warning.
- void
- gold_warning(const char* format, ...)
- {
- va_list args;
- va_start(args, format);
- parameters->errors()->warning(format, args);
- va_end(args);
- }
- // Print an informational message.
- void
- gold_info(const char* format, ...)
- {
- va_list args;
- va_start(args, format);
- parameters->errors()->info(format, args);
- va_end(args);
- }
- // Report an error at a location.
- template<int size, bool big_endian>
- void
- gold_error_at_location(const Relocate_info<size, big_endian>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...)
- {
- va_list args;
- va_start(args, format);
- parameters->errors()->error_at_location(relinfo, relnum, reloffset,
- format, args);
- va_end(args);
- }
- // Report a warning at a location.
- template<int size, bool big_endian>
- void
- gold_warning_at_location(const Relocate_info<size, big_endian>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...)
- {
- va_list args;
- va_start(args, format);
- parameters->errors()->warning_at_location(relinfo, relnum, reloffset,
- format, args);
- va_end(args);
- }
- // Report an undefined symbol.
- void
- gold_undefined_symbol(const Symbol* sym)
- {
- parameters->errors()->undefined_symbol(sym, sym->object()->name().c_str());
- }
- // Report an undefined symbol at a reloc location
- template<int size, bool big_endian>
- void
- gold_undefined_symbol_at_location(const Symbol* sym,
- const Relocate_info<size, big_endian>* relinfo,
- size_t relnum, off_t reloffset)
- {
- parameters->errors()->undefined_symbol(sym,
- relinfo->location(relnum, reloffset));
- }
- #ifdef HAVE_TARGET_32_LITTLE
- template
- void
- gold_error_at_location<32, false>(const Relocate_info<32, false>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...);
- #endif
- #ifdef HAVE_TARGET_32_BIG
- template
- void
- gold_error_at_location<32, true>(const Relocate_info<32, true>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...);
- #endif
- #ifdef HAVE_TARGET_64_LITTLE
- template
- void
- gold_error_at_location<64, false>(const Relocate_info<64, false>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...);
- #endif
- #ifdef HAVE_TARGET_64_BIG
- template
- void
- gold_error_at_location<64, true>(const Relocate_info<64, true>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...);
- #endif
- #ifdef HAVE_TARGET_32_LITTLE
- template
- void
- gold_warning_at_location<32, false>(const Relocate_info<32, false>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...);
- #endif
- #ifdef HAVE_TARGET_32_BIG
- template
- void
- gold_warning_at_location<32, true>(const Relocate_info<32, true>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...);
- #endif
- #ifdef HAVE_TARGET_64_LITTLE
- template
- void
- gold_warning_at_location<64, false>(const Relocate_info<64, false>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...);
- #endif
- #ifdef HAVE_TARGET_64_BIG
- template
- void
- gold_warning_at_location<64, true>(const Relocate_info<64, true>* relinfo,
- size_t relnum, off_t reloffset,
- const char* format, ...);
- #endif
- #ifdef HAVE_TARGET_32_LITTLE
- template
- void
- gold_undefined_symbol_at_location<32, false>(
- const Symbol* sym,
- const Relocate_info<32, false>* relinfo,
- size_t relnum, off_t reloffset);
- #endif
- #ifdef HAVE_TARGET_32_BIG
- template
- void
- gold_undefined_symbol_at_location<32, true>(
- const Symbol* sym,
- const Relocate_info<32, true>* relinfo,
- size_t relnum, off_t reloffset);
- #endif
- #ifdef HAVE_TARGET_64_LITTLE
- template
- void
- gold_undefined_symbol_at_location<64, false>(
- const Symbol* sym,
- const Relocate_info<64, false>* relinfo,
- size_t relnum, off_t reloffset);
- #endif
- #ifdef HAVE_TARGET_64_BIG
- template
- void
- gold_undefined_symbol_at_location<64, true>(
- const Symbol* sym,
- const Relocate_info<64, true>* relinfo,
- size_t relnum, off_t reloffset);
- #endif
- } // End namespace gold.
|