Run all error handling through an Errors object. Delete output file
authorIan Lance Taylor <iant@google.com>
Sun, 14 Oct 2007 06:49:14 +0000 (06:49 +0000)
committerIan Lance Taylor <iant@google.com>
Sun, 14 Oct 2007 06:49:14 +0000 (06:49 +0000)
on error.

31 files changed:
gold/Makefile.am
gold/Makefile.in
gold/archive.cc
gold/dirsearch.cc
gold/dynobj.cc
gold/errors.cc [new file with mode: 0644]
gold/errors.h [new file with mode: 0644]
gold/fileread.cc
gold/fileread.h
gold/gold.cc
gold/gold.h
gold/i386.cc
gold/main.cc
gold/merge.cc
gold/object.cc
gold/object.h
gold/options.cc
gold/output.cc
gold/parameters.cc
gold/parameters.h
gold/po/POTFILES.in
gold/po/gold.pot
gold/readsyms.cc
gold/reloc.cc
gold/resolve.cc
gold/script.cc
gold/symtab.cc
gold/symtab.h
gold/target-reloc.h
gold/tls.h
gold/x86_64.cc

index e9508de15e537c54be340946815369ace67b3f2a..1c5498678118422cbe1256a5332bc8a272eaff42 100644 (file)
@@ -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 \
index 8c979bef1b4eb4758581c5b5b053822a5ea9a130..5f0bac3b05c784b267e3096d0464d7bcad5cf8ed 100644 (file)
@@ -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@
index d80718db75839de4c3bffbeea985dd75d819f9ab..e7a87824080a9e920c55f7c17d2db4b1ff906d8c 100644 (file)
@@ -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<const unsigned char*>(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<long>(off));
-      gold_exit(false);
+      gold_error(_("%s: malformed archive header at %zu"),
+                this->name().c_str(), static_cast<size_t>(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<long>(off));
-      gold_exit(false);
+      gold_error(_("%s: malformed archive header size at %zu"),
+                this->name().c_str(), static_cast<size_t>(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<int>(sizeof hdr->ar_name))
        {
-         fprintf(stderr, _("%s: %s: malformed archive header name at %ld\n"),
-                 program_name, this->name().c_str(),
-                 static_cast<long>(off));
-         gold_exit(false);
+         gold_error(_("%s: malformed archive header name at %zu\n"),
+                    this->name().c_str(), static_cast<size_t>(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<size_t>(x) >= this->extended_names_.size())
        {
-         fprintf(stderr, _("%s: %s: bad extended name index at %ld\n"),
-                 program_name, this->name().c_str(),
-                 static_cast<long>(off));
-         gold_exit(false);
+         gold_error(_("%s: bad extended name index at %zu"),
+                    this->name().c_str(), static_cast<size_t>(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<size_t>(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<long>(off));
-         gold_exit(false);
+         gold_error(_("%s: bad extended name entry at header %zu"),
+                    this->name().c_str(), static_cast<size_t>(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<off_t>(sizeof(Archive_header)))
         {
           if (filesize != off)
-            {
-              fprintf(stderr, _("%s: %s: short archive header at %ld\n"),
-                      program_name, this->name().c_str(),
-                      static_cast<long>(off));
-              gold_exit(false);
-            }
-
+           gold_error(_("%s: short archive header at %zu"),
+                      this->name().c_str(), static_cast<size_t>(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<long>(off));
-      gold_exit(false);
+      gold_error(_("%s: member at %zu is not an ELF object"),
+                this->name().c_str(), static_cast<size_t>(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<long>(off));
-      gold_exit(false);
+      gold_error(_("%s: member at %zu is not an ELF object"),
+                this->name().c_str(), static_cast<size_t>(off));
+      return;
     }
 
   Object* obj = make_elf_object((std::string(this->input_file_->filename())
index 6dea53db7143a29eb9c3e68e447bc370f658ab12..45caf86daf269688f49863e29c4d98105c36bae5 100644 (file)
@@ -23,6 +23,7 @@
 #include "gold.h"
 
 #include <cerrno>
+#include <cstring>
 #include <sys/types.h>
 #include <dirent.h>
 
@@ -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
index f2cf8e156ea6cc04d8541c22a06edd13429cf62a..2bf2373b846cb493fbe2a27e55a905e55881dd87 100644 (file)
@@ -125,13 +125,8 @@ Sized_dynobj<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<long long>(val),
-                     static_cast<long long>(strtab_size));
-             gold_exit(false);
+             this->error(_("DT_SONAME value out of range: %lld >= %lld"),
+                        static_cast<long long>(val),
+                        static_cast<long long>(strtab_size));
+             return;
            }
 
          const char* strtab = reinterpret_cast<const char*>(strtabu);
@@ -256,9 +239,7 @@ Sized_dynobj<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<unsigned int>(strtabshdr.get_sh_type()));
-         gold_exit(false);
+         this->error(_("dynamic symbol table name section "
+                       "has wrong type: %u"),
+                     static_cast<unsigned int>(strtabshdr.get_sh_type()));
+         return;
        }
 
       sd->symbol_names = this->get_lasting_view(strtabshdr.get_sh_offset(),
@@ -386,11 +362,9 @@ Sized_dynobj<size, big_endian>::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<unsigned long>(shdr.get_sh_name()));
-         gold_exit(false);
+         this->error(_("bad section name offset for section %u: %lu"),
+                     i, static_cast<unsigned long>(shdr.get_sh_name()));
+         return;
        }
 
       const char* name = pnames + shdr.get_sh_name();
@@ -417,11 +391,7 @@ Sized_dynobj<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::do_add_symbols(Symbol_table* symtab,
   const size_t symcount = sd->symbols_size / sym_size;
   if (static_cast<off_t>(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 (file)
index 0000000..3aa3ece
--- /dev/null
@@ -0,0 +1,314 @@
+// errors.cc -- handle errors for gold
+
+// Copyright 2006, 2007 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+#include "gold.h"
+
+#include <cstdarg>
+#include <cstdio>
+
+#include "gold-threads.h"
+#include "parameters.h"
+#include "object.h"
+#include "symtab.h"
+#include "errors.h"
+
+namespace gold
+{
+
+// Class Errors.
+
+const int Errors::max_undefined_error_report;
+
+Errors::Errors(const char* program_name)
+  : program_name_(program_name), lock_(), 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<int size, bool big_endian>
+void
+Errors::error_at_location(const Relocate_info<size, big_endian>* relinfo,
+                         size_t relnum, off_t reloffset,
+                         const char* format, va_list args)
+{
+  fprintf(stderr, "%s: %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<int size, bool big_endian>
+void
+Errors::warning_at_location(const Relocate_info<size, big_endian>* relinfo,
+                           size_t relnum, off_t reloffset,
+                           const char* format, va_list args)
+{
+  fprintf(stderr, _("%s: %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<int size, bool big_endian>
+void
+Errors::undefined_symbol(const Symbol* sym,
+                        const Relocate_info<size, big_endian>* 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<int size, bool big_endian>
+void
+gold_error_at_location(const Relocate_info<size, big_endian>* relinfo,
+                      size_t relnum, off_t reloffset,
+                      const char* format, ...)
+{
+  va_list args;
+  va_start(args, format);
+  parameters->errors()->error_at_location(relinfo, relnum, reloffset,
+                                         format, args);
+  va_end(args);
+}
+
+// Report a warning at a location.
+
+template<int size, bool big_endian>
+void
+gold_warning_at_location(const Relocate_info<size, big_endian>* relinfo,
+                        size_t relnum, off_t reloffset,
+                        const char* format, ...)
+{
+  va_list args;
+  va_start(args, format);
+  parameters->errors()->warning_at_location(relinfo, relnum, reloffset,
+                                           format, args);
+  va_end(args);
+}
+
+// Report an undefined symbol.
+
+template<int size, bool big_endian>
+void
+gold_undefined_symbol(const Symbol* sym,
+                     const Relocate_info<size, big_endian>* 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 (file)
index 0000000..545c463
--- /dev/null
@@ -0,0 +1,111 @@
+// errors.h -- handle errors for gold  -*- C++ -*-
+
+// Copyright 2006, 2007 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+#ifndef GOLD_ERRORS_H
+#define GOLD_ERRORS_H
+
+#include <cstdarg>
+
+#include "gold-threads.h"
+
+namespace gold
+{
+
+class Symbol;
+template<int size, bool big_endian>
+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<int size, bool big_endian>
+  void
+  error_at_location(const Relocate_info<size, big_endian>* relinfo,
+                   size_t relnum, off_t reloffset,
+                   const char* format, va_list);
+
+  // Report a warning at a reloc location.
+  template<int size, bool big_endian>
+  void
+  warning_at_location(const Relocate_info<size, big_endian>* 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<int size, bool big_endian>
+  void
+  undefined_symbol(const Symbol* sym,
+                  const Relocate_info<size, big_endian>* 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<const Symbol*, int> undefined_symbols_;
+};
+
+} // End namespace gold.
+
+#endif // !defined(GOLD_ERRORS_H)
index 97773d23a7d2f157fa0d9cc2070bed015aff3644..ed14d98567be09e554254809e13eba9ebeff1be7 100644 (file)
@@ -46,8 +46,7 @@ File_read::View::~View()
   else
     {
       if (::munmap(const_cast<unsigned char*>(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<long long>(bytes),
-         static_cast<long long>(size),
-         static_cast<long long>(start));
-  gold_exit(false);
+  gold_fatal(_("%s: file too short: read only %lld of %lld bytes at %lld"),
+            this->filename().c_str(),
+            static_cast<long long>(bytes),
+            static_cast<long long>(size),
+            static_cast<long long>(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<long long>(poff),
-                  static_cast<long long>(psize),
-                  strerror(errno));
-          gold_exit(false);
-        }
+       gold_fatal(_("%s: mmap offset %lld size %lld failed: %s"),
+                  this->filename().c_str(),
+                  static_cast<long long>(poff),
+                  static_cast<long long>(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.
index cf4b3ab98aedcfa041513b7d26be52b8535b12c3..c39f9de55b2293ddc6882fa39a15618892df6b3a 100644 (file)
@@ -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".
index a4264087e7fbb314922a554c8bd196b1a7043c0a..139652430b020fa2bf6fd0ba5cecdea9e42ea154 100644 (file)
@@ -26,6 +26,7 @@
 #include <cstdio>
 #include <cstring>
 #include <unistd.h>
+#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
index 63bcb79c960e358115c5ad74a1597851312ff4b3..25f6c0c77120cde54b27e8095f441aa31e65a30b 100644 (file)
@@ -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<int size, bool big_endian>
+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* 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<int size, bool big_endian>
+extern void
+gold_error_at_location(const Relocate_info<size, big_endian>*,
+                      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<int size, bool big_endian>
+extern void
+gold_warning_at_location(const Relocate_info<size, big_endian>*,
+                        size_t, off_t, const char* format, ...)
+  ATTRIBUTE_PRINTF_4;
+
+// This function is called to report an undefined symbol.
+template<int size, bool big_endian>
 extern void
-gold_fatal(const char* msg, bool perrno) ATTRIBUTE_NORETURN;
+gold_undefined_symbol(const Symbol*,
+                     const Relocate_info<size, big_endian>*,
+                     size_t, off_t);
 
 // This is function is called in some cases if we run out of memory.
 extern void
index fa564c4be544ef03d46e4946752261f60452845a..837f5abdf843dfd181452739bc371e2aa0d7559b 100644 (file)
@@ -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;
     }
 }
index 49b50b2ca4cc0a99137349c233d6b18c994ab01e..eda586bc673c9c4d6c2d74375badc66810213f2b 100644 (file)
@@ -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<long long>(layout.output_file_size()));
     }
 
-  gold_exit(true);
+  gold_exit(errors.error_count() == 0);
 }
index dc293abebdfc8ef06083ba04b737f376d708f4cf..f31b44e805517f2da03259b1fec1d4b43d428287 100644 (file)
@@ -169,7 +169,7 @@ Output_merge_data::add_constant(const unsigned char* p)
        this->alc_ *= 2;
       this->p_ = static_cast<unsigned char*>(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<Char_type>::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<Char_type>::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;
            }
        }
 
index d8b3b901d2cd81a2177e544350a8379f0c03f8bd..d655a4102fd86cdff90ed2a06001e578ac47963f 100644 (file)
@@ -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<size, big_endian, Object>* elf_file,
   typename elfcpp::Shdr<size, big_endian> 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<unsigned int>(shdrnames.get_sh_type()));
-      gold_exit(false);
-    }
+    this->error(_("section name section has wrong type: %u"),
+               static_cast<unsigned int>(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<size, big_endian>::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<size, big_endian>::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<unsigned int>(strtabshdr.get_sh_type()));
-      gold_exit(false);
+      this->error(_("symbol table name section has wrong type: %u"),
+                 static_cast<unsigned int>(strtabshdr.get_sh_type()));
+      return;
     }
 
   // Read the symbol names.
@@ -310,9 +301,9 @@ Sized_relobj<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<unsigned long>(shdr.get_sh_name()));
-         gold_exit(false);
+         this->error(_("bad section name offset for section %u: %lu"),
+                     i, static_cast<unsigned long>(shdr.get_sh_name()));
+         return;
        }
 
       const char* name = pnames + shdr.get_sh_name();
@@ -505,10 +491,8 @@ Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
   size_t symcount = sd->symbols_size / sym_size;
   if (static_cast<off_t>(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<size, big_endian>::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<size, big_endian>::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<unsigned int>(strtab_size));
-         gold_exit(false);
+         this->error(_("local symbol %u section name out of range: %u >= %u"),
+                     i, sym.get_st_name(),
+                     static_cast<unsigned int>(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
        }
     }
index 8f0a3b7726e41c8c6a2bde09fe2605f38629c936..1b8c1e2440d7157151e046e1afd518e8c82ca103 100644 (file)
@@ -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
index 89eecf66bb8635b01e732535ed2c8808f8bda6b4..0458139a59e9761394e320b6dda7751d2b38c236 100644 (file)
@@ -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
index f539deac83d1d97f7d63c88c2a07edd92d5f65a5..99a2954f8f9d777a66ba60eee37ffa1ad47fd2b4 100644 (file)
@@ -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<unsigned long>(addralign), secname);
-      gold_exit(false);
+      object->error(_("invalid alignment %lu for section \"%s\""),
+                   static_cast<unsigned long>(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<unsigned char*>(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;
 }
 
index 337469a4ba623aabdf9506768bca90330893812f..817268b1624d0e69caeee172a3936cd1b7a88d64 100644 (file)
@@ -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.
index 3b480c211bda2458ec30c76bce50b4144044a145..c4e3fe311e98d5641d355684863fc4508f3bfeed 100644 (file)
@@ -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);
index a65d3a52239aa4d8c797e65c5627fd2d0ff172e7..bb32fdf9d9965d42aaec3cf6a601f6ef7c5e10ca 100644 (file)
@@ -10,6 +10,8 @@ dynobj.cc
 dynobj.h
 ehframe.cc
 ehframe.h
+errors.cc
+errors.h
 fileread.cc
 fileread.h
 gold.cc
index 620182bc5c46a4954f82b2b007dc0615db02ac76..12770a648227050ac81857b5f9edcc80d23f8821 100644 (file)
@@ -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 <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\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
+msgid "missing DT_NULL in dynamic segment"
+msgstr ""
+
+#: dynobj.cc:285
 #, c-format
-msgid "%s: %s: DT_SONAME value out of range: %lld >= %lld\n"
+msgid "invalid dynamic symbol table name index: %u"
 msgstr ""
 
-#: dynobj.cc:259
+#: dynobj.cc:292
 #, c-format
-msgid "%s: %s: missing DT_NULL in dynamic segment\n"
+msgid "dynamic symbol table name section has wrong type: %u"
 msgstr ""
 
-#: dynobj.cc:307
+#: dynobj.cc:365 object.cc:428
 #, c-format
-msgid "%s: %s: invalid dynamic symbol table name index: %u\n"
+msgid "bad section name offset for section %u: %lu"
 msgstr ""
 
-#: dynobj.cc:315
+#: dynobj.cc:394
 #, c-format
-msgid "%s: %s: dynamic symbol table name section has wrong type: %u\n"
+msgid "duplicate definition for version %u"
 msgstr ""
 
-#: dynobj.cc:390 object.cc:441
+#: dynobj.cc:423
 #, c-format
-msgid "%s: %s: bad section name offset for section %u: %lu\n"
+msgid "unexpected verdef version %u"
 msgstr ""
 
-#: dynobj.cc:421
+#: dynobj.cc:439
 #, c-format
-msgid "%s: %s: duplicate definition for version %u\n"
+msgid "verdef vd_cnt field too small: %u"
 msgstr ""
 
-#: dynobj.cc:453
+#: dynobj.cc:446
 #, c-format
-msgid "%s: %s: unexpected verdef version %u\n"
+msgid "verdef vd_aux field out of range: %u"
 msgstr ""
 
-#: dynobj.cc:469
+#: dynobj.cc:456
 #, c-format
-msgid "%s: %s: verdef vd_cnt field too small: %u\n"
+msgid "verdaux vda_name field out of range: %u"
 msgstr ""
 
-#: dynobj.cc:478
+#: dynobj.cc:465
 #, c-format
-msgid "%s: %s: verdef vd_aux field out of range: %u\n"
+msgid "verdef vd_next field out of range: %u"
 msgstr ""
 
-#: dynobj.cc:490
+#: dynobj.cc:498
 #, c-format
-msgid "%s: %s: verdaux vda_name field out of range: %u\n"
+msgid "unexpected verneed version %u"
 msgstr ""
 
-#: dynobj.cc:501
+#: dynobj.cc:507
 #, c-format
-msgid "%s: %s: verdef vd_next field out of range: %u\n"
+msgid "verneed vn_aux field out of range: %u"
 msgstr ""
 
-#: dynobj.cc:535
+#: dynobj.cc:520
 #, c-format
-msgid "%s: %s: unexpected verneed version %u\n"
+msgid "vernaux vna_name field out of range: %u"
 msgstr ""
 
-#: dynobj.cc:546
+#: dynobj.cc:531
 #, c-format
-msgid "%s: %s: verneed vn_aux field out of range: %u\n"
+msgid "verneed vna_next field out of range: %u"
 msgstr ""
 
-#: dynobj.cc:561
+#: dynobj.cc:542
 #, c-format
-msgid "%s: %s: vernaux vna_name field out of range: %u\n"
+msgid "verneed vn_next field out of range: %u"
+msgstr ""
+
+#: dynobj.cc:588
+msgid "size of dynamic symbols is not multiple of symbol size"
 msgstr ""
 
-#: dynobj.cc:574
+#: dynobj.cc:1253
 #, c-format
-msgid "%s: %s: verneed vna_next field out of range: %u\n"
+msgid "symbol %s has undefined version %s"
 msgstr ""
 
-#: dynobj.cc:587
+#: errors.cc:77
 #, c-format
-msgid "%s: %s: verneed vn_next field out of range: %u\n"
+msgid "%s: warning: "
 msgstr ""
 
-#: dynobj.cc:635
+#: errors.cc:112
 #, c-format
-msgid "%s: %s: size of dynamic symbols is not multiple of symbol size\n"
+msgid "%s: %s: warning: "
 msgstr ""
 
-#: dynobj.cc:1302
+#: errors.cc:136
 #, c-format
-msgid "%s: symbol %s has undefined version %s\n"
+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:90
+#, c-format
+msgid "close of %s failed: %s"
 msgstr ""
 
-#: fileread.cc:84
+#: fileread.cc:114
 #, c-format
-msgid "%s: warning: close(%s) failed: %s"
+msgid "%s: fstat failed: %s"
 msgstr ""
 
-#: fileread.cc:109
+#: fileread.cc:210
 #, c-format
-msgid "%s: %s: fstat failed: %s"
+msgid "%s: pread failed: %s"
 msgstr ""
 
-#: fileread.cc:199
+#: fileread.cc:216
 #, c-format
-msgid "%s: %s: pread failed: %s\n"
+msgid "%s: file too short: read only %lld of %lld bytes at %lld"
 msgstr ""
 
-#: fileread.cc:206
+#: fileread.cc:292
 #, c-format
-msgid "%s: %s: file too short: read only %lld of %lld bytes at %lld\n"
+msgid "%s: mmap offset %lld size %lld failed: %s"
 msgstr ""
 
-#: fileread.cc:284
+#: fileread.cc:371
 #, c-format
-msgid "%s: %s: mmap offset %lld size %lld failed: %s\n"
+msgid "%s: total bytes mapped for read: %llu\n"
 msgstr ""
 
-#: fileread.cc:422
+#: fileread.cc:373
 #, c-format
-msgid "%s: cannot find -l%s\n"
+msgid "%s: maximum bytes mapped for read at one time: %llu\n"
 msgstr ""
 
-#: fileread.cc:449
+#: fileread.cc:441
 #, c-format
-msgid "%s: cannot find %s\n"
+msgid "cannot find -l%s\n"
 msgstr ""
 
-#: fileread.cc:460
+#: fileread.cc:468
 #, c-format
-msgid "%s: cannot open %s: %s\n"
+msgid "cannot find %s\n"
 msgstr ""
 
-#: gold.cc:126
+#: 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
+#: i386.cc:1364
+msgid "both SUN and GNU model TLS relocations"
+msgstr ""
+
+#: merge.cc:254
+msgid "mergeable string section length not multiple of character size"
+msgstr ""
+
+#: merge.cc:269
+msgid "entry in mergeable string section not null terminated"
+msgstr ""
+
+#: object.cc:49
 #, c-format
-msgid ""
-"%s: %s: mergeable string section length not multiple of character size\n"
+msgid "%s: unsupported ELF machine number %d"
 msgstr ""
 
-#: merge.cc:272
+#: object.cc:67
 #, c-format
-msgid "%s: %s: entry in mergeable string section not null terminated\n"
+msgid "%s: %s"
 msgstr ""
 
-#: object.cc:50
+#: object.cc:102
 #, c-format
-msgid "%s: %s: unsupported ELF machine number %d\n"
+msgid "section name section has wrong type: %u"
 msgstr ""
 
-#: object.cc:106
+#: object.cc:243
 #, c-format
-msgid "%s: %s: section name section has wrong type: %u\n"
+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:1725
+#: output.cc:1711
 #, c-format
-msgid "%s: %s: mmap: %s\n"
+msgid "%s: mmap: %s"
 msgstr ""
 
-#: output.cc:1739
+#: output.cc:1721
 #, c-format
-msgid "%s: %s: munmap: %s\n"
+msgid "%s: munmap: %s\n"
 msgstr ""
 
-#: output.cc:1747
+#: output.cc:1725
 #, c-format
-msgid "%s: %s: close: %s\n"
+msgid "%s: close: %s"
 msgstr ""
 
-#: readsyms.cc:93
+#: readsyms.cc:94
 #, c-format
-msgid "%s: %s: file is empty\n"
+msgid "%s: file is empty"
 msgstr ""
 
-#: readsyms.cc:127
+#: readsyms.cc:129
 #, 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
+#. FIXME: This needs to specify the location somehow.
+#: x86_64.cc:154
+msgid "missing expected TLS relocation\n"
+msgstr ""
+
+#: x86_64.cc:1047
 #, c-format
-msgid "%s: %s: unsupported REL reloc section\n"
+msgid "%s: unsupported REL reloc section"
 msgstr ""
 
-#: x86_64.cc:1292
+#: x86_64.cc:1389
 #, c-format
-msgid "%s: %s: unsupported reloc type %u\n"
+msgid "unsupported reloc type %u"
 msgstr ""
index 87e4fa4c030dec63be754b256598676e467413cd..45be6fb6e12720313048bef6249f90380d91cb70 100644 (file)
@@ -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
index bf4b2d66ead92a6dbf4c1fcec9db20b8c45d0e20..7647edf511038ebd842830ebcbcb45f0c3cacf16 100644 (file)
@@ -187,9 +187,9 @@ Sized_relobj<size, big_endian>::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<size, big_endian>::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<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
        reloc_size = elfcpp::Elf_sizes<size>::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<unsigned long>(shdr.get_sh_entsize()),
-                 reloc_size);
-         gold_exit(false);
+         this->error(_("unexpected entsize for reloc section %u: %lu != %u"),
+                     i, static_cast<unsigned long>(shdr.get_sh_entsize()),
+                     reloc_size);
+         continue;
        }
 
       size_t reloc_count = sh_size / reloc_size;
       if (static_cast<off_t>(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<unsigned long>(sh_size));
-         gold_exit(false);
+         this->error(_("reloc section %u size %lu uneven"),
+                     i, static_cast<unsigned long>(sh_size));
+         continue;
        }
 
       rd->relocs.push_back(Section_relocs());
@@ -433,9 +428,9 @@ Sized_relobj<size, big_endian>::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<size, big_endian>::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<size, big_endian>::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<unsigned long>(shdr.get_sh_entsize()),
+         gold_error(_("unexpected entsize for reloc section %u: %lu != %u"),
+                    i, static_cast<unsigned long>(shdr.get_sh_entsize()),
                  reloc_size);
-         gold_exit(false);
+         continue;
        }
 
       size_t reloc_count = sh_size / reloc_size;
       if (static_cast<off_t>(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<unsigned long>(sh_size));
-         gold_exit(false);
+         gold_error(_("reloc section %u size %lu uneven"),
+                    i, static_cast<unsigned long>(sh_size));
+         continue;
        }
 
       relinfo.reloc_shndx = i;
index 87c175ad3442e59bda0465ed588bef2217c1b894..d5167d934ab35660b0d307db1ed89fdc697d0f08 100644 (file)
@@ -133,17 +133,17 @@ Symbol_table::resolve(Sized_symbol<size>* 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<int>(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<int>(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:
index 365cedf9c2ef8d68cee4b4b9a90480c84d2bbe2f..b672385e98cb00793cdfd866d171c0033deb9e88 100644 (file)
@@ -1166,9 +1166,7 @@ yyerror(void* closurev, const char* message)
 {
   Parser_closure* closure = static_cast<Parser_closure*>(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.
index 00caed7224a2c3e050fa7a3b891ed15cdbf1ed6d..28729a88021431d197f3927295809b06c1b4556e 100644 (file)
@@ -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<unsigned long>(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<size>::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<unsigned long>(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);
-             }
-
-           Object* symobj = sym->object();
-           if (symobj->is_dynamic())
-             {
-               if (sym->needs_dynsym_value())
-                 value = target->dynsym_value(sym);
-               shndx = elfcpp::SHN_UNDEF;
+               gold_error(_("%s: unsupported symbol section 0x%x"),
+                          sym->name(), in_shndx);
+               shndx = in_shndx;
              }
-           else if (in_shndx == elfcpp::SHN_UNDEF
-                    || in_shndx == elfcpp::SHN_ABS)
-             shndx = in_shndx;
            else
              {
-               Relobj* relobj = static_cast<Relobj*>(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<Relobj*>(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<int size, bool big_endian>
 void
-Warnings::issue_warning(const Symbol* sym, const std::string& location) const
+Warnings::issue_warning(const Symbol* sym,
+                       const Relocate_info<size, big_endian>* 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<const char*>* 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.
index 0dabd517d1b74de518432b14ff907c7d7f91ce33..58c0e50ccf7861bf8354ba070a6c7e98d2581a7e 100644 (file)
@@ -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<int size, bool big_endian>
   void
-  issue_warning(const Symbol* sym, const std::string& location) const;
+  issue_warning(const Symbol* sym, const Relocate_info<size, big_endian>*,
+               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<int size, bool big_endian>
   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<size, big_endian>* 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
index 2ebd3c97913c5c2b8ade9f87b2a8a2435ce534a8..8b87963f57b5370e3cd52d61a4363fb09903643e 100644 (file)
@@ -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<size_t>(offset));
-         gold_exit(false);
+         gold_error_at_location(relinfo, i, offset,
+                                _("reloc has bad offset %zu"),
+                                static_cast<size_t>(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);
     }
 }
 
index 9324701c105c73115fee390d4a76bac3abea8f9a..7103d3febb3ec12e368420df8cc520688978b496 100644 (file)
@@ -54,12 +54,8 @@ check_range(const Relocate_info<size, big_endian>* 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<size, big_endian>* 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"));
 }
 
 
index ea20c4281fec9e91fbc91f0a55848dae326e2fd6..e454e246e838692a6842f9dc17f69f5f3f7027cd 100644 (file)
@@ -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.