errors.cc 9.8 KB

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