diff --git a/gold/Makefile.am b/gold/Makefile.am index e9508de15e5..1c549867811 100644 --- a/gold/Makefile.am +++ b/gold/Makefile.am @@ -30,6 +30,7 @@ CCFILES = \ dirsearch.cc \ dynobj.cc \ ehframe.cc \ + errors.cc \ fileread.cc \ gold.cc \ gold-threads.cc \ @@ -56,6 +57,7 @@ HFILES = \ dirsearch.h \ dynobj.h \ ehframe.h \ + errors.h \ fileread.h \ gold.h \ gold-threads.h \ diff --git a/gold/Makefile.in b/gold/Makefile.in index 8c979bef1b4..5f0bac3b05c 100644 --- a/gold/Makefile.in +++ b/gold/Makefile.in @@ -72,12 +72,13 @@ libgold_a_AR = $(AR) $(ARFLAGS) libgold_a_LIBADD = am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) defstd.$(OBJEXT) \ dirsearch.$(OBJEXT) dynobj.$(OBJEXT) ehframe.$(OBJEXT) \ - fileread.$(OBJEXT) gold.$(OBJEXT) gold-threads.$(OBJEXT) \ - layout.$(OBJEXT) merge.$(OBJEXT) object.$(OBJEXT) \ - options.$(OBJEXT) output.$(OBJEXT) parameters.$(OBJEXT) \ - readsyms.$(OBJEXT) reloc.$(OBJEXT) resolve.$(OBJEXT) \ - script.$(OBJEXT) symtab.$(OBJEXT) stringpool.$(OBJEXT) \ - target-select.$(OBJEXT) version.$(OBJEXT) workqueue.$(OBJEXT) + errors.$(OBJEXT) fileread.$(OBJEXT) gold.$(OBJEXT) \ + gold-threads.$(OBJEXT) layout.$(OBJEXT) merge.$(OBJEXT) \ + object.$(OBJEXT) options.$(OBJEXT) output.$(OBJEXT) \ + parameters.$(OBJEXT) readsyms.$(OBJEXT) reloc.$(OBJEXT) \ + resolve.$(OBJEXT) script.$(OBJEXT) symtab.$(OBJEXT) \ + stringpool.$(OBJEXT) target-select.$(OBJEXT) version.$(OBJEXT) \ + workqueue.$(OBJEXT) am__objects_2 = am__objects_3 = yyscript.$(OBJEXT) am_libgold_a_OBJECTS = $(am__objects_1) $(am__objects_2) \ @@ -283,6 +284,7 @@ CCFILES = \ dirsearch.cc \ dynobj.cc \ ehframe.cc \ + errors.cc \ fileread.cc \ gold.cc \ gold-threads.cc \ @@ -309,6 +311,7 @@ HFILES = \ dirsearch.h \ dynobj.h \ ehframe.h \ + errors.h \ fileread.h \ gold.h \ gold-threads.h \ @@ -457,6 +460,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirsearch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynobj.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehframe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gold-threads.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gold.Po@am__quote@ diff --git a/gold/archive.cc b/gold/archive.cc index d80718db758..e7a87824080 100644 --- a/gold/archive.cc +++ b/gold/archive.cc @@ -78,20 +78,15 @@ Archive::setup() // The first member of the archive should be the symbol table. std::string armap_name; off_t armap_size = this->read_header(sarmag, &armap_name); - off_t off; + off_t off = sarmag; if (armap_name.empty()) { this->read_armap(sarmag + sizeof(Archive_header), armap_size); off = sarmag + sizeof(Archive_header) + armap_size; } else if (!this->input_file_->options().include_whole_archive()) - { - fprintf(stderr, _("%s: %s: no archive symbol table (run ranlib)\n"), - program_name, this->name().c_str()); - gold_exit(false); - } - else - off = sarmag; + gold_error(_("%s: no archive symbol table (run ranlib)"), + this->name().c_str()); // See if there is an extended name table. if ((off & 1) != 0) @@ -140,11 +135,8 @@ Archive::read_armap(off_t start, off_t size) } if (reinterpret_cast(pnames) - p > size) - { - fprintf(stderr, _("%s: %s: bad archive symbol table names\n"), - program_name, this->name().c_str()); - gold_exit(false); - } + gold_error(_("%s: bad archive symbol table names"), + this->name().c_str()); // This array keeps track of which symbols are for archive elements // which we have already included in the link. @@ -173,10 +165,9 @@ Archive::interpret_header(const Archive_header* hdr, off_t off, { if (memcmp(hdr->ar_fmag, arfmag, sizeof arfmag) != 0) { - fprintf(stderr, _("%s; %s: malformed archive header at %ld\n"), - program_name, this->name().c_str(), - static_cast(off)); - gold_exit(false); + gold_error(_("%s: malformed archive header at %zu"), + this->name().c_str(), static_cast(off)); + return this->input_file_->file().filesize() - off; } const int size_string_size = sizeof hdr->ar_size; @@ -194,10 +185,9 @@ Archive::interpret_header(const Archive_header* hdr, off_t off, || member_size < 0 || (member_size == LONG_MAX && errno == ERANGE)) { - fprintf(stderr, _("%s: %s: malformed archive header size at %ld\n"), - program_name, this->name().c_str(), - static_cast(off)); - gold_exit(false); + gold_error(_("%s: malformed archive header size at %zu"), + this->name().c_str(), static_cast(off)); + return this->input_file_->file().filesize() - off; } if (hdr->ar_name[0] != '/') @@ -206,10 +196,9 @@ Archive::interpret_header(const Archive_header* hdr, off_t off, if (name_end == NULL || name_end - hdr->ar_name >= static_cast(sizeof hdr->ar_name)) { - fprintf(stderr, _("%s: %s: malformed archive header name at %ld\n"), - program_name, this->name().c_str(), - static_cast(off)); - gold_exit(false); + gold_error(_("%s: malformed archive header name at %zu\n"), + this->name().c_str(), static_cast(off)); + return this->input_file_->file().filesize() - off; } pname->assign(hdr->ar_name, name_end - hdr->ar_name); } @@ -232,10 +221,9 @@ Archive::interpret_header(const Archive_header* hdr, off_t off, || (x == LONG_MAX && errno == ERANGE) || static_cast(x) >= this->extended_names_.size()) { - fprintf(stderr, _("%s: %s: bad extended name index at %ld\n"), - program_name, this->name().c_str(), - static_cast(off)); - gold_exit(false); + gold_error(_("%s: bad extended name index at %zu"), + this->name().c_str(), static_cast(off)); + return this->input_file_->file().filesize() - off; } const char* name = this->extended_names_.data() + x; @@ -243,10 +231,9 @@ Archive::interpret_header(const Archive_header* hdr, off_t off, if (static_cast(name_end - name) > this->extended_names_.size() || name_end[1] != '\n') { - fprintf(stderr, _("%s: %s: bad extended name entry at header %ld\n"), - program_name, this->name().c_str(), - static_cast(off)); - gold_exit(false); + gold_error(_("%s: bad extended name entry at header %zu"), + this->name().c_str(), static_cast(off)); + return this->input_file_->file().filesize() - off; } pname->assign(name, name_end - name); } @@ -337,13 +324,8 @@ Archive::include_all_members(Symbol_table* symtab, Layout* layout, if (filesize - off < static_cast(sizeof(Archive_header))) { if (filesize != off) - { - fprintf(stderr, _("%s: %s: short archive header at %ld\n"), - program_name, this->name().c_str(), - static_cast(off)); - gold_exit(false); - } - + gold_error(_("%s: short archive header at %zu"), + this->name().c_str(), static_cast(off)); break; } @@ -393,10 +375,9 @@ Archive::include_member(Symbol_table* symtab, Layout* layout, if (read_size < 4) { - fprintf(stderr, _("%s: %s: member at %ld is not an ELF object"), - program_name, this->name().c_str(), - static_cast(off)); - gold_exit(false); + gold_error(_("%s: member at %zu is not an ELF object"), + this->name().c_str(), static_cast(off)); + return; } this->input_file_->file().read(memoff, read_size, ehdr_buf); @@ -408,10 +389,9 @@ Archive::include_member(Symbol_table* symtab, Layout* layout, }; if (memcmp(ehdr_buf, elfmagic, 4) != 0) { - fprintf(stderr, _("%s: %s: member at %ld is not an ELF object"), - program_name, this->name().c_str(), - static_cast(off)); - gold_exit(false); + gold_error(_("%s: member at %zu is not an ELF object"), + this->name().c_str(), static_cast(off)); + return; } Object* obj = make_elf_object((std::string(this->input_file_->filename()) diff --git a/gold/dirsearch.cc b/gold/dirsearch.cc index 6dea53db714..45caf86daf2 100644 --- a/gold/dirsearch.cc +++ b/gold/dirsearch.cc @@ -23,6 +23,7 @@ #include "gold.h" #include +#include #include #include @@ -63,13 +64,10 @@ Dir_cache::read_files() if (d == NULL) { // We ignore directories which do not exist. - if (errno == ENOENT) - return; - - char *s = NULL; - if (asprintf(&s, _("can not read directory %s"), this->dirname_) < 0) - gold::gold_nomem(); - gold::gold_fatal(s, true); + if (errno != ENOENT) + gold::gold_error(_("%s: can not read directory: %s"), + this->dirname_, strerror(errno)); + return; } dirent* de; @@ -77,7 +75,8 @@ Dir_cache::read_files() this->files_.insert(std::string(de->d_name)); if (closedir(d) != 0) - gold::gold_fatal("closedir failed", true); + gold::gold_warning("%s: closedir failed: %s", this->dirname_, + strerror(errno)); } bool diff --git a/gold/dynobj.cc b/gold/dynobj.cc index f2cf8e156ea..2bf2373b846 100644 --- a/gold/dynobj.cc +++ b/gold/dynobj.cc @@ -125,13 +125,8 @@ Sized_dynobj::find_dynsym_sections( continue; if (*pi != -1U) - { - fprintf(stderr, - _("%s: %s: unexpected duplicate type %u section: %u, %u\n"), - program_name, this->name().c_str(), shdr.get_sh_type(), - *pi, i); - gold_exit(false); - } + this->error(_("unexpected duplicate type %u section: %u, %u"), + shdr.get_sh_type(), *pi, i); *pi = i; } @@ -166,13 +161,8 @@ Sized_dynobj::read_dynsym_section( gold_assert(shdr.get_sh_type() == type); if (shdr.get_sh_link() != link) - { - fprintf(stderr, - _("%s: %s: unexpected link in section %u header: %u != %u\n"), - program_name, this->name().c_str(), shndx, - shdr.get_sh_link(), link); - gold_exit(false); - } + this->error(_("unexpected link in section %u header: %u != %u"), + shndx, shdr.get_sh_link(), link); *view = this->get_lasting_view(shdr.get_sh_offset(), shdr.get_sh_size(), false); @@ -206,21 +196,17 @@ Sized_dynobj::set_soname(const unsigned char* pshdrs, { if (link >= this->shnum()) { - fprintf(stderr, - _("%s: %s: DYNAMIC section %u link out of range: %u\n"), - program_name, this->name().c_str(), - dynamic_shndx, link); - gold_exit(false); + this->error(_("DYNAMIC section %u link out of range: %u"), + dynamic_shndx, link); + return; } typename This::Shdr strtabshdr(pshdrs + link * This::shdr_size); if (strtabshdr.get_sh_type() != elfcpp::SHT_STRTAB) { - fprintf(stderr, - _("%s: %s: DYNAMIC section %u link %u is not a strtab\n"), - program_name, this->name().c_str(), - dynamic_shndx, link); - gold_exit(false); + this->error(_("DYNAMIC section %u link %u is not a strtab"), + dynamic_shndx, link); + return; } strtab_size = strtabshdr.get_sh_size(); @@ -238,13 +224,10 @@ Sized_dynobj::set_soname(const unsigned char* pshdrs, off_t val = dyn.get_d_val(); if (val >= strtab_size) { - fprintf(stderr, - _("%s: %s: DT_SONAME value out of range: " - "%lld >= %lld\n"), - program_name, this->name().c_str(), - static_cast(val), - static_cast(strtab_size)); - gold_exit(false); + this->error(_("DT_SONAME value out of range: %lld >= %lld"), + static_cast(val), + static_cast(strtab_size)); + return; } const char* strtab = reinterpret_cast(strtabu); @@ -256,9 +239,7 @@ Sized_dynobj::set_soname(const unsigned char* pshdrs, return; } - fprintf(stderr, _("%s: %s: missing DT_NULL in dynamic segment\n"), - program_name, this->name().c_str()); - gold_exit(false); + this->error(_("missing DT_NULL in dynamic segment")); } // Read the symbols and sections from a dynamic object. We read the @@ -282,14 +263,12 @@ Sized_dynobj::do_read_symbols(Read_symbols_data* sd) unsigned int strtab_shndx = -1U; - if (dynsym_shndx == -1U) - { - sd->symbols = NULL; - sd->symbols_size = 0; - sd->symbol_names = NULL; - sd->symbol_names_size = 0; - } - else + sd->symbols = NULL; + sd->symbols_size = 0; + sd->symbol_names = NULL; + sd->symbol_names_size = 0; + + if (dynsym_shndx != -1U) { // Get the dynamic symbols. typename This::Shdr dynsymshdr(pshdrs + dynsym_shndx * This::shdr_size); @@ -303,20 +282,17 @@ Sized_dynobj::do_read_symbols(Read_symbols_data* sd) strtab_shndx = dynsymshdr.get_sh_link(); if (strtab_shndx >= this->shnum()) { - fprintf(stderr, - _("%s: %s: invalid dynamic symbol table name index: %u\n"), - program_name, this->name().c_str(), strtab_shndx); - gold_exit(false); + this->error(_("invalid dynamic symbol table name index: %u"), + strtab_shndx); + return; } typename This::Shdr strtabshdr(pshdrs + strtab_shndx * This::shdr_size); if (strtabshdr.get_sh_type() != elfcpp::SHT_STRTAB) { - fprintf(stderr, - _("%s: %s: dynamic symbol table name section " - "has wrong type: %u\n"), - program_name, this->name().c_str(), - static_cast(strtabshdr.get_sh_type())); - gold_exit(false); + this->error(_("dynamic symbol table name section " + "has wrong type: %u"), + static_cast(strtabshdr.get_sh_type())); + return; } sd->symbol_names = this->get_lasting_view(strtabshdr.get_sh_offset(), @@ -386,11 +362,9 @@ Sized_dynobj::do_layout(Symbol_table* symtab, if (shdr.get_sh_name() >= sd->section_names_size) { - fprintf(stderr, - _("%s: %s: bad section name offset for section %u: %lu\n"), - program_name, this->name().c_str(), i, - static_cast(shdr.get_sh_name())); - gold_exit(false); + this->error(_("bad section name offset for section %u: %lu"), + i, static_cast(shdr.get_sh_name())); + return; } const char* name = pnames + shdr.get_sh_name(); @@ -417,11 +391,7 @@ Sized_dynobj::set_version_map( if (ndx >= version_map->size()) version_map->resize(ndx + 1); if ((*version_map)[ndx] != NULL) - { - fprintf(stderr, _("%s: %s: duplicate definition for version %u\n"), - program_name, this->name().c_str(), ndx); - gold_exit(false); - } + this->error(_("duplicate definition for version %u"), ndx); (*version_map)[ndx] = name; } @@ -450,9 +420,9 @@ Sized_dynobj::make_verdef_map( if (verdef.get_vd_version() != elfcpp::VER_DEF_CURRENT) { - fprintf(stderr, _("%s: %s: unexpected verdef version %u\n"), - program_name, this->name().c_str(), verdef.get_vd_version()); - gold_exit(false); + this->error(_("unexpected verdef version %u"), + verdef.get_vd_version()); + return; } const unsigned int vd_ndx = verdef.get_vd_ndx(); @@ -466,18 +436,15 @@ Sized_dynobj::make_verdef_map( const unsigned int vd_cnt = verdef.get_vd_cnt(); if (vd_cnt < 1) { - fprintf(stderr, _("%s: %s: verdef vd_cnt field too small: %u\n"), - program_name, this->name().c_str(), vd_cnt); - gold_exit(false); + this->error(_("verdef vd_cnt field too small: %u"), vd_cnt); + return; } const unsigned int vd_aux = verdef.get_vd_aux(); if ((p - pverdef) + vd_aux >= verdef_size) { - fprintf(stderr, - _("%s: %s: verdef vd_aux field out of range: %u\n"), - program_name, this->name().c_str(), vd_aux); - gold_exit(false); + this->error(_("verdef vd_aux field out of range: %u"), vd_aux); + return; } const unsigned char* pvda = p + vd_aux; @@ -486,10 +453,8 @@ Sized_dynobj::make_verdef_map( const unsigned int vda_name = verdaux.get_vda_name(); if (vda_name >= names_size) { - fprintf(stderr, - _("%s: %s: verdaux vda_name field out of range: %u\n"), - program_name, this->name().c_str(), vda_name); - gold_exit(false); + this->error(_("verdaux vda_name field out of range: %u"), vda_name); + return; } this->set_version_map(version_map, vd_ndx, names + vda_name); @@ -497,10 +462,8 @@ Sized_dynobj::make_verdef_map( const unsigned int vd_next = verdef.get_vd_next(); if ((p - pverdef) + vd_next >= verdef_size) { - fprintf(stderr, - _("%s: %s: verdef vd_next field out of range: %u\n"), - program_name, this->name().c_str(), vd_next); - gold_exit(false); + this->error(_("verdef vd_next field out of range: %u"), vd_next); + return; } p += vd_next; @@ -532,20 +495,17 @@ Sized_dynobj::make_verneed_map( if (verneed.get_vn_version() != elfcpp::VER_NEED_CURRENT) { - fprintf(stderr, _("%s: %s: unexpected verneed version %u\n"), - program_name, this->name().c_str(), - verneed.get_vn_version()); - gold_exit(false); + this->error(_("unexpected verneed version %u"), + verneed.get_vn_version()); + return; } const unsigned int vn_aux = verneed.get_vn_aux(); if ((p - pverneed) + vn_aux >= verneed_size) { - fprintf(stderr, - _("%s: %s: verneed vn_aux field out of range: %u\n"), - program_name, this->name().c_str(), vn_aux); - gold_exit(false); + this->error(_("verneed vn_aux field out of range: %u"), vn_aux); + return; } const unsigned int vn_cnt = verneed.get_vn_cnt(); @@ -557,11 +517,9 @@ Sized_dynobj::make_verneed_map( const unsigned int vna_name = vernaux.get_vna_name(); if (vna_name >= names_size) { - fprintf(stderr, - _("%s: %s: vernaux vna_name field " - "out of range: %u\n"), - program_name, this->name().c_str(), vna_name); - gold_exit(false); + this->error(_("vernaux vna_name field out of range: %u"), + vna_name); + return; } this->set_version_map(version_map, vernaux.get_vna_other(), @@ -570,11 +528,9 @@ Sized_dynobj::make_verneed_map( const unsigned int vna_next = vernaux.get_vna_next(); if ((pvna - pverneed) + vna_next >= verneed_size) { - fprintf(stderr, - _("%s: %s: verneed vna_next field " - "out of range: %u\n"), - program_name, this->name().c_str(), vna_next); - gold_exit(false); + this->error(_("verneed vna_next field out of range: %u"), + vna_next); + return; } pvna += vna_next; @@ -583,10 +539,8 @@ Sized_dynobj::make_verneed_map( const unsigned int vn_next = verneed.get_vn_next(); if ((p - pverneed) + vn_next >= verneed_size) { - fprintf(stderr, - _("%s: %s: verneed vn_next field out of range: %u\n"), - program_name, this->name().c_str(), vn_next); - gold_exit(false); + this->error(_("verneed vn_next field out of range: %u"), vn_next); + return; } p += vn_next; @@ -631,11 +585,8 @@ Sized_dynobj::do_add_symbols(Symbol_table* symtab, const size_t symcount = sd->symbols_size / sym_size; if (static_cast(symcount * sym_size) != sd->symbols_size) { - fprintf(stderr, - _("%s: %s: size of dynamic symbols is not " - "multiple of symbol size\n"), - program_name, this->name().c_str()); - gold_exit(false); + this->error(_("size of dynamic symbols is not multiple of symbol size")); + return; } Version_map version_map; @@ -1299,9 +1250,9 @@ Versions::add_def(const General_options* options, const Symbol* sym, // in the version script. if (parameters->output_is_shared()) { - fprintf(stderr, _("%s: symbol %s has undefined version %s\n"), - program_name, sym->name(), version); - gold_exit(false); + gold_error(_("symbol %s has undefined version %s"), + sym->name(), version); + return; } // If this is the first version we are defining, first define diff --git a/gold/errors.cc b/gold/errors.cc new file mode 100644 index 00000000000..3aa3ece8972 --- /dev/null +++ b/gold/errors.cc @@ -0,0 +1,314 @@ +// errors.cc -- handle errors for gold + +// Copyright 2006, 2007 Free Software Foundation, Inc. +// Written by Ian Lance Taylor . + +// 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 +#include + +#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_(), error_count_(0), warning_count_(0), + undefined_symbols_() +{ +} + +// Report a fatal error. + +void +Errors::fatal(const char* format, va_list args) +{ + fprintf(stderr, "%s: ", this->program_name_); + vfprintf(stderr, format, args); + fputc('\n', stderr); + gold_exit(false); +} + +// Report an error. + +void +Errors::error(const char* format, va_list args) +{ + fprintf(stderr, "%s: ", this->program_name_); + vfprintf(stderr, format, args); + fputc('\n', stderr); + { + Hold_lock h(this->lock_); + ++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); + { + Hold_lock h(this->lock_); + ++this->warning_count_; + } +} + +// Report an error at a reloc location. + +template +void +Errors::error_at_location(const Relocate_info* relinfo, + size_t relnum, off_t reloffset, + const char* format, va_list args) +{ + fprintf(stderr, "%s: %s: ", this->program_name_, + relinfo->location(relnum, reloffset).c_str()); + vfprintf(stderr, format, args); + fputc('\n', stderr); + { + Hold_lock h(this->lock_); + ++this->error_count_; + } +} + +// Report a warning at a reloc location. + +template +void +Errors::warning_at_location(const Relocate_info* relinfo, + size_t relnum, off_t reloffset, + const char* format, va_list args) +{ + fprintf(stderr, _("%s: %s: warning: "), this->program_name_, + relinfo->location(relnum, reloffset).c_str()); + vfprintf(stderr, format, args); + fputc('\n', stderr); + { + Hold_lock h(this->lock_); + ++this->warning_count_; + } +} + +// Issue an undefined symbol error. + +template +void +Errors::undefined_symbol(const Symbol* sym, + const Relocate_info* relinfo, + size_t relnum, off_t reloffset) +{ + { + Hold_lock h(this->lock_); + if (++this->undefined_symbols_[sym] >= max_undefined_error_report) + return; + ++this->error_count_; + } + fprintf(stderr, _("%s: %s: undefined reference to '%s'\n"), + this->program_name_, relinfo->location(relnum, reloffset).c_str(), + sym->name()); +} + + +// 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 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); +} + +// Report an error at a location. + +template +void +gold_error_at_location(const Relocate_info* 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 +void +gold_warning_at_location(const Relocate_info* 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. + +template +void +gold_undefined_symbol(const Symbol* sym, + const Relocate_info* relinfo, + size_t relnum, off_t reloffset) +{ + parameters->errors()->undefined_symbol(sym, relinfo, 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<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<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<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<64, true>(const Symbol* sym, + const Relocate_info<64, true>* relinfo, + size_t relnum, off_t reloffset); +#endif + +} // End namespace gold. diff --git a/gold/errors.h b/gold/errors.h new file mode 100644 index 00000000000..545c463bad3 --- /dev/null +++ b/gold/errors.h @@ -0,0 +1,111 @@ +// errors.h -- handle errors for gold -*- C++ -*- + +// Copyright 2006, 2007 Free Software Foundation, Inc. +// Written by Ian Lance Taylor . + +// 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. + +#ifndef GOLD_ERRORS_H +#define GOLD_ERRORS_H + +#include + +#include "gold-threads.h" + +namespace gold +{ + +class Symbol; +template +struct Relocate_info; + +// This class handles errors for gold. There is a single instance +// which is used by all threads. If and when we make the gold code +// more amenable to being used in a library, we will make this an +// abstract interface class, and expect the caller to provide their +// own instantiation. + +class Errors +{ + public: + Errors(const char* program_name); + + // Report a fatal error. After printing the error, this must exit. + void + fatal(const char* format, va_list) ATTRIBUTE_NORETURN; + + // Report an error and continue. + void + error(const char* format, va_list); + + // Report a warning and continue. + void + warning(const char* format, va_list); + + // Report an error at a reloc location. + template + void + error_at_location(const Relocate_info* relinfo, + size_t relnum, off_t reloffset, + const char* format, va_list); + + // Report a warning at a reloc location. + template + void + warning_at_location(const Relocate_info* relinfo, + size_t relnum, off_t reloffset, + const char* format, va_list); + + // Issue an undefined symbol error. SYM is the undefined symbol. + // RELINFO is the general relocation info. RELNUM is the number of + // the reloc, and RELOFFSET is the reloc's offset. + template + void + undefined_symbol(const Symbol* sym, + const Relocate_info* relinfo, + size_t relnum, off_t reloffset); + + // Return the number of errors. + int + error_count() const + { return this->error_count_; } + + private: + Errors(const Errors&); + Errors& operator=(const Errors&); + + // The number of times we report an undefined symbol. + static const int max_undefined_error_report = 5; + + // The name of the program. + const char* program_name_; + // This class can be accessed from multiple threads. This lock is + // used to control access to the data structures. + Lock lock_; + // Numbers of errors reported. + int error_count_; + // Number of warnings reported. + int warning_count_; + // A map counting the numbers of times we have seen an undefined + // symbol. + Unordered_map undefined_symbols_; +}; + +} // End namespace gold. + +#endif // !defined(GOLD_ERRORS_H) diff --git a/gold/fileread.cc b/gold/fileread.cc index 97773d23a7d..ed14d98567b 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -46,8 +46,7 @@ File_read::View::~View() else { if (::munmap(const_cast(this->data_), this->size_) != 0) - fprintf(stderr, _("%s: munmap failed: %s\n"), - program_name, strerror(errno)); + gold_warning(_("munmap failed: %s"), strerror(errno)); File_read::current_mapped_bytes -= this->size_; } @@ -88,8 +87,8 @@ File_read::~File_read() if (this->descriptor_ >= 0) { if (close(this->descriptor_) < 0) - fprintf(stderr, _("%s: warning: close(%s) failed: %s"), - program_name, this->name_.c_str(), strerror(errno)); + gold_warning(_("close of %s failed: %s"), + this->name_.c_str(), strerror(errno)); this->descriptor_ = -1; } this->name_.clear(); @@ -112,11 +111,8 @@ File_read::open(const std::string& name) { struct stat s; if (::fstat(this->descriptor_, &s) < 0) - { - fprintf(stderr, _("%s: %s: fstat failed: %s"), program_name, - this->name_.c_str(), strerror(errno)); - gold_exit(false); - } + gold_error(_("%s: fstat failed: %s"), + this->name_.c_str(), strerror(errno)); this->size_ = s.st_size; } @@ -211,19 +207,17 @@ File_read::do_read(off_t start, off_t size, void* p) if (bytes < 0) { - fprintf(stderr, _("%s: %s: pread failed: %s\n"), - program_name, this->filename().c_str(), strerror(errno)); - gold_exit(false); + gold_fatal(_("%s: pread failed: %s"), + this->filename().c_str(), strerror(errno)); + return; } } - fprintf(stderr, - _("%s: %s: file too short: read only %lld of %lld bytes at %lld\n"), - program_name, this->filename().c_str(), - static_cast(bytes), - static_cast(size), - static_cast(start)); - gold_exit(false); + gold_fatal(_("%s: file too short: read only %lld of %lld bytes at %lld"), + this->filename().c_str(), + static_cast(bytes), + static_cast(size), + static_cast(start)); } // Read data from the file. @@ -295,14 +289,11 @@ File_read::find_or_make_view(off_t start, off_t size, bool cache) void* p = ::mmap(NULL, psize, PROT_READ, MAP_SHARED, this->descriptor_, poff); if (p == MAP_FAILED) - { - fprintf(stderr, _("%s: %s: mmap offset %lld size %lld failed: %s\n"), - program_name, this->filename().c_str(), - static_cast(poff), - static_cast(psize), - strerror(errno)); - gold_exit(false); - } + gold_fatal(_("%s: mmap offset %lld size %lld failed: %s"), + this->filename().c_str(), + static_cast(poff), + static_cast(psize), + strerror(errno)); this->mapped_bytes_ += psize; @@ -414,7 +405,7 @@ Input_file::Input_file(const char* name, const unsigned char* contents, // In both cases, we look in extra_search_path + library_path to find // the file location, rather than the current directory. -void +bool Input_file::open(const General_options& options, const Dirsearch& dirpath) { std::string name; @@ -447,9 +438,9 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath) name = dirpath.find(n1, n2, &this->is_in_sysroot_); if (name.empty()) { - fprintf(stderr, _("%s: cannot find -l%s\n"), program_name, - this->input_argument_->name()); - gold_exit(false); + gold_error(_("cannot find -l%s\n"), + this->input_argument_->name()); + return false; } if (n2.empty() || name[name.length() - 1] == 'o') this->found_name_ = n1; @@ -474,9 +465,9 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath) &this->is_in_sysroot_); if (name.empty()) { - fprintf(stderr, _("%s: cannot find %s\n"), program_name, - this->input_argument_->name()); - gold_exit(false); + gold_error(_("cannot find %s\n"), + this->input_argument_->name()); + return false; } } this->found_name_ = this->input_argument_->name(); @@ -485,10 +476,12 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath) // Now that we've figured out where the file lives, try to open it. if (!this->file_.open(name)) { - fprintf(stderr, _("%s: cannot open %s: %s\n"), program_name, - name.c_str(), strerror(errno)); - gold_exit(false); + gold_error(_("cannot open %s: %s\n"), + name.c_str(), strerror(errno)); + return false; } + + return true; } } // End namespace gold. diff --git a/gold/fileread.h b/gold/fileread.h index cf4b3ab98ae..c39f9de55b2 100644 --- a/gold/fileread.h +++ b/gold/fileread.h @@ -290,8 +290,9 @@ class Input_file // method. Input_file(const char* name, const unsigned char* contents, off_t size); - // Open the file. - void + // Open the file. If the open fails, this will report an error and + // return false. + bool open(const General_options&, const Dirsearch&); // Return the name given by the user. For -lc this will return "c". diff --git a/gold/gold.cc b/gold/gold.cc index a4264087e7f..139652430b0 100644 --- a/gold/gold.cc +++ b/gold/gold.cc @@ -26,6 +26,7 @@ #include #include #include +#include "libiberty.h" #include "options.h" #include "workqueue.h" @@ -46,20 +47,11 @@ const char* program_name; void gold_exit(bool status) { + if (!status && parameters != NULL) + unlink_if_ordinary(parameters->output_file_name()); exit(status ? EXIT_SUCCESS : EXIT_FAILURE); } -void -gold_fatal(const char* msg, bool perrno) -{ - fprintf(stderr, "%s: ", program_name); - if (perrno) - perror(msg); - else - fprintf(stderr, "%s\n", msg); - gold_exit(false); -} - void gold_nomem() { @@ -123,7 +115,7 @@ queue_initial_tasks(const General_options& options, Symbol_table* symtab, Layout* layout) { if (cmdline.begin() == cmdline.end()) - gold_fatal(_("no input files"), false); + gold_fatal(_("no input files")); // Read the input files. We have to add the symbols to the symbol // table in order. We do this by creating a separate blocker for @@ -166,9 +158,8 @@ queue_middle_tasks(const General_options& options, if (!doing_static_link && options.is_static()) { // We print out just the first .so we see; there may be others. - fprintf(stderr, _("%s: cannot mix -static with dynamic object %s\n"), - program_name, (*input_objects->dynobj_begin())->name().c_str()); - gold_exit(false); + gold_error(_("cannot mix -static with dynamic object %s"), + (*input_objects->dynobj_begin())->name().c_str()); } // Define some sections and symbols needed for a dynamic link. This diff --git a/gold/gold.h b/gold/gold.h index 63bcb79c960..25f6c0c7712 100644 --- a/gold/gold.h +++ b/gold/gold.h @@ -171,10 +171,13 @@ class Command_line; class Input_argument_list; class Dirsearch; class Input_objects; +class Symbol; class Symbol_table; class Layout; class Workqueue; class Output_file; +template +struct Relocate_info; // The name of the program as used in error messages. extern const char* program_name; @@ -184,11 +187,42 @@ extern const char* program_name; extern void gold_exit(bool status) ATTRIBUTE_NORETURN; -// This function is called to emit an unexpected error message and a -// newline, and then exit with failure. If PERRNO is true, it reports -// the error in errno. +// This function is called to emit an error message and then +// immediately exit with failure. extern void -gold_fatal(const char* msg, bool perrno) ATTRIBUTE_NORETURN; +gold_fatal(const char* format, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1; + +// This function is called to issue an error. This will cause gold to +// eventually exit with failure. +extern void +gold_error(const char* msg, ...) ATTRIBUTE_PRINTF_1; + +// This function is called to issue a warning. +extern void +gold_warning(const char* msg, ...) ATTRIBUTE_PRINTF_1; + +// This function is called to issue an error at the location of a +// reloc. +template +extern void +gold_error_at_location(const Relocate_info*, + size_t, off_t, const char* format, ...) + ATTRIBUTE_PRINTF_4; + +// This function is called to issue a warning at the location of a +// reloc. +template +extern void +gold_warning_at_location(const Relocate_info*, + size_t, off_t, const char* format, ...) + ATTRIBUTE_PRINTF_4; + +// This function is called to report an undefined symbol. +template +extern void +gold_undefined_symbol(const Symbol*, + const Relocate_info*, + size_t, off_t); // This is function is called in some cases if we run out of memory. extern void diff --git a/gold/i386.cc b/gold/i386.cc index fa564c4be54..837f5abdf84 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -139,9 +139,7 @@ class Target_i386 : public Sized_target<32, false> if (this->skip_call_tls_get_addr_) { // FIXME: This needs to specify the location somehow. - fprintf(stderr, _("%s: missing expected TLS relocation\n"), - program_name); - gold_exit(false); + gold_error(_("missing expected TLS relocation")); } } @@ -727,8 +725,8 @@ void Target_i386::Scan::unsupported_reloc_local(Sized_relobj<32, false>* object, unsigned int r_type) { - fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"), - program_name, object->name().c_str(), r_type); + gold_error(_("%s: unsupported reloc %u against local symbol"), + object->name().c_str(), r_type); } // Scan a relocation for a local symbol. @@ -781,9 +779,8 @@ Target_i386::Scan::local(const General_options&, case elfcpp::R_386_TLS_DTPOFF32: case elfcpp::R_386_TLS_TPOFF32: case elfcpp::R_386_TLS_DESC: - fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"), - program_name, object->name().c_str(), r_type); - gold_exit(false); + gold_error(_("%s: unexpected reloc %u in object file\n"), + object->name().c_str(), r_type); break; // These are initial TLS relocs, which are expected when @@ -870,9 +867,8 @@ Target_i386::Scan::unsupported_reloc_global(Sized_relobj<32, false>* object, unsigned int r_type, Symbol* gsym) { - fprintf(stderr, - _("%s: %s: unsupported reloc %u against global symbol %s\n"), - program_name, object->name().c_str(), r_type, gsym->name()); + gold_error(_("%s: unsupported reloc %u against global symbol %s"), + object->name().c_str(), r_type, gsym->name()); } // Scan a relocation for a global symbol. @@ -975,9 +971,8 @@ Target_i386::Scan::global(const General_options& options, case elfcpp::R_386_TLS_DTPOFF32: case elfcpp::R_386_TLS_TPOFF32: case elfcpp::R_386_TLS_DESC: - fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"), - program_name, object->name().c_str(), r_type); - gold_exit(false); + gold_error(_("%s: unexpected reloc %u in object file"), + object->name().c_str(), r_type); break; // These are initial tls relocs, which are expected when @@ -1072,9 +1067,9 @@ Target_i386::scan_relocs(const General_options& options, { if (sh_type == elfcpp::SHT_RELA) { - fprintf(stderr, _("%s: %s: unsupported RELA reloc section\n"), - program_name, object->name().c_str()); - gold_exit(false); + gold_error(_("%s: unsupported RELA reloc section"), + object->name().c_str()); + return; } gold::scan_relocs<32, false, Target_i386, elfcpp::SHT_REL, @@ -1161,16 +1156,13 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo, if (r_type != elfcpp::R_386_PLT32 || gsym == NULL || strcmp(gsym->name(), "___tls_get_addr") != 0) + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("missing expected TLS relocation")); + else { - fprintf(stderr, _("%s: %s: missing expected TLS relocation\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str()); - gold_exit(false); + this->skip_call_tls_get_addr_ = false; + return false; } - - this->skip_call_tls_get_addr_ = false; - - return false; } // Pick the value to use for symbols defined in shared objects. @@ -1256,11 +1248,9 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo, case elfcpp::R_386_TLS_DTPOFF32: case elfcpp::R_386_TLS_TPOFF32: case elfcpp::R_386_TLS_DESC: - fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("unexpected reloc %u in object file"), + r_type); break; // These are initial tls relocs, which are expected when @@ -1290,11 +1280,9 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo, case elfcpp::R_386_TLS_LDM_POP: case elfcpp::R_386_USED_BY_INTEL_200: default: - fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("unsupported reloc %u"), + r_type); break; } @@ -1317,10 +1305,9 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, Output_segment* tls_segment = relinfo->layout->tls_segment(); if (tls_segment == NULL) { - fprintf(stderr, _("%s: %s: TLS reloc but no TLS segment\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str()); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("TLS reloc but no TLS segment")); + return; } elfcpp::Elf_types<32>::Elf_Addr value = psymval->value(relinfo->object, 0); @@ -1352,11 +1339,9 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, view_size); break; } - fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("unsupported reloc %u"), + r_type); break; case elfcpp::R_386_TLS_GD: @@ -1367,21 +1352,18 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, view_size); break; } - fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("unsupported reloc %u"), + r_type); break; case elfcpp::R_386_TLS_LDM: if (this->local_dynamic_type_ == LOCAL_DYNAMIC_SUN) { - fprintf(stderr, - _("%s: %s: both SUN and GNU model TLS relocations\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str()); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("both SUN and GNU model " + "TLS relocations")); + break; } this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU; if (optimized_type == tls::TLSOPT_TO_LE) @@ -1390,11 +1372,9 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, value, view, view_size); break; } - fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("unsupported reloc %u"), + r_type); break; case elfcpp::R_386_TLS_LDO_32: @@ -1413,11 +1393,9 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, case elfcpp::R_386_TLS_GOTDESC: case elfcpp::R_386_TLS_DESC_CALL: - fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("unsupported reloc %u"), + r_type); break; } } diff --git a/gold/main.cc b/gold/main.cc index 49b50b2ca4c..eda586bc673 100644 --- a/gold/main.cc +++ b/gold/main.cc @@ -29,6 +29,7 @@ #include "options.h" #include "parameters.h" +#include "errors.h" #include "dirsearch.h" #include "workqueue.h" #include "object.h" @@ -51,6 +52,8 @@ main(int argc, char** argv) program_name = argv[0]; + Errors errors(program_name); + // Handle the command line options. Command_line command_line; command_line.process(argc - 1, argv + 1); @@ -59,7 +62,7 @@ main(int argc, char** argv) if (command_line.options().print_stats()) start_time = get_run_time(); - initialize_parameters(&command_line.options()); + initialize_parameters(&command_line.options(), &errors); // The work queue. Workqueue workqueue(command_line.options()); @@ -100,5 +103,5 @@ main(int argc, char** argv) program_name, static_cast(layout.output_file_size())); } - gold_exit(true); + gold_exit(errors.error_count() == 0); } diff --git a/gold/merge.cc b/gold/merge.cc index dc293abebdf..f31b44e8055 100644 --- a/gold/merge.cc +++ b/gold/merge.cc @@ -169,7 +169,7 @@ Output_merge_data::add_constant(const unsigned char* p) this->alc_ *= 2; this->p_ = static_cast(realloc(this->p_, this->alc_)); if (this->p_ == NULL) - gold_fatal("out of memory", true); + gold_nomem(); } memcpy(this->p_ + this->len_, p, entsize); @@ -251,11 +251,9 @@ Output_merge_string::do_add_input_section(Relobj* object, if (len % sizeof(Char_type) != 0) { - fprintf(stderr, - _("%s: %s: mergeable string section length not multiple of " - "character size\n"), - program_name, object->name().c_str()); - gold_exit(false); + object->error(_("mergeable string section length not multiple of " + "character size")); + return false; } len /= sizeof(Char_type); @@ -268,11 +266,9 @@ Output_merge_string::do_add_input_section(Relobj* object, ++plen; if (i + plen >= len) { - fprintf(stderr, - _("%s: %s: entry in mergeable string section " - "not null terminated\n"), - program_name, object->name().c_str()); - gold_exit(false); + object->error(_("entry in mergeable string section " + "not null terminated")); + break; } } diff --git a/gold/object.cc b/gold/object.cc index d8b3b901d2c..d655a4102fd 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -46,28 +46,26 @@ Object::set_target(int machine, int size, bool big_endian, int osabi, { Target* target = select_target(machine, size, big_endian, osabi, abiversion); if (target == NULL) - { - fprintf(stderr, _("%s: %s: unsupported ELF machine number %d\n"), - program_name, this->name().c_str(), machine); - gold_exit(false); - } + gold_fatal(_("%s: unsupported ELF machine number %d"), + this->name().c_str(), machine); this->target_ = target; } -// Report an error for the elfcpp::Elf_file interface. +// Report an error for this object file. This is used by the +// elfcpp::Elf_file interface, and also called by the Object code +// itself. void -Object::error(const char* format, ...) +Object::error(const char* format, ...) const { va_list args; - - fprintf(stderr, "%s: %s: ", program_name, this->name().c_str()); va_start(args, format); - vfprintf(stderr, format, args); + char* buf = NULL; + if (vasprintf(&buf, format, args) < 0) + gold_nomem(); va_end(args); - putc('\n', stderr); - - gold_exit(false); + gold_error(_("%s: %s"), this->name().c_str(), buf); + free(buf); } // Return a view of the contents of a section. @@ -101,13 +99,8 @@ Object::read_section_data(elfcpp::Elf_file* elf_file, typename elfcpp::Shdr shdrnames(pshdrnames); if (shdrnames.get_sh_type() != elfcpp::SHT_STRTAB) - { - fprintf(stderr, - _("%s: %s: section name section has wrong type: %u\n"), - program_name, this->name().c_str(), - static_cast(shdrnames.get_sh_type())); - gold_exit(false); - } + this->error(_("section name section has wrong type: %u"), + static_cast(shdrnames.get_sh_type())); sd->section_names_size = shdrnames.get_sh_size(); sd->section_names = this->get_lasting_view(shdrnames.get_sh_offset(), @@ -216,13 +209,14 @@ Sized_relobj::do_read_symbols(Read_symbols_data* sd) this->find_symtab(pshdrs); + sd->symbols = NULL; + sd->symbols_size = 0; + sd->symbol_names = NULL; + sd->symbol_names_size = 0; + if (this->symtab_shndx_ == 0) { // No symbol table. Weird but legal. - sd->symbols = NULL; - sd->symbols_size = 0; - sd->symbol_names = NULL; - sd->symbol_names_size = 0; return; } @@ -246,18 +240,15 @@ Sized_relobj::do_read_symbols(Read_symbols_data* sd) unsigned int strtab_shndx = symtabshdr.get_sh_link(); if (strtab_shndx >= this->shnum()) { - fprintf(stderr, _("%s: %s: invalid symbol table name index: %u\n"), - program_name, this->name().c_str(), strtab_shndx); - gold_exit(false); + this->error(_("invalid symbol table name index: %u"), strtab_shndx); + return; } typename This::Shdr strtabshdr(pshdrs + strtab_shndx * This::shdr_size); if (strtabshdr.get_sh_type() != elfcpp::SHT_STRTAB) { - fprintf(stderr, - _("%s: %s: symbol table name section has wrong type: %u\n"), - program_name, this->name().c_str(), - static_cast(strtabshdr.get_sh_type())); - gold_exit(false); + this->error(_("symbol table name section has wrong type: %u"), + static_cast(strtabshdr.get_sh_type())); + return; } // Read the symbol names. @@ -310,9 +301,9 @@ Sized_relobj::include_section_group( // Read the symbol table entry. if (shdr.get_sh_info() >= symshdr.get_sh_size() / This::sym_size) { - fprintf(stderr, _("%s: %s: section group %u info %u out of range\n"), - program_name, this->name().c_str(), index, shdr.get_sh_info()); - gold_exit(false); + this->error(_("section group %u info %u out of range"), + index, shdr.get_sh_info()); + return false; } off_t symoff = symshdr.get_sh_offset() + shdr.get_sh_info() * This::sym_size; const unsigned char* psym = this->get_view(symoff, This::sym_size, true); @@ -328,10 +319,9 @@ Sized_relobj::include_section_group( // Get the section group signature. if (sym.get_st_name() >= symnamelen) { - fprintf(stderr, _("%s: %s: symbol %u name offset %u out of range\n"), - program_name, this->name().c_str(), shdr.get_sh_info(), - sym.get_st_name()); - gold_exit(false); + this->error(_("symbol %u name offset %u out of range"), + shdr.get_sh_info(), sym.get_st_name()); + return false; } const char* signature = psymnames + sym.get_st_name(); @@ -361,11 +351,9 @@ Sized_relobj::include_section_group( elfcpp::Swap<32, big_endian>::readval(pword + i); if (secnum >= this->shnum()) { - fprintf(stderr, - _("%s: %s: section %u in section group %u out of range"), - program_name, this->name().c_str(), secnum, - index); - gold_exit(false); + this->error(_("section %u in section group %u out of range"), + secnum, index); + continue; } (*omit)[secnum] = true; } @@ -437,11 +425,9 @@ Sized_relobj::do_layout(Symbol_table* symtab, if (shdr.get_sh_name() >= sd->section_names_size) { - fprintf(stderr, - _("%s: %s: bad section name offset for section %u: %lu\n"), - program_name, this->name().c_str(), i, - static_cast(shdr.get_sh_name())); - gold_exit(false); + this->error(_("bad section name offset for section %u: %lu"), + i, static_cast(shdr.get_sh_name())); + return; } const char* name = pnames + shdr.get_sh_name(); @@ -505,10 +491,8 @@ Sized_relobj::do_add_symbols(Symbol_table* symtab, size_t symcount = sd->symbols_size / sym_size; if (static_cast(symcount * sym_size) != sd->symbols_size) { - fprintf(stderr, - _("%s: %s: size of symbols is not multiple of symbol size\n"), - program_name, this->name().c_str()); - gold_exit(false); + this->error(_("size of symbols is not multiple of symbol size")); + return; } this->symbols_ = new Symbol*[symcount]; @@ -597,22 +581,18 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, else { // FIXME: Handle SHN_XINDEX. - fprintf(stderr, - _("%s: %s: unknown section index %u " - "for local symbol %u\n"), - program_name, this->name().c_str(), shndx, i); - gold_exit(false); + this->error(_("unknown section index %u for local symbol %u"), + shndx, i); + lv.set_output_value(0); } } else { if (shndx >= shnum) { - fprintf(stderr, - _("%s: %s: local symbol %u section index %u " - "out of range\n"), - program_name, this->name().c_str(), i, shndx); - gold_exit(false); + this->error(_("local symbol %u section index %u out of range"), + i, shndx); + shndx = 0; } Output_section* os = mo[shndx].output_section; @@ -642,13 +622,11 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, if (sym.get_st_name() >= strtab_size) { - fprintf(stderr, - _("%s: %s: local symbol %u section name " - "out of range: %u >= %u\n"), - program_name, this->name().c_str(), - i, sym.get_st_name(), - static_cast(strtab_size)); - gold_exit(false); + this->error(_("local symbol %u section name out of range: %u >= %u"), + i, sym.get_st_name(), + static_cast(strtab_size)); + lv.set_no_output_symtab_entry(); + continue; } const char* name = pnames + sym.get_st_name(); @@ -824,9 +802,8 @@ Input_objects::add_object(Object* obj) this->target_ = target; else if (this->target_ != target) { - fprintf(stderr, _("%s: %s: incompatible target\n"), - program_name, obj->name().c_str()); - gold_exit(false); + gold_error(_("%s: incompatible target"), obj->name().c_str()); + return false; } set_parameters_size_and_endianness(target->get_size(), @@ -892,9 +869,9 @@ make_elf_sized_object(const std::string& name, Input_file* input_file, } else { - fprintf(stderr, _("%s: %s: unsupported ELF file type %d\n"), - program_name, name.c_str(), et); - gold_exit(false); + gold_error(_("%s: unsupported ELF file type %d"), + name.c_str(), et); + return NULL; } } @@ -911,51 +888,44 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset, { if (bytes < elfcpp::EI_NIDENT) { - fprintf(stderr, _("%s: %s: ELF file too short\n"), - program_name, name.c_str()); - gold_exit(false); + gold_error(_("%s: ELF file too short"), name.c_str()); + return NULL; } int v = p[elfcpp::EI_VERSION]; if (v != elfcpp::EV_CURRENT) { if (v == elfcpp::EV_NONE) - fprintf(stderr, _("%s: %s: invalid ELF version 0\n"), - program_name, name.c_str()); + gold_error(_("%s: invalid ELF version 0"), name.c_str()); else - fprintf(stderr, _("%s: %s: unsupported ELF version %d\n"), - program_name, name.c_str(), v); - gold_exit(false); + gold_error(_("%s: unsupported ELF version %d"), name.c_str(), v); + return NULL; } int c = p[elfcpp::EI_CLASS]; if (c == elfcpp::ELFCLASSNONE) { - fprintf(stderr, _("%s: %s: invalid ELF class 0\n"), - program_name, name.c_str()); - gold_exit(false); + gold_error(_("%s: invalid ELF class 0"), name.c_str()); + return NULL; } else if (c != elfcpp::ELFCLASS32 && c != elfcpp::ELFCLASS64) { - fprintf(stderr, _("%s: %s: unsupported ELF class %d\n"), - program_name, name.c_str(), c); - gold_exit(false); + gold_error(_("%s: unsupported ELF class %d"), name.c_str(), c); + return NULL; } int d = p[elfcpp::EI_DATA]; if (d == elfcpp::ELFDATANONE) { - fprintf(stderr, _("%s: %s: invalid ELF data encoding\n"), - program_name, name.c_str()); - gold_exit(false); + gold_error(_("%s: invalid ELF data encoding"), name.c_str()); + return NULL; } else if (d != elfcpp::ELFDATA2LSB && d != elfcpp::ELFDATA2MSB) { - fprintf(stderr, _("%s: %s: unsupported ELF data encoding %d\n"), - program_name, name.c_str(), d); - gold_exit(false); + gold_error(_("%s: unsupported ELF data encoding %d"), name.c_str(), d); + return NULL; } bool big_endian = d == elfcpp::ELFDATA2MSB; @@ -964,9 +934,8 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset, { if (bytes < elfcpp::Elf_sizes<32>::ehdr_size) { - fprintf(stderr, _("%s: %s: ELF file too short\n"), - program_name, name.c_str()); - gold_exit(false); + gold_error(_("%s: ELF file too short"), name.c_str()); + return NULL; } if (big_endian) { @@ -975,10 +944,10 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset, return make_elf_sized_object<32, true>(name, input_file, offset, ehdr); #else - fprintf(stderr, - _("%s: %s: not configured to support 32-bit big-endian object\n"), - program_name, name.c_str()); - gold_exit(false); + gold_error(_("%s: not configured to support " + "32-bit big-endian object"), + name.c_str()); + return NULL; #endif } else @@ -988,10 +957,10 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset, return make_elf_sized_object<32, false>(name, input_file, offset, ehdr); #else - fprintf(stderr, - _("%s: %s: not configured to support 32-bit little-endian object\n"), - program_name, name.c_str()); - gold_exit(false); + gold_error(_("%s: not configured to support " + "32-bit little-endian object"), + name.c_str()); + return NULL; #endif } } @@ -999,9 +968,8 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset, { if (bytes < elfcpp::Elf_sizes<32>::ehdr_size) { - fprintf(stderr, _("%s: %s: ELF file too short\n"), - program_name, name.c_str()); - gold_exit(false); + gold_error(_("%s: ELF file too short"), name.c_str()); + return NULL; } if (big_endian) { @@ -1010,10 +978,10 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset, return make_elf_sized_object<64, true>(name, input_file, offset, ehdr); #else - fprintf(stderr, - _("%s: %s: not configured to support 64-bit big-endian object\n"), - program_name, name.c_str()); - gold_exit(false); + gold_error(_("%s: not configured to support " + "64-bit big-endian object"), + name.c_str()); + return NULL; #endif } else @@ -1023,10 +991,10 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset, return make_elf_sized_object<64, false>(name, input_file, offset, ehdr); #else - fprintf(stderr, - _("%s: %s: not configured to support 64-bit little-endian object\n"), - program_name, name.c_str()); - gold_exit(false); + gold_error(_("%s: not configured to support " + "64-bit little-endian object"), + name.c_str()); + return NULL; #endif } } diff --git a/gold/object.h b/gold/object.h index 8f0a3b7726e..1b8c1e2440d 100644 --- a/gold/object.h +++ b/gold/object.h @@ -233,7 +233,7 @@ class Object // Report an error. void - error(const char* format, ...) ATTRIBUTE_PRINTF_2; + error(const char* format, ...) const ATTRIBUTE_PRINTF_2; // A location in the file. struct Location diff --git a/gold/options.cc b/gold/options.cc index 89eecf66bb8..0458139a59e 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -215,7 +215,7 @@ help(int, char**, char*, gold::Command_line*) std::puts(options[i].doc); } - gold::gold_exit(true); + ::exit(true); return 0; } @@ -226,7 +226,7 @@ int version(int, char**, char* opt, gold::Command_line*) { gold::print_version(opt[0] == 'v' && opt[1] == '\0'); - gold::gold_exit(true); + ::exit(true); return 0; } @@ -767,7 +767,7 @@ Command_line::usage() fprintf(stderr, _("%s: use the --help option for usage information\n"), program_name); - gold_exit(false); + ::exit(false); } void diff --git a/gold/output.cc b/gold/output.cc index f539deac83d..99a2954f8f9 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -1028,10 +1028,9 @@ Output_section::add_input_section(Relobj* object, unsigned int shndx, elfcpp::Elf_Xword addralign = shdr.get_sh_addralign(); if ((addralign & (addralign - 1)) != 0) { - fprintf(stderr, _("%s: %s: invalid alignment %lu for section \"%s\"\n"), - program_name, object->name().c_str(), - static_cast(addralign), secname); - gold_exit(false); + object->error(_("invalid alignment %lu for section \"%s\""), + static_cast(addralign), secname); + addralign = 1; } if (addralign > this->addralign_) @@ -1695,37 +1694,21 @@ Output_file::open(off_t file_size) int mode = parameters->output_is_object() ? 0666 : 0777; int o = ::open(this->name_, O_RDWR | O_CREAT | O_TRUNC, mode); if (o < 0) - { - fprintf(stderr, _("%s: %s: open: %s\n"), - program_name, this->name_, strerror(errno)); - gold_exit(false); - } + gold_fatal(_("%s: open: %s"), this->name_, strerror(errno)); this->o_ = o; // Write out one byte to make the file the right size. if (::lseek(o, file_size - 1, SEEK_SET) < 0) - { - fprintf(stderr, _("%s: %s: lseek: %s\n"), - program_name, this->name_, strerror(errno)); - gold_exit(false); - } + gold_fatal(_("%s: lseek: %s"), this->name_, strerror(errno)); char b = 0; if (::write(o, &b, 1) != 1) - { - fprintf(stderr, _("%s: %s: write: %s\n"), - program_name, this->name_, strerror(errno)); - gold_exit(false); - } + gold_fatal(_("%s: write: %s"), this->name_, strerror(errno)); // Map the file into memory. void* base = ::mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, o, 0); if (base == MAP_FAILED) - { - fprintf(stderr, _("%s: %s: mmap: %s\n"), - program_name, this->name_, strerror(errno)); - gold_exit(false); - } + gold_fatal(_("%s: mmap: %s"), this->name_, strerror(errno)); this->base_ = static_cast(base); } @@ -1735,19 +1718,11 @@ void Output_file::close() { if (::munmap(this->base_, this->file_size_) < 0) - { - fprintf(stderr, _("%s: %s: munmap: %s\n"), - program_name, this->name_, strerror(errno)); - gold_exit(false); - } + gold_error(_("%s: munmap: %s\n"), this->name_, strerror(errno)); this->base_ = NULL; if (::close(this->o_) < 0) - { - fprintf(stderr, _("%s: %s: close: %s\n"), - program_name, this->name_, strerror(errno)); - gold_exit(false); - } + gold_error(_("%s: close: %s"), this->name_, strerror(errno)); this->o_ = -1; } diff --git a/gold/parameters.cc b/gold/parameters.cc index 337469a4ba6..817268b1624 100644 --- a/gold/parameters.cc +++ b/gold/parameters.cc @@ -30,8 +30,9 @@ namespace gold // Initialize the parameters from the options. -Parameters::Parameters(const General_options* options) - : sysroot_(options->sysroot()), +Parameters::Parameters(const General_options* options, Errors* errors) + : errors_(errors), output_file_name_(options->output_file_name()), + sysroot_(options->sysroot()), is_doing_static_link_valid_(false), doing_static_link_(false), is_size_and_endian_valid_(false), size_(0), is_big_endian_(false), optimization_level_(options->optimization_level()) @@ -89,9 +90,9 @@ const Parameters* parameters; // Initialize the global variable. void -initialize_parameters(const General_options* options) +initialize_parameters(const General_options* options, Errors* errors) { - parameters = static_parameters = new Parameters(options); + parameters = static_parameters = new Parameters(options, errors); } // Set whether we are doing a static link. diff --git a/gold/parameters.h b/gold/parameters.h index 3b480c211bd..c4e3fe311e9 100644 --- a/gold/parameters.h +++ b/gold/parameters.h @@ -27,6 +27,7 @@ namespace gold { class General_options; +class Errors; // Here we define the Parameters class which simply holds simple // general parameters which apply to the entire link. We use a global @@ -39,7 +40,17 @@ class General_options; class Parameters { public: - Parameters(const General_options*); + Parameters(const General_options*, Errors*); + + // Return the error object. + Errors* + errors() const + { return this->errors_; } + + // Return the output file name. + const char* + output_file_name() const + { return this->output_file_name_; } // Whether we are generating a regular executable. bool @@ -135,6 +146,11 @@ class Parameters STRIP_DEBUG }; + // A pointer to the error handling object. + Errors* errors_; + + // The output file name. + const char* output_file_name_; // The type of the output file. Output_file_type output_file_type_; // The target system root directory. @@ -160,7 +176,7 @@ class Parameters extern const Parameters* parameters; // Initialize the global variable. -extern void initialize_parameters(const General_options*); +extern void initialize_parameters(const General_options*, Errors*); // Set the size and endianness of the global parameters variable. extern void set_parameters_size_and_endianness(int size, bool is_big_endian); diff --git a/gold/po/POTFILES.in b/gold/po/POTFILES.in index a65d3a52239..bb32fdf9d99 100644 --- a/gold/po/POTFILES.in +++ b/gold/po/POTFILES.in @@ -10,6 +10,8 @@ dynobj.cc dynobj.h ehframe.cc ehframe.h +errors.cc +errors.h fileread.cc fileread.h gold.cc diff --git a/gold/po/gold.pot b/gold/po/gold.pot index 620182bc5c4..12770a64822 100644 --- a/gold/po/gold.pot +++ b/gold/po/gold.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-10-10 12:27-0700\n" +"POT-Creation-Date: 2007-10-13 23:40-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,215 +16,249 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: archive.cc:89 +#: archive.cc:88 #, c-format -msgid "%s: %s: no archive symbol table (run ranlib)\n" +msgid "%s: no archive symbol table (run ranlib)" msgstr "" -#: archive.cc:144 +#: archive.cc:138 #, c-format -msgid "%s: %s: bad archive symbol table names\n" +msgid "%s: bad archive symbol table names" msgstr "" -#: archive.cc:176 +#: archive.cc:168 #, c-format -msgid "%s; %s: malformed archive header at %ld\n" +msgid "%s: malformed archive header at %zu" msgstr "" -#: archive.cc:197 +#: archive.cc:188 #, c-format -msgid "%s: %s: malformed archive header size at %ld\n" +msgid "%s: malformed archive header size at %zu" msgstr "" -#: archive.cc:209 +#: archive.cc:199 #, c-format -msgid "%s: %s: malformed archive header name at %ld\n" +msgid "%s: malformed archive header name at %zu\n" msgstr "" -#: archive.cc:235 +#: archive.cc:224 #, c-format -msgid "%s: %s: bad extended name index at %ld\n" +msgid "%s: bad extended name index at %zu" msgstr "" -#: archive.cc:246 +#: archive.cc:234 #, c-format -msgid "%s: %s: bad extended name entry at header %ld\n" +msgid "%s: bad extended name entry at header %zu" msgstr "" -#: archive.cc:341 +#: archive.cc:327 #, c-format -msgid "%s: %s: short archive header at %ld\n" +msgid "%s: short archive header at %zu" msgstr "" -#: archive.cc:396 archive.cc:411 +#: archive.cc:378 archive.cc:392 #, c-format -msgid "%s: %s: member at %ld is not an ELF object" +msgid "%s: member at %zu is not an ELF object" msgstr "" -#: dirsearch.cc:70 +#: dirsearch.cc:68 #, c-format -msgid "can not read directory %s" +msgid "%s: can not read directory: %s" msgstr "" -#: dynobj.cc:130 +#: dynobj.cc:128 #, c-format -msgid "%s: %s: unexpected duplicate type %u section: %u, %u\n" +msgid "unexpected duplicate type %u section: %u, %u" msgstr "" -#: dynobj.cc:171 +#: dynobj.cc:164 #, c-format -msgid "%s: %s: unexpected link in section %u header: %u != %u\n" +msgid "unexpected link in section %u header: %u != %u" msgstr "" -#: dynobj.cc:210 +#: dynobj.cc:199 #, c-format -msgid "%s: %s: DYNAMIC section %u link out of range: %u\n" +msgid "DYNAMIC section %u link out of range: %u" msgstr "" -#: dynobj.cc:220 +#: dynobj.cc:207 #, c-format -msgid "%s: %s: DYNAMIC section %u link %u is not a strtab\n" +msgid "DYNAMIC section %u link %u is not a strtab" +msgstr "" + +#: dynobj.cc:227 +#, c-format +msgid "DT_SONAME value out of range: %lld >= %lld" msgstr "" #: dynobj.cc:242 -#, c-format -msgid "%s: %s: DT_SONAME value out of range: %lld >= %lld\n" +msgid "missing DT_NULL in dynamic segment" msgstr "" -#: dynobj.cc:259 +#: dynobj.cc:285 #, c-format -msgid "%s: %s: missing DT_NULL in dynamic segment\n" +msgid "invalid dynamic symbol table name index: %u" msgstr "" -#: dynobj.cc:307 +#: dynobj.cc:292 #, c-format -msgid "%s: %s: invalid dynamic symbol table name index: %u\n" +msgid "dynamic symbol table name section has wrong type: %u" msgstr "" -#: dynobj.cc:315 +#: dynobj.cc:365 object.cc:428 #, c-format -msgid "%s: %s: dynamic symbol table name section has wrong type: %u\n" +msgid "bad section name offset for section %u: %lu" msgstr "" -#: dynobj.cc:390 object.cc:441 +#: dynobj.cc:394 #, c-format -msgid "%s: %s: bad section name offset for section %u: %lu\n" +msgid "duplicate definition for version %u" msgstr "" -#: dynobj.cc:421 +#: dynobj.cc:423 #, c-format -msgid "%s: %s: duplicate definition for version %u\n" +msgid "unexpected verdef version %u" msgstr "" -#: dynobj.cc:453 +#: dynobj.cc:439 #, c-format -msgid "%s: %s: unexpected verdef version %u\n" +msgid "verdef vd_cnt field too small: %u" msgstr "" -#: dynobj.cc:469 +#: dynobj.cc:446 #, c-format -msgid "%s: %s: verdef vd_cnt field too small: %u\n" +msgid "verdef vd_aux field out of range: %u" msgstr "" -#: dynobj.cc:478 +#: dynobj.cc:456 #, c-format -msgid "%s: %s: verdef vd_aux field out of range: %u\n" +msgid "verdaux vda_name field out of range: %u" msgstr "" -#: dynobj.cc:490 +#: dynobj.cc:465 #, c-format -msgid "%s: %s: verdaux vda_name field out of range: %u\n" +msgid "verdef vd_next field out of range: %u" msgstr "" -#: dynobj.cc:501 +#: dynobj.cc:498 #, c-format -msgid "%s: %s: verdef vd_next field out of range: %u\n" +msgid "unexpected verneed version %u" msgstr "" -#: dynobj.cc:535 +#: dynobj.cc:507 #, c-format -msgid "%s: %s: unexpected verneed version %u\n" +msgid "verneed vn_aux field out of range: %u" msgstr "" -#: dynobj.cc:546 +#: dynobj.cc:520 #, c-format -msgid "%s: %s: verneed vn_aux field out of range: %u\n" +msgid "vernaux vna_name field out of range: %u" msgstr "" -#: dynobj.cc:561 +#: dynobj.cc:531 #, c-format -msgid "%s: %s: vernaux vna_name field out of range: %u\n" +msgid "verneed vna_next field out of range: %u" msgstr "" -#: dynobj.cc:574 +#: dynobj.cc:542 #, c-format -msgid "%s: %s: verneed vna_next field out of range: %u\n" +msgid "verneed vn_next field out of range: %u" msgstr "" -#: dynobj.cc:587 -#, c-format -msgid "%s: %s: verneed vn_next field out of range: %u\n" +#: dynobj.cc:588 +msgid "size of dynamic symbols is not multiple of symbol size" msgstr "" -#: dynobj.cc:635 +#: dynobj.cc:1253 #, c-format -msgid "%s: %s: size of dynamic symbols is not multiple of symbol size\n" +msgid "symbol %s has undefined version %s" msgstr "" -#: dynobj.cc:1302 +#: errors.cc:77 #, c-format -msgid "%s: symbol %s has undefined version %s\n" +msgid "%s: warning: " +msgstr "" + +#: errors.cc:112 +#, c-format +msgid "%s: %s: warning: " +msgstr "" + +#: errors.cc:136 +#, c-format +msgid "%s: %s: undefined reference to '%s'\n" msgstr "" #: fileread.cc:49 #, c-format -msgid "%s: munmap failed: %s\n" +msgid "munmap failed: %s" msgstr "" -#: fileread.cc:84 +#: fileread.cc:90 #, c-format -msgid "%s: warning: close(%s) failed: %s" +msgid "close of %s failed: %s" msgstr "" -#: fileread.cc:109 +#: fileread.cc:114 #, c-format -msgid "%s: %s: fstat failed: %s" +msgid "%s: fstat failed: %s" msgstr "" -#: fileread.cc:199 +#: fileread.cc:210 #, c-format -msgid "%s: %s: pread failed: %s\n" +msgid "%s: pread failed: %s" msgstr "" -#: fileread.cc:206 +#: fileread.cc:216 #, c-format -msgid "%s: %s: file too short: read only %lld of %lld bytes at %lld\n" +msgid "%s: file too short: read only %lld of %lld bytes at %lld" msgstr "" -#: fileread.cc:284 +#: fileread.cc:292 #, c-format -msgid "%s: %s: mmap offset %lld size %lld failed: %s\n" +msgid "%s: mmap offset %lld size %lld failed: %s" msgstr "" -#: fileread.cc:422 +#: fileread.cc:371 #, c-format -msgid "%s: cannot find -l%s\n" +msgid "%s: total bytes mapped for read: %llu\n" msgstr "" -#: fileread.cc:449 +#: fileread.cc:373 #, c-format -msgid "%s: cannot find %s\n" +msgid "%s: maximum bytes mapped for read at one time: %llu\n" msgstr "" -#: fileread.cc:460 +#: fileread.cc:441 #, c-format -msgid "%s: cannot open %s: %s\n" +msgid "cannot find -l%s\n" msgstr "" -#: gold.cc:126 +#: fileread.cc:468 +#, c-format +msgid "cannot find %s\n" +msgstr "" + +#: fileread.cc:479 +#, c-format +msgid "cannot open %s: %s\n" +msgstr "" + +#: gold.cc:72 +#, c-format +msgid "%s: internal error in %s, at %s:%d\n" +msgstr "" + +#: gold.cc:118 msgid "no input files" msgstr "" +#. We print out just the first .so we see; there may be others. +#: gold.cc:161 +#, c-format +msgid "cannot mix -static with dynamic object %s" +msgstr "" + #: gold-threads.cc:66 msgid "pthead_mutextattr_init failed" msgstr "" @@ -270,177 +304,185 @@ msgid "pthread_cond_signal failed" msgstr "" #. FIXME: This needs to specify the location somehow. -#: i386.cc:139 x86_64.cc:146 -#, c-format -msgid "%s: missing expected TLS relocation\n" +#: i386.cc:142 i386.cc:1160 x86_64.cc:1138 +msgid "missing expected TLS relocation" msgstr "" -#: i386.cc:727 x86_64.cc:766 x86_64.cc:782 +#: i386.cc:728 x86_64.cc:700 x86_64.cc:840 #, c-format -msgid "%s: %s: unsupported reloc %u against local symbol\n" +msgid "%s: unsupported reloc %u against local symbol" msgstr "" -#: i386.cc:781 i386.cc:975 i386.cc:1256 x86_64.cc:737 x86_64.cc:898 -#: x86_64.cc:1215 +#: i386.cc:782 #, c-format -msgid "%s: %s: unexpected reloc %u in object file\n" +msgid "%s: unexpected reloc %u in object file\n" msgstr "" -#: i386.cc:871 x86_64.cc:927 x86_64.cc:940 +#: i386.cc:870 x86_64.cc:854 x86_64.cc:1024 #, c-format -msgid "%s: %s: unsupported reloc %u against global symbol %s\n" +msgid "%s: unsupported reloc %u against global symbol %s" msgstr "" -#: i386.cc:1072 +#: i386.cc:974 x86_64.cc:778 x86_64.cc:965 #, c-format -msgid "%s: %s: unsupported RELA reloc section\n" +msgid "%s: unexpected reloc %u in object file" msgstr "" -#: i386.cc:1162 x86_64.cc:1053 +#: i386.cc:1070 #, c-format -msgid "%s: %s: missing expected TLS relocation\n" +msgid "%s: unsupported RELA reloc section" msgstr "" -#: i386.cc:1290 i386.cc:1352 i386.cc:1367 i386.cc:1390 i386.cc:1413 -#: x86_64.cc:1237 x86_64.cc:1307 x86_64.cc:1315 +#: i386.cc:1252 x86_64.cc:1315 #, c-format -msgid "%s: %s: unsupported reloc %u\n" +msgid "unexpected reloc %u in object file" msgstr "" -#: i386.cc:1317 x86_64.cc:1264 +#: i386.cc:1284 i386.cc:1343 i386.cc:1356 i386.cc:1376 i386.cc:1397 +#: x86_64.cc:1337 x86_64.cc:1404 x86_64.cc:1413 #, c-format -msgid "%s: %s: TLS reloc but no TLS segment\n" +msgid "unsupported reloc %u" msgstr "" -#: i386.cc:1378 -#, c-format -msgid "%s: %s: both SUN and GNU model TLS relocations\n" +#: i386.cc:1309 x86_64.cc:1362 +msgid "TLS reloc but no TLS segment" msgstr "" -#: merge.cc:255 -#, c-format -msgid "" -"%s: %s: mergeable string section length not multiple of character size\n" +#: i386.cc:1364 +msgid "both SUN and GNU model TLS relocations" msgstr "" -#: merge.cc:272 -#, c-format -msgid "%s: %s: entry in mergeable string section not null terminated\n" +#: merge.cc:254 +msgid "mergeable string section length not multiple of character size" msgstr "" -#: object.cc:50 -#, c-format -msgid "%s: %s: unsupported ELF machine number %d\n" +#: merge.cc:269 +msgid "entry in mergeable string section not null terminated" msgstr "" -#: object.cc:106 +#: object.cc:49 #, c-format -msgid "%s: %s: section name section has wrong type: %u\n" +msgid "%s: unsupported ELF machine number %d" +msgstr "" + +#: object.cc:67 +#, c-format +msgid "%s: %s" +msgstr "" + +#: object.cc:102 +#, c-format +msgid "section name section has wrong type: %u" +msgstr "" + +#: object.cc:243 +#, c-format +msgid "invalid symbol table name index: %u" msgstr "" #: object.cc:249 #, c-format -msgid "%s: %s: invalid symbol table name index: %u\n" +msgid "symbol table name section has wrong type: %u" msgstr "" -#: object.cc:257 +#: object.cc:304 #, c-format -msgid "%s: %s: symbol table name section has wrong type: %u\n" +msgid "section group %u info %u out of range" msgstr "" -#: object.cc:313 +#: object.cc:322 #, c-format -msgid "%s: %s: section group %u info %u out of range\n" +msgid "symbol %u name offset %u out of range" msgstr "" -#: object.cc:331 +#: object.cc:354 #, c-format -msgid "%s: %s: symbol %u name offset %u out of range\n" +msgid "section %u in section group %u out of range" msgstr "" -#: object.cc:365 -#, c-format -msgid "%s: %s: section %u in section group %u out of range" +#: object.cc:494 +msgid "size of symbols is not multiple of symbol size" msgstr "" -#: object.cc:509 +#. FIXME: Handle SHN_XINDEX. +#: object.cc:584 #, c-format -msgid "%s: %s: size of symbols is not multiple of symbol size\n" +msgid "unknown section index %u for local symbol %u" msgstr "" -#: object.cc:601 +#: object.cc:593 #, c-format -msgid "%s: %s: unknown section index %u for local symbol %u\n" +msgid "local symbol %u section index %u out of range" msgstr "" -#: object.cc:612 +#: object.cc:625 #, c-format -msgid "%s: %s: local symbol %u section index %u out of range\n" +msgid "local symbol %u section name out of range: %u >= %u" msgstr "" -#: object.cc:646 +#: object.cc:805 #, c-format -msgid "%s: %s: local symbol %u section name out of range: %u >= %u\n" +msgid "%s: incompatible target" msgstr "" -#: object.cc:895 +#: object.cc:872 #, c-format -msgid "%s: %s: unsupported ELF file type %d\n" +msgid "%s: unsupported ELF file type %d" msgstr "" -#: object.cc:914 object.cc:967 object.cc:1002 +#: object.cc:891 object.cc:937 object.cc:971 #, c-format -msgid "%s: %s: ELF file too short\n" +msgid "%s: ELF file too short" msgstr "" -#: object.cc:923 +#: object.cc:899 #, c-format -msgid "%s: %s: invalid ELF version 0\n" +msgid "%s: invalid ELF version 0" msgstr "" -#: object.cc:926 +#: object.cc:901 #, c-format -msgid "%s: %s: unsupported ELF version %d\n" +msgid "%s: unsupported ELF version %d" msgstr "" -#: object.cc:934 +#: object.cc:908 #, c-format -msgid "%s: %s: invalid ELF class 0\n" +msgid "%s: invalid ELF class 0" msgstr "" -#: object.cc:941 +#: object.cc:914 #, c-format -msgid "%s: %s: unsupported ELF class %d\n" +msgid "%s: unsupported ELF class %d" msgstr "" -#: object.cc:949 +#: object.cc:921 #, c-format -msgid "%s: %s: invalid ELF data encoding\n" +msgid "%s: invalid ELF data encoding" msgstr "" -#: object.cc:956 +#: object.cc:927 #, c-format -msgid "%s: %s: unsupported ELF data encoding %d\n" +msgid "%s: unsupported ELF data encoding %d" msgstr "" -#: object.cc:979 +#: object.cc:947 #, c-format -msgid "%s: %s: not configured to support 32-bit big-endian object\n" +msgid "%s: not configured to support 32-bit big-endian object" msgstr "" -#: object.cc:992 +#: object.cc:960 #, c-format -msgid "%s: %s: not configured to support 32-bit little-endian object\n" +msgid "%s: not configured to support 32-bit little-endian object" msgstr "" -#: object.cc:1014 +#: object.cc:981 #, c-format -msgid "%s: %s: not configured to support 64-bit big-endian object\n" +msgid "%s: not configured to support 64-bit big-endian object" msgstr "" -#: object.cc:1027 +#: object.cc:994 #, c-format -msgid "%s: %s: not configured to support 64-bit little-endian object\n" +msgid "%s: not configured to support 64-bit little-endian object" msgstr "" #: options.cc:139 @@ -547,211 +589,214 @@ msgid "Do not link against shared libraries" msgstr "" #: options.cc:351 +msgid "Print resource usage statistics" +msgstr "" + +#: options.cc:353 msgid "Set target system root directory" msgstr "" -#: options.cc:352 +#: options.cc:354 msgid "--sysroot DIR" msgstr "" -#: options.cc:354 +#: options.cc:356 msgid "Only set DT_NEEDED for dynamic libs if used" msgstr "" -#: options.cc:357 +#: options.cc:359 msgid "Always DT_NEEDED for dynamic libs (default)" msgstr "" -#: options.cc:360 +#: options.cc:362 msgid "Include all archive contents" msgstr "" -#: options.cc:364 +#: options.cc:366 msgid "Include only needed archive contents" msgstr "" -#: options.cc:367 +#: options.cc:369 msgid "Report usage information" msgstr "" -#: options.cc:369 +#: options.cc:371 msgid "Report version information" msgstr "" -#: options.cc:573 +#: options.cc:576 msgid "unexpected argument" msgstr "" -#: options.cc:580 options.cc:631 options.cc:732 +#: options.cc:583 options.cc:634 options.cc:735 msgid "missing argument" msgstr "" -#: options.cc:593 options.cc:640 +#: options.cc:596 options.cc:643 msgid "unknown option" msgstr "" -#: options.cc:648 +#: options.cc:651 #, c-format msgid "%s: missing group end" msgstr "" -#: options.cc:745 +#: options.cc:748 msgid "may not nest groups" msgstr "" -#: options.cc:755 +#: options.cc:758 msgid "group end without group start" msgstr "" -#: options.cc:765 +#: options.cc:768 #, c-format msgid "%s: use the --help option for usage information\n" msgstr "" -#: options.cc:774 script.cc:1169 +#: options.cc:777 #, c-format msgid "%s: %s: %s\n" msgstr "" -#: options.cc:783 +#: options.cc:786 #, c-format msgid "%s: -%c: %s\n" msgstr "" #: output.cc:1031 #, c-format -msgid "%s: %s: invalid alignment %lu for section \"%s\"\n" +msgid "invalid alignment %lu for section \"%s\"" msgstr "" -#: output.cc:1699 +#: output.cc:1697 #, c-format -msgid "%s: %s: open: %s\n" +msgid "%s: open: %s" msgstr "" -#: output.cc:1708 +#: output.cc:1702 #, c-format -msgid "%s: %s: lseek: %s\n" +msgid "%s: lseek: %s" msgstr "" -#: output.cc:1715 +#: output.cc:1705 #, c-format -msgid "%s: %s: write: %s\n" +msgid "%s: write: %s" +msgstr "" + +#: output.cc:1711 +#, c-format +msgid "%s: mmap: %s" +msgstr "" + +#: output.cc:1721 +#, c-format +msgid "%s: munmap: %s\n" msgstr "" #: output.cc:1725 #, c-format -msgid "%s: %s: mmap: %s\n" +msgid "%s: close: %s" msgstr "" -#: output.cc:1739 +#: readsyms.cc:94 #, c-format -msgid "%s: %s: munmap: %s\n" +msgid "%s: file is empty" msgstr "" -#: output.cc:1747 +#: readsyms.cc:129 #, c-format -msgid "%s: %s: close: %s\n" -msgstr "" - -#: readsyms.cc:93 -#, c-format -msgid "%s: %s: file is empty\n" -msgstr "" - -#: readsyms.cc:127 -#, c-format -msgid "%s: %s: ordinary object found in input group\n" +msgid "%s: ordinary object found in input group" msgstr "" #. Here we have to handle any other input file types we need. -#: readsyms.cc:175 +#: readsyms.cc:177 #, c-format -msgid "%s: %s: not an object or archive\n" +msgid "%s: not an object or archive" msgstr "" -#: reloc.cc:190 reloc.cc:436 +#: reloc.cc:190 reloc.cc:431 #, c-format -msgid "%s: %s: relocation section %u has bad info %u\n" +msgid "relocation section %u has bad info %u" msgstr "" -#: reloc.cc:209 reloc.cc:453 +#: reloc.cc:208 reloc.cc:447 #, c-format -msgid "%s: %s: relocation section %u uses unexpected symbol table %u\n" +msgid "relocation section %u uses unexpected symbol table %u" msgstr "" -#: reloc.cc:225 reloc.cc:472 +#: reloc.cc:223 reloc.cc:465 #, c-format -msgid "%s: %s: unexpected entsize for reloc section %u: %lu != %u" +msgid "unexpected entsize for reloc section %u: %lu != %u" msgstr "" -#: reloc.cc:236 reloc.cc:483 +#: reloc.cc:232 reloc.cc:474 #, c-format -msgid "%s: %s: reloc section %u size %lu uneven" +msgid "reloc section %u size %lu uneven" msgstr "" -#: resolve.cc:137 +#: resolve.cc:136 #, c-format -msgid "%s: %s: invalid STB_LOCAL symbol %s in external symbols\n" +msgid "%s: invalid STB_LOCAL symbol %s in external symbols" msgstr "" -#: resolve.cc:143 +#: resolve.cc:142 #, c-format -msgid "%s: %s: unsupported symbol binding %d for symbol %s\n" +msgid "%s: unsupported symbol binding %d for symbol %s" msgstr "" -#: symtab.cc:518 +#. Two definitions of the same symbol. +#. FIXME: Report locations. +#: resolve.cc:280 #, c-format -msgid "%s: %s: bad global symbol name offset %u at %lu\n" +msgid "multiple definition of %s\n" msgstr "" -#: symtab.cc:597 +#: script.cc:1169 #, c-format -msgid "%s: %s: too few symbol versions\n" +msgid "%s: %s\n" msgstr "" -#: symtab.cc:617 +#: symtab.cc:517 #, c-format -msgid "%s: %s: bad symbol name offset %u at %lu\n" +msgid "bad global symbol name offset %u at %zu" msgstr "" -#: symtab.cc:670 -#, c-format -msgid "%s: %s: versym for symbol %zu out of range: %u\n" +#: symtab.cc:595 +msgid "too few symbol versions" msgstr "" -#: symtab.cc:678 +#: symtab.cc:614 #, c-format -msgid "%s: %s: versym for symbol %zu has no name: %u\n" +msgid "bad symbol name offset %u at %zu" msgstr "" -#: symtab.cc:1248 symtab.cc:1451 +#: symtab.cc:665 #, c-format -msgid "%s: %s: unsupported symbol section 0x%x\n" +msgid "versym for symbol %zu out of range: %u" msgstr "" -#: symtab.cc:1671 +#: symtab.cc:672 #, c-format -msgid "%s: %s: warning: %s\n" +msgid "versym for symbol %zu has no name: %u" msgstr "" -#: target-reloc.h:190 +#: symtab.cc:1241 symtab.cc:1444 #, c-format -msgid "%s: %s: reloc has bad offset %zu\n" +msgid "%s: unsupported symbol section 0x%x" msgstr "" -#: target-reloc.h:200 +#: target-reloc.h:191 #, c-format -msgid "%s: %s: undefined reference to '%s'\n" +msgid "reloc has bad offset %zu" msgstr "" -#: tls.h:58 x86_64.cc:1463 -#, c-format -msgid "%s: %s: TLS relocation out of range\n" +#: tls.h:58 x86_64.cc:1538 +msgid "TLS relocation out of range" msgstr "" -#: tls.h:77 x86_64.cc:1481 -#, c-format -msgid "%s: %s: TLS relocation against invalid instruction\n" +#: tls.h:72 x86_64.cc:1551 +msgid "TLS relocation against invalid instruction" msgstr "" #. This output is intended to follow the GNU standards. @@ -769,12 +814,17 @@ msgid "" "This program has absolutely no warranty.\n" msgstr "" -#: x86_64.cc:963 -#, c-format -msgid "%s: %s: unsupported REL reloc section\n" +#. FIXME: This needs to specify the location somehow. +#: x86_64.cc:154 +msgid "missing expected TLS relocation\n" msgstr "" -#: x86_64.cc:1292 +#: x86_64.cc:1047 #, c-format -msgid "%s: %s: unsupported reloc type %u\n" +msgid "%s: unsupported REL reloc section" +msgstr "" + +#: x86_64.cc:1389 +#, c-format +msgid "unsupported reloc type %u" msgstr "" diff --git a/gold/readsyms.cc b/gold/readsyms.cc index 87e4fa4c030..45be6fb6e12 100644 --- a/gold/readsyms.cc +++ b/gold/readsyms.cc @@ -82,7 +82,8 @@ Read_symbols::run(Workqueue* workqueue) } Input_file* input_file = new Input_file(&this->input_argument_->file()); - input_file->open(this->options_, this->dirpath_); + if (!input_file->open(this->options_, this->dirpath_)) + return; // Read enough of the file to pick up the entire ELF header. @@ -90,9 +91,9 @@ Read_symbols::run(Workqueue* workqueue) if (filesize == 0) { - fprintf(stderr, _("%s: %s: file is empty\n"), - program_name, input_file->file().filename().c_str()); - gold_exit(false); + gold_error(_("%s: file is empty"), + input_file->file().filename().c_str()); + return; } unsigned char ehdr_buf[elfcpp::Elf_sizes<64>::ehdr_size]; @@ -116,6 +117,8 @@ Read_symbols::run(Workqueue* workqueue) Object* obj = make_elf_object(input_file->filename(), input_file, 0, ehdr_buf, read_size); + if (obj == NULL) + return; // We don't have a way to record a non-archive in an input // group. If this is an ordinary object file, we can't @@ -123,10 +126,9 @@ Read_symbols::run(Workqueue* workqueue) // object, then including it a second time changes nothing. if (this->input_group_ != NULL && !obj->is_dynamic()) { - fprintf(stderr, - _("%s: %s: ordinary object found in input group\n"), - program_name, input_file->name()); - gold_exit(false); + gold_error(_("%s: ordinary object found in input group"), + input_file->name()); + return; } Read_symbols_data* sd = new Read_symbols_data; @@ -172,9 +174,8 @@ Read_symbols::run(Workqueue* workqueue) return; // Here we have to handle any other input file types we need. - fprintf(stderr, _("%s: %s: not an object or archive\n"), - program_name, input_file->file().filename().c_str()); - gold_exit(false); + gold_error(_("%s: not an object or archive"), + input_file->file().filename().c_str()); } // Handle a group. We need to walk through the arguments over and diff --git a/gold/reloc.cc b/gold/reloc.cc index bf4b2d66ead..7647edf5110 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -187,9 +187,9 @@ Sized_relobj::do_read_relocs(Read_relocs_data* rd) unsigned int shndx = shdr.get_sh_info(); if (shndx >= shnum) { - fprintf(stderr, _("%s: %s: relocation section %u has bad info %u\n"), - program_name, this->name().c_str(), i, shndx); - gold_exit(false); + this->error(_("relocation section %u has bad info %u"), + i, shndx); + continue; } if (!this->is_section_included(shndx)) @@ -205,11 +205,10 @@ Sized_relobj::do_read_relocs(Read_relocs_data* rd) if (shdr.get_sh_link() != this->symtab_shndx_) { - fprintf(stderr, - _("%s: %s: relocation section %u uses unexpected " - "symbol table %u\n"), - program_name, this->name().c_str(), i, shdr.get_sh_link()); - gold_exit(false); + this->error(_("relocation section %u uses unexpected " + "symbol table %u"), + i, shdr.get_sh_link()); + continue; } off_t sh_size = shdr.get_sh_size(); @@ -221,22 +220,18 @@ Sized_relobj::do_read_relocs(Read_relocs_data* rd) reloc_size = elfcpp::Elf_sizes::rela_size; if (reloc_size != shdr.get_sh_entsize()) { - fprintf(stderr, - _("%s: %s: unexpected entsize for reloc section %u: " - "%lu != %u"), - program_name, this->name().c_str(), i, - static_cast(shdr.get_sh_entsize()), - reloc_size); - gold_exit(false); + this->error(_("unexpected entsize for reloc section %u: %lu != %u"), + i, static_cast(shdr.get_sh_entsize()), + reloc_size); + continue; } size_t reloc_count = sh_size / reloc_size; if (static_cast(reloc_count * reloc_size) != sh_size) { - fprintf(stderr, _("%s: %s: reloc section %u size %lu uneven"), - program_name, this->name().c_str(), i, - static_cast(sh_size)); - gold_exit(false); + this->error(_("reloc section %u size %lu uneven"), + i, static_cast(sh_size)); + continue; } rd->relocs.push_back(Section_relocs()); @@ -433,9 +428,9 @@ Sized_relobj::relocate_sections( unsigned int index = shdr.get_sh_info(); if (index >= this->shnum()) { - fprintf(stderr, _("%s: %s: relocation section %u has bad info %u\n"), - program_name, this->name().c_str(), i, index); - gold_exit(false); + this->error(_("relocation section %u has bad info %u"), + i, index); + continue; } if (!this->is_section_included(index)) @@ -449,11 +444,10 @@ Sized_relobj::relocate_sections( if (shdr.get_sh_link() != this->symtab_shndx_) { - fprintf(stderr, - _("%s: %s: relocation section %u uses unexpected " - "symbol table %u\n"), - program_name, this->name().c_str(), i, shdr.get_sh_link()); - gold_exit(false); + gold_error(_("relocation section %u uses unexpected " + "symbol table %u"), + i, shdr.get_sh_link()); + continue; } off_t sh_size = shdr.get_sh_size(); @@ -468,22 +462,18 @@ Sized_relobj::relocate_sections( if (reloc_size != shdr.get_sh_entsize()) { - fprintf(stderr, - _("%s: %s: unexpected entsize for reloc section %u: " - "%lu != %u"), - program_name, this->name().c_str(), i, - static_cast(shdr.get_sh_entsize()), + gold_error(_("unexpected entsize for reloc section %u: %lu != %u"), + i, static_cast(shdr.get_sh_entsize()), reloc_size); - gold_exit(false); + continue; } size_t reloc_count = sh_size / reloc_size; if (static_cast(reloc_count * reloc_size) != sh_size) { - fprintf(stderr, _("%s: %s: reloc section %u size %lu uneven"), - program_name, this->name().c_str(), i, - static_cast(sh_size)); - gold_exit(false); + gold_error(_("reloc section %u size %lu uneven"), + i, static_cast(sh_size)); + continue; } relinfo.reloc_shndx = i; diff --git a/gold/resolve.cc b/gold/resolve.cc index 87c175ad344..d5167d934ab 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -133,17 +133,17 @@ Symbol_table::resolve(Sized_symbol* to, break; case elfcpp::STB_LOCAL: - fprintf(stderr, - _("%s: %s: invalid STB_LOCAL symbol %s in external symbols\n"), - program_name, object->name().c_str(), to->name()); - gold_exit(false); + gold_error(_("%s: invalid STB_LOCAL symbol %s in external symbols"), + object->name().c_str(), to->name()); + frombits = global_flag; + break; default: - fprintf(stderr, - _("%s: %s: unsupported symbol binding %d for symbol %s\n"), - program_name, object->name().c_str(), - static_cast(sym.get_st_bind()), to->name()); - gold_exit(false); + gold_error(_("%s: unsupported symbol binding %d for symbol %s"), + object->name().c_str(), + static_cast(sym.get_st_bind()), to->name()); + frombits = global_flag; + break; } if (!object->is_dynamic()) @@ -276,9 +276,8 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, { case DEF * 16 + DEF: // Two definitions of the same symbol. - fprintf(stderr, _("%s: multiple definition of %s\n"), - program_name, to->name()); - // FIXME: Report locations. Record that we have seen an error. + // FIXME: Report locations. + gold_error(_("multiple definition of %s\n"), to->name()); return false; case WEAK_DEF * 16 + DEF: diff --git a/gold/script.cc b/gold/script.cc index 365cedf9c2e..b672385e98c 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -1166,9 +1166,7 @@ yyerror(void* closurev, const char* message) { Parser_closure* closure = static_cast(closurev); - fprintf(stderr, _("%s: %s: %s\n"), - program_name, closure->filename(), message); - gold_exit(false); + gold_error(_("%s: %s\n"), closure->filename(), message); } // Called by the bison parser to add a file to the link. diff --git a/gold/symtab.cc b/gold/symtab.cc index 00caed7224a..28729a88021 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -514,11 +514,9 @@ Symbol_table::add_from_relobj( unsigned int st_name = psym->get_st_name(); if (st_name >= sym_name_size) { - fprintf(stderr, - _("%s: %s: bad global symbol name offset %u at %lu\n"), - program_name, relobj->name().c_str(), st_name, - static_cast(i)); - gold_exit(false); + relobj->error(_("bad global symbol name offset %u at %zu"), + st_name, i); + continue; } const char* name = sym_names + st_name; @@ -594,9 +592,8 @@ Symbol_table::add_from_dynobj( if (versym != NULL && versym_size / 2 < count) { - fprintf(stderr, _("%s: %s: too few symbol versions\n"), - program_name, dynobj->name().c_str()); - gold_exit(false); + dynobj->error(_("too few symbol versions")); + return; } const int sym_size = elfcpp::Elf_sizes::sym_size; @@ -614,10 +611,9 @@ Symbol_table::add_from_dynobj( unsigned int st_name = sym.get_st_name(); if (st_name >= sym_name_size) { - fprintf(stderr, _("%s: %s: bad symbol name offset %u at %lu\n"), - program_name, dynobj->name().c_str(), st_name, - static_cast(i)); - gold_exit(false); + dynobj->error(_("bad symbol name offset %u at %zu"), + st_name, i); + continue; } const char* name = sym_names + st_name; @@ -666,18 +662,15 @@ Symbol_table::add_from_dynobj( if (v >= version_map->size()) { - fprintf(stderr, - _("%s: %s: versym for symbol %zu out of range: %u\n"), - program_name, dynobj->name().c_str(), i, v); - gold_exit(false); + dynobj->error(_("versym for symbol %zu out of range: %u"), i, v); + continue; } const char* version = (*version_map)[v]; if (version == NULL) { - fprintf(stderr, _("%s: %s: versym for symbol %zu has no name: %u\n"), - program_name, dynobj->name().c_str(), i, v); - gold_exit(false); + dynobj->error(_("versym for symbol %zu has no name: %u"), i, v); + continue; } Stringpool::Key version_key; @@ -1245,9 +1238,9 @@ Symbol_table::sized_finalize(unsigned index, off_t off, Stringpool* pool) if (shndx >= elfcpp::SHN_LORESERVE && shndx != elfcpp::SHN_ABS) { - fprintf(stderr, _("%s: %s: unsupported symbol section 0x%x\n"), - program_name, sym->name(), shndx); - gold_exit(false); + gold_error(_("%s: unsupported symbol section 0x%x"), + sym->name(), shndx); + shndx = elfcpp::SHN_UNDEF; } Object* symobj = sym->object(); @@ -1448,28 +1441,31 @@ Symbol_table::sized_write_globals(const Target* target, if (in_shndx >= elfcpp::SHN_LORESERVE && in_shndx != elfcpp::SHN_ABS) { - fprintf(stderr, _("%s: %s: unsupported symbol section 0x%x\n"), - program_name, sym->name(), in_shndx); - gold_exit(false); + gold_error(_("%s: unsupported symbol section 0x%x"), + sym->name(), in_shndx); + shndx = in_shndx; } - - Object* symobj = sym->object(); - if (symobj->is_dynamic()) - { - if (sym->needs_dynsym_value()) - value = target->dynsym_value(sym); - shndx = elfcpp::SHN_UNDEF; - } - else if (in_shndx == elfcpp::SHN_UNDEF - || in_shndx == elfcpp::SHN_ABS) - shndx = in_shndx; else { - Relobj* relobj = static_cast(symobj); - off_t secoff; - Output_section* os = relobj->output_section(in_shndx, &secoff); - gold_assert(os != NULL); - shndx = os->out_shndx(); + Object* symobj = sym->object(); + if (symobj->is_dynamic()) + { + if (sym->needs_dynsym_value()) + value = target->dynsym_value(sym); + shndx = elfcpp::SHN_UNDEF; + } + else if (in_shndx == elfcpp::SHN_UNDEF + || in_shndx == elfcpp::SHN_ABS) + shndx = in_shndx; + else + { + Relobj* relobj = static_cast(symobj); + off_t secoff; + Output_section* os = relobj->output_section(in_shndx, + &secoff); + gold_assert(os != NULL); + shndx = os->out_shndx(); + } } } break; @@ -1662,14 +1658,17 @@ Warnings::note_warnings(Symbol_table* symtab) // Issue a warning. This is called when we see a relocation against a // symbol for which has a warning. +template void -Warnings::issue_warning(const Symbol* sym, const std::string& location) const +Warnings::issue_warning(const Symbol* sym, + const Relocate_info* relinfo, + size_t relnum, off_t reloffset) const { gold_assert(sym->has_warning()); Warning_table::const_iterator p = this->warnings_.find(sym->name()); gold_assert(p != this->warnings_.end()); - fprintf(stderr, _("%s: %s: warning: %s\n"), program_name, location.c_str(), - p->second.text.c_str()); + gold_warning_at_location(relinfo, relnum, reloffset, + "%s", p->second.text.c_str()); } // Instantiate the templates we need. We could use the configure @@ -1780,4 +1779,37 @@ Symbol_table::add_from_dynobj<64, true>( const std::vector* version_map); #endif +#ifdef HAVE_TARGET_32_LITTLE +template +void +Warnings::issue_warning<32, false>(const Symbol* sym, + const Relocate_info<32, false>* relinfo, + size_t relnum, off_t reloffset) const; +#endif + +#ifdef HAVE_TARGET_32_BIG +template +void +Warnings::issue_warning<32, true>(const Symbol* sym, + const Relocate_info<32, true>* relinfo, + size_t relnum, off_t reloffset) const; +#endif + +#ifdef HAVE_TARGET_64_LITTLE +template +void +Warnings::issue_warning<64, false>(const Symbol* sym, + const Relocate_info<64, false>* relinfo, + size_t relnum, off_t reloffset) const; +#endif + +#ifdef HAVE_TARGET_64_BIG +template +void +Warnings::issue_warning<64, true>(const Symbol* sym, + const Relocate_info<64, true>* relinfo, + size_t relnum, off_t reloffset) const; +#endif + + } // End namespace gold. diff --git a/gold/symtab.h b/gold/symtab.h index 0dabd517d1b..58c0e50ccf7 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -728,9 +728,11 @@ class Warnings void note_warnings(Symbol_table* symtab); - // Issue a warning for a reference to SYM at LOCATION. + // Issue a warning for a reference to SYM at RELINFO's location. + template void - issue_warning(const Symbol* sym, const std::string& location) const; + issue_warning(const Symbol* sym, const Relocate_info*, + size_t relnum, off_t reloffset) const; private: Warnings(const Warnings&); @@ -876,9 +878,12 @@ class Symbol_table // Possibly issue a warning for a reference to SYM at LOCATION which // is in OBJ. + template void - issue_warning(const Symbol* sym, const std::string& location) const - { this->warnings_.issue_warning(sym, location); } + issue_warning(const Symbol* sym, + const Relocate_info* relinfo, + size_t relnum, off_t reloffset) const + { this->warnings_.issue_warning(sym, relinfo, relnum, reloffset); } // Set the dynamic symbol indexes. INDEX is the index of the first // global dynamic symbol. Pointers to the symbols are stored into diff --git a/gold/target-reloc.h b/gold/target-reloc.h index 2ebd3c97913..8b87963f57b 100644 --- a/gold/target-reloc.h +++ b/gold/target-reloc.h @@ -187,24 +187,19 @@ relocate_section( if (offset < 0 || offset >= view_size) { - fprintf(stderr, _("%s: %s: reloc has bad offset %zu\n"), - program_name, relinfo->location(i, offset).c_str(), - static_cast(offset)); - gold_exit(false); + gold_error_at_location(relinfo, i, offset, + _("reloc has bad offset %zu"), + static_cast(offset)); + continue; } if (sym != NULL && sym->is_undefined() && sym->binding() != elfcpp::STB_WEAK) - { - fprintf(stderr, _("%s: %s: undefined reference to '%s'\n"), - program_name, relinfo->location(i, offset).c_str(), - sym->name()); - gold_exit(false); - } + gold_undefined_symbol(sym, relinfo, i, offset); if (sym != NULL && sym->has_warning()) - relinfo->symtab->issue_warning(sym, relinfo->location(i, offset)); + relinfo->symtab->issue_warning(sym, relinfo, i, offset); } } diff --git a/gold/tls.h b/gold/tls.h index 9324701c105..7103d3febb3 100644 --- a/gold/tls.h +++ b/gold/tls.h @@ -54,12 +54,8 @@ check_range(const Relocate_info* relinfo, { off_t offset = rel_offset + off; if (offset < 0 || offset > view_size) - { - fprintf(stderr, _("%s: %s: TLS relocation out of range\n"), - program_name, - relinfo->location(relnum, rel_offset).c_str()); - gold_exit(false); - } + gold_error_at_location(relinfo, relnum, rel_offset, + _("TLS relocation out of range")); } // Check the validity of a TLS relocation. This is like assert. @@ -72,13 +68,8 @@ check_tls(const Relocate_info* relinfo, bool valid) { if (!valid) - { - fprintf(stderr, - _("%s: %s: TLS relocation against invalid instruction\n"), - program_name, - relinfo->location(relnum, rel_offset).c_str()); - gold_exit(false); - } + gold_error_at_location(relinfo, relnum, rel_offset, + _("TLS relocation against invalid instruction")); } diff --git a/gold/x86_64.cc b/gold/x86_64.cc index ea20c4281fe..e454e246e83 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -151,9 +151,7 @@ class Target_x86_64 : public Sized_target<64, false> if (this->skip_call_tls_get_addr_) { // FIXME: This needs to specify the location somehow. - fprintf(stderr, _("%s: missing expected TLS relocation\n"), - program_name); - gold_exit(false); + gold_error(_("missing expected TLS relocation\n")); } } @@ -699,8 +697,8 @@ void Target_x86_64::Scan::unsupported_reloc_local(Sized_relobj<64, false>* object, unsigned int r_type) { - fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"), - program_name, object->name().c_str(), r_type); + gold_error(_("%s: unsupported reloc %u against local symbol"), + object->name().c_str(), r_type); } // Scan a relocation for a local symbol. @@ -777,9 +775,8 @@ Target_x86_64::Scan::local(const General_options&, case elfcpp::R_X86_64_TPOFF64: case elfcpp::R_X86_64_DTPMOD64: case elfcpp::R_X86_64_TLSDESC: - fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"), - program_name, object->name().c_str(), r_type); - gold_exit(false); + gold_error(_("%s: unexpected reloc %u in object file"), + object->name().c_str(), r_type); break; // These are initial tls relocs, which are expected when linking @@ -840,8 +837,8 @@ Target_x86_64::Scan::local(const General_options&, case elfcpp::R_X86_64_SIZE32: // TODO(csilvers): correct? case elfcpp::R_X86_64_SIZE64: // TODO(csilvers): correct? default: - fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"), - program_name, object->name().c_str(), r_type); + gold_error(_("%s: unsupported reloc %u against local symbol"), + object->name().c_str(), r_type); break; } } @@ -854,9 +851,8 @@ Target_x86_64::Scan::unsupported_reloc_global(Sized_relobj<64, false>* object, unsigned int r_type, Symbol* gsym) { - fprintf(stderr, - _("%s: %s: unsupported reloc %u against global symbol %s\n"), - program_name, object->name().c_str(), r_type, gsym->name()); + gold_error(_("%s: unsupported reloc %u against global symbol %s"), + object->name().c_str(), r_type, gsym->name()); } // Scan a relocation for a global symbol. @@ -966,9 +962,8 @@ Target_x86_64::Scan::global(const General_options& options, case elfcpp::R_X86_64_TPOFF64: case elfcpp::R_X86_64_DTPMOD64: case elfcpp::R_X86_64_TLSDESC: - fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"), - program_name, object->name().c_str(), r_type); - gold_exit(false); + gold_error(_("%s: unexpected reloc %u in object file"), + object->name().c_str(), r_type); break; // These are initial tls relocs, which are expected for global() @@ -1026,9 +1021,8 @@ Target_x86_64::Scan::global(const General_options& options, case elfcpp::R_X86_64_SIZE32: // TODO(csilvers): correct? case elfcpp::R_X86_64_SIZE64: // TODO(csilvers): correct? default: - fprintf(stderr, - _("%s: %s: unsupported reloc %u against global symbol %s\n"), - program_name, object->name().c_str(), r_type, gsym->name()); + gold_error(_("%s: unsupported reloc %u against global symbol %s"), + object->name().c_str(), r_type, gsym->name()); break; } } @@ -1050,9 +1044,9 @@ Target_x86_64::scan_relocs(const General_options& options, { if (sh_type == elfcpp::SHT_REL) { - fprintf(stderr, _("%s: %s: unsupported REL reloc section\n"), - program_name, object->name().c_str()); - gold_exit(false); + gold_error(_("%s: unsupported REL reloc section"), + object->name().c_str()); + return; } gold::scan_relocs<64, false, Target_x86_64, elfcpp::SHT_RELA, @@ -1140,15 +1134,14 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo, || gsym == NULL || strcmp(gsym->name(), "__tls_get_addr") != 0) { - fprintf(stderr, _("%s: %s: missing expected TLS relocation\n"), - program_name, - relinfo->location(relnum, rela.get_r_offset()).c_str()); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rela.get_r_offset(), + _("missing expected TLS relocation")); + } + else + { + this->skip_call_tls_get_addr_ = false; + return false; } - - this->skip_call_tls_get_addr_ = false; - - return false; } // Pick the value to use for symbols defined in shared objects. @@ -1318,11 +1311,9 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo, case elfcpp::R_X86_64_TPOFF64: case elfcpp::R_X86_64_DTPMOD64: case elfcpp::R_X86_64_TLSDESC: - fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"), - program_name, - relinfo->location(relnum, rela.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rela.get_r_offset(), + _("unexpected reloc %u in object file"), + r_type); break; // These are initial tls relocs, which are expected when linking @@ -1342,11 +1333,9 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo, case elfcpp::R_X86_64_SIZE64: // TODO(csilvers): correct? case elfcpp::R_X86_64_PLTOFF64: // TODO(csilvers): implement me! default: - fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), - program_name, - relinfo->location(relnum, rela.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rela.get_r_offset(), + _("unsupported reloc %u"), + r_type); break; } @@ -1369,10 +1358,9 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, Output_segment* tls_segment = relinfo->layout->tls_segment(); if (tls_segment == NULL) { - fprintf(stderr, _("%s: %s: TLS reloc but no TLS segment\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str()); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("TLS reloc but no TLS segment")); + return; } elfcpp::Elf_types<64>::Elf_Addr value = psymval->value(relinfo->object, 0); @@ -1397,11 +1385,9 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, view_size); break; } - fprintf(stderr, _("%s: %s: unsupported reloc type %u\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("unsupported reloc type %u"), + r_type); break; case elfcpp::R_X86_64_TLSGD: @@ -1414,11 +1400,8 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, view_size); break; } - fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("unsupported reloc %u"), r_type); break; case elfcpp::R_X86_64_TLSLD: @@ -1426,11 +1409,8 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, { // FIXME: implement ld_to_le } - fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str(), - r_type); - gold_exit(false); + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("unsupported reloc %u"), r_type); break; case elfcpp::R_X86_64_DTPOFF32: @@ -1554,12 +1534,8 @@ Target_x86_64::Relocate::check_range(const Relocate_info<64, false>* relinfo, { off_t offset = rel.get_r_offset() + off; if (offset < 0 || offset > view_size) - { - fprintf(stderr, _("%s: %s: TLS relocation out of range\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str()); - gold_exit(false); - } + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("TLS relocation out of range")); } // Check the validity of a TLS relocation. This is like assert. @@ -1571,13 +1547,8 @@ Target_x86_64::Relocate::check_tls(const Relocate_info<64, false>* relinfo, bool valid) { if (!valid) - { - fprintf(stderr, - _("%s: %s: TLS relocation against invalid instruction\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str()); - gold_exit(false); - } + gold_error_at_location(relinfo, relnum, rel.get_r_offset(), + _("TLS relocation against invalid instruction")); } // Relocate section data.