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