summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-10-14 06:49:14 +0000
committerIan Lance Taylor <iant@google.com>2007-10-14 06:49:14 +0000
commit75f2446ec3c13eca3fe0c7cfdbb232e760d36596 (patch)
treea243e4c2c79cd8790a316a38b552507b62bf0421
parenteb4dfdd470e49ab56eed5cead19704e0926530d0 (diff)
downloadppe42-binutils-75f2446ec3c13eca3fe0c7cfdbb232e760d36596.tar.gz
ppe42-binutils-75f2446ec3c13eca3fe0c7cfdbb232e760d36596.zip
Run all error handling through an Errors object. Delete output file
on error.
-rw-r--r--gold/Makefile.am2
-rw-r--r--gold/Makefile.in16
-rw-r--r--gold/archive.cc76
-rw-r--r--gold/dirsearch.cc15
-rw-r--r--gold/dynobj.cc171
-rw-r--r--gold/errors.cc314
-rw-r--r--gold/errors.h111
-rw-r--r--gold/fileread.cc67
-rw-r--r--gold/fileread.h5
-rw-r--r--gold/gold.cc21
-rw-r--r--gold/gold.h42
-rw-r--r--gold/i386.cc106
-rw-r--r--gold/main.cc7
-rw-r--r--gold/merge.cc18
-rw-r--r--gold/object.cc204
-rw-r--r--gold/object.h2
-rw-r--r--gold/options.cc6
-rw-r--r--gold/output.cc43
-rw-r--r--gold/parameters.cc9
-rw-r--r--gold/parameters.h20
-rw-r--r--gold/po/POTFILES.in2
-rw-r--r--gold/po/gold.pot512
-rw-r--r--gold/readsyms.cc23
-rw-r--r--gold/reloc.cc64
-rw-r--r--gold/resolve.cc23
-rw-r--r--gold/script.cc4
-rw-r--r--gold/symtab.cc120
-rw-r--r--gold/symtab.h13
-rw-r--r--gold/target-reloc.h17
-rw-r--r--gold/tls.h17
-rw-r--r--gold/x86_64.cc115
31 files changed, 1258 insertions, 907 deletions
diff --git a/gold/Makefile.am b/gold/Makefile.am
index e9508de15e..1c54986781 100644
--- a/gold/Makefile.am
+++ b/gold/Makefile.am
@@ -30,6 +30,7 @@ CCFILES = \
dirsearch.cc \
dynobj.cc \
ehframe.cc \
+ errors.cc \
fileread.cc \
gold.cc \
gold-threads.cc \
@@ -56,6 +57,7 @@ HFILES = \
dirsearch.h \
dynobj.h \
ehframe.h \
+ errors.h \
fileread.h \
gold.h \
gold-threads.h \
diff --git a/gold/Makefile.in b/gold/Makefile.in
index 8c979bef1b..5f0bac3b05 100644
--- a/gold/Makefile.in
+++ b/gold/Makefile.in
@@ -72,12 +72,13 @@ libgold_a_AR = $(AR) $(ARFLAGS)
libgold_a_LIBADD =
am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) defstd.$(OBJEXT) \
dirsearch.$(OBJEXT) dynobj.$(OBJEXT) ehframe.$(OBJEXT) \
- fileread.$(OBJEXT) gold.$(OBJEXT) gold-threads.$(OBJEXT) \
- layout.$(OBJEXT) merge.$(OBJEXT) object.$(OBJEXT) \
- options.$(OBJEXT) output.$(OBJEXT) parameters.$(OBJEXT) \
- readsyms.$(OBJEXT) reloc.$(OBJEXT) resolve.$(OBJEXT) \
- script.$(OBJEXT) symtab.$(OBJEXT) stringpool.$(OBJEXT) \
- target-select.$(OBJEXT) version.$(OBJEXT) workqueue.$(OBJEXT)
+ errors.$(OBJEXT) fileread.$(OBJEXT) gold.$(OBJEXT) \
+ gold-threads.$(OBJEXT) layout.$(OBJEXT) merge.$(OBJEXT) \
+ object.$(OBJEXT) options.$(OBJEXT) output.$(OBJEXT) \
+ parameters.$(OBJEXT) readsyms.$(OBJEXT) reloc.$(OBJEXT) \
+ resolve.$(OBJEXT) script.$(OBJEXT) symtab.$(OBJEXT) \
+ stringpool.$(OBJEXT) target-select.$(OBJEXT) version.$(OBJEXT) \
+ workqueue.$(OBJEXT)
am__objects_2 =
am__objects_3 = yyscript.$(OBJEXT)
am_libgold_a_OBJECTS = $(am__objects_1) $(am__objects_2) \
@@ -283,6 +284,7 @@ CCFILES = \
dirsearch.cc \
dynobj.cc \
ehframe.cc \
+ errors.cc \
fileread.cc \
gold.cc \
gold-threads.cc \
@@ -309,6 +311,7 @@ HFILES = \
dirsearch.h \
dynobj.h \
ehframe.h \
+ errors.h \
fileread.h \
gold.h \
gold-threads.h \
@@ -457,6 +460,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirsearch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynobj.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehframe.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileread.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gold-threads.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gold.Po@am__quote@
diff --git a/gold/archive.cc b/gold/archive.cc
index d80718db75..e7a8782408 100644
--- a/gold/archive.cc
+++ b/gold/archive.cc
@@ -78,20 +78,15 @@ Archive::setup()
// The first member of the archive should be the symbol table.
std::string armap_name;
off_t armap_size = this->read_header(sarmag, &armap_name);
- off_t off;
+ off_t off = sarmag;
if (armap_name.empty())
{
this->read_armap(sarmag + sizeof(Archive_header), armap_size);
off = sarmag + sizeof(Archive_header) + armap_size;
}
else if (!this->input_file_->options().include_whole_archive())
- {
- fprintf(stderr, _("%s: %s: no archive symbol table (run ranlib)\n"),
- program_name, this->name().c_str());
- gold_exit(false);
- }
- else
- off = sarmag;
+ gold_error(_("%s: no archive symbol table (run ranlib)"),
+ this->name().c_str());
// See if there is an extended name table.
if ((off & 1) != 0)
@@ -140,11 +135,8 @@ Archive::read_armap(off_t start, off_t size)
}
if (reinterpret_cast<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())
diff --git a/gold/dirsearch.cc b/gold/dirsearch.cc
index 6dea53db71..45caf86daf 100644
--- a/gold/dirsearch.cc
+++ b/gold/dirsearch.cc
@@ -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
diff --git a/gold/dynobj.cc b/gold/dynobj.cc
index f2cf8e156e..2bf2373b84 100644
--- a/gold/dynobj.cc
+++ b/gold/dynobj.cc
@@ -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
index 0000000000..3aa3ece897
--- /dev/null
+++ b/gold/errors.cc
@@ -0,0 +1,314 @@
+// errors.cc -- handle errors for gold
+
+// Copyright 2006, 2007 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <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
index 0000000000..545c463bad
--- /dev/null
+++ b/gold/errors.h
@@ -0,0 +1,111 @@
+// errors.h -- handle errors for gold -*- C++ -*-
+
+// Copyright 2006, 2007 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <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)
diff --git a/gold/fileread.cc b/gold/fileread.cc
index 97773d23a7..ed14d98567 100644
--- a/gold/fileread.cc
+++ b/gold/fileread.cc
@@ -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.
diff --git a/gold/fileread.h b/gold/fileread.h
index cf4b3ab98a..c39f9de55b 100644
--- a/gold/fileread.h
+++ b/gold/fileread.h
@@ -290,8 +290,9 @@ class Input_file
// method.
Input_file(const char* name, const unsigned char* contents, off_t size);
- // Open the file.
- void
+ // Open the file. If the open fails, this will report an error and
+ // return false.
+ bool
open(const General_options&, const Dirsearch&);
// Return the name given by the user. For -lc this will return "c".
diff --git a/gold/gold.cc b/gold/gold.cc
index a4264087e7..139652430b 100644
--- a/gold/gold.cc
+++ b/gold/gold.cc
@@ -26,6 +26,7 @@
#include <cstdio>
#include <cstring>
#include <unistd.h>
+#include "libiberty.h"
#include "options.h"
#include "workqueue.h"
@@ -46,21 +47,12 @@ 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()
{
// We are out of memory, so try hard to print a reasonable message.
@@ -123,7 +115,7 @@ queue_initial_tasks(const General_options& options,
Symbol_table* symtab, Layout* layout)
{
if (cmdline.begin() == cmdline.end())
- gold_fatal(_("no input files"), false);
+ gold_fatal(_("no input files"));
// Read the input files. We have to add the symbols to the symbol
// table in order. We do this by creating a separate blocker for
@@ -166,9 +158,8 @@ queue_middle_tasks(const General_options& options,
if (!doing_static_link && options.is_static())
{
// We print out just the first .so we see; there may be others.
- fprintf(stderr, _("%s: cannot mix -static with dynamic object %s\n"),
- program_name, (*input_objects->dynobj_begin())->name().c_str());
- gold_exit(false);
+ gold_error(_("cannot mix -static with dynamic object %s"),
+ (*input_objects->dynobj_begin())->name().c_str());
}
// Define some sections and symbols needed for a dynamic link. This
diff --git a/gold/gold.h b/gold/gold.h
index 63bcb79c96..25f6c0c771 100644
--- a/gold/gold.h
+++ b/gold/gold.h
@@ -171,10 +171,13 @@ class Command_line;
class Input_argument_list;
class Dirsearch;
class Input_objects;
+class Symbol;
class Symbol_table;
class Layout;
class Workqueue;
class Output_file;
+template<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
diff --git a/gold/i386.cc b/gold/i386.cc
index fa564c4be5..837f5abdf8 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -139,9 +139,7 @@ class Target_i386 : public Sized_target<32, false>
if (this->skip_call_tls_get_addr_)
{
// FIXME: This needs to specify the location somehow.
- fprintf(stderr, _("%s: missing expected TLS relocation\n"),
- program_name);
- gold_exit(false);
+ gold_error(_("missing expected TLS relocation"));
}
}
@@ -727,8 +725,8 @@ void
Target_i386::Scan::unsupported_reloc_local(Sized_relobj<32, false>* object,
unsigned int r_type)
{
- fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"),
- program_name, object->name().c_str(), r_type);
+ gold_error(_("%s: unsupported reloc %u against local symbol"),
+ object->name().c_str(), r_type);
}
// Scan a relocation for a local symbol.
@@ -781,9 +779,8 @@ Target_i386::Scan::local(const General_options&,
case elfcpp::R_386_TLS_DTPOFF32:
case elfcpp::R_386_TLS_TPOFF32:
case elfcpp::R_386_TLS_DESC:
- fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
- program_name, object->name().c_str(), r_type);
- gold_exit(false);
+ gold_error(_("%s: unexpected reloc %u in object file\n"),
+ object->name().c_str(), r_type);
break;
// These are initial TLS relocs, which are expected when
@@ -870,9 +867,8 @@ Target_i386::Scan::unsupported_reloc_global(Sized_relobj<32, false>* object,
unsigned int r_type,
Symbol* gsym)
{
- fprintf(stderr,
- _("%s: %s: unsupported reloc %u against global symbol %s\n"),
- program_name, object->name().c_str(), r_type, gsym->name());
+ gold_error(_("%s: unsupported reloc %u against global symbol %s"),
+ object->name().c_str(), r_type, gsym->name());
}
// Scan a relocation for a global symbol.
@@ -975,9 +971,8 @@ Target_i386::Scan::global(const General_options& options,
case elfcpp::R_386_TLS_DTPOFF32:
case elfcpp::R_386_TLS_TPOFF32:
case elfcpp::R_386_TLS_DESC:
- fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
- program_name, object->name().c_str(), r_type);
- gold_exit(false);
+ gold_error(_("%s: unexpected reloc %u in object file"),
+ object->name().c_str(), r_type);
break;
// These are initial tls relocs, which are expected when
@@ -1072,9 +1067,9 @@ Target_i386::scan_relocs(const General_options& options,
{
if (sh_type == elfcpp::SHT_RELA)
{
- fprintf(stderr, _("%s: %s: unsupported RELA reloc section\n"),
- program_name, object->name().c_str());
- gold_exit(false);
+ gold_error(_("%s: unsupported RELA reloc section"),
+ object->name().c_str());
+ return;
}
gold::scan_relocs<32, false, Target_i386, elfcpp::SHT_REL,
@@ -1161,16 +1156,13 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
if (r_type != elfcpp::R_386_PLT32
|| gsym == NULL
|| strcmp(gsym->name(), "___tls_get_addr") != 0)
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("missing expected TLS relocation"));
+ else
{
- fprintf(stderr, _("%s: %s: missing expected TLS relocation\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str());
- gold_exit(false);
+ this->skip_call_tls_get_addr_ = false;
+ return false;
}
-
- this->skip_call_tls_get_addr_ = false;
-
- return false;
}
// Pick the value to use for symbols defined in shared objects.
@@ -1256,11 +1248,9 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
case elfcpp::R_386_TLS_DTPOFF32:
case elfcpp::R_386_TLS_TPOFF32:
case elfcpp::R_386_TLS_DESC:
- fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("unexpected reloc %u in object file"),
+ r_type);
break;
// These are initial tls relocs, which are expected when
@@ -1290,11 +1280,9 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
case elfcpp::R_386_TLS_LDM_POP:
case elfcpp::R_386_USED_BY_INTEL_200:
default:
- fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("unsupported reloc %u"),
+ r_type);
break;
}
@@ -1317,10 +1305,9 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
Output_segment* tls_segment = relinfo->layout->tls_segment();
if (tls_segment == NULL)
{
- fprintf(stderr, _("%s: %s: TLS reloc but no TLS segment\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str());
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("TLS reloc but no TLS segment"));
+ return;
}
elfcpp::Elf_types<32>::Elf_Addr value = psymval->value(relinfo->object, 0);
@@ -1352,11 +1339,9 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
view_size);
break;
}
- fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("unsupported reloc %u"),
+ r_type);
break;
case elfcpp::R_386_TLS_GD:
@@ -1367,21 +1352,18 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
view_size);
break;
}
- fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("unsupported reloc %u"),
+ r_type);
break;
case elfcpp::R_386_TLS_LDM:
if (this->local_dynamic_type_ == LOCAL_DYNAMIC_SUN)
{
- fprintf(stderr,
- _("%s: %s: both SUN and GNU model TLS relocations\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str());
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("both SUN and GNU model "
+ "TLS relocations"));
+ break;
}
this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
if (optimized_type == tls::TLSOPT_TO_LE)
@@ -1390,11 +1372,9 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
value, view, view_size);
break;
}
- fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("unsupported reloc %u"),
+ r_type);
break;
case elfcpp::R_386_TLS_LDO_32:
@@ -1413,11 +1393,9 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
case elfcpp::R_386_TLS_GOTDESC:
case elfcpp::R_386_TLS_DESC_CALL:
- fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("unsupported reloc %u"),
+ r_type);
break;
}
}
diff --git a/gold/main.cc b/gold/main.cc
index 49b50b2ca4..eda586bc67 100644
--- a/gold/main.cc
+++ b/gold/main.cc
@@ -29,6 +29,7 @@
#include "options.h"
#include "parameters.h"
+#include "errors.h"
#include "dirsearch.h"
#include "workqueue.h"
#include "object.h"
@@ -51,6 +52,8 @@ main(int argc, char** argv)
program_name = argv[0];
+ Errors errors(program_name);
+
// Handle the command line options.
Command_line command_line;
command_line.process(argc - 1, argv + 1);
@@ -59,7 +62,7 @@ main(int argc, char** argv)
if (command_line.options().print_stats())
start_time = get_run_time();
- initialize_parameters(&command_line.options());
+ initialize_parameters(&command_line.options(), &errors);
// The work queue.
Workqueue workqueue(command_line.options());
@@ -100,5 +103,5 @@ main(int argc, char** argv)
program_name, static_cast<long long>(layout.output_file_size()));
}
- gold_exit(true);
+ gold_exit(errors.error_count() == 0);
}
diff --git a/gold/merge.cc b/gold/merge.cc
index dc293abebd..f31b44e805 100644
--- a/gold/merge.cc
+++ b/gold/merge.cc
@@ -169,7 +169,7 @@ Output_merge_data::add_constant(const unsigned char* p)
this->alc_ *= 2;
this->p_ = static_cast<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;
}
}
diff --git a/gold/object.cc b/gold/object.cc
index d8b3b901d2..d655a4102f 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -46,28 +46,26 @@ Object::set_target(int machine, int size, bool big_endian, int osabi,
{
Target* target = select_target(machine, size, big_endian, osabi, abiversion);
if (target == NULL)
- {
- fprintf(stderr, _("%s: %s: unsupported ELF machine number %d\n"),
- program_name, this->name().c_str(), machine);
- gold_exit(false);
- }
+ gold_fatal(_("%s: unsupported ELF machine number %d"),
+ this->name().c_str(), machine);
this->target_ = target;
}
-// Report an error for the elfcpp::Elf_file interface.
+// Report an error for this object file. This is used by the
+// elfcpp::Elf_file interface, and also called by the Object code
+// itself.
void
-Object::error(const char* format, ...)
+Object::error(const char* format, ...) const
{
va_list args;
-
- fprintf(stderr, "%s: %s: ", program_name, this->name().c_str());
va_start(args, format);
- vfprintf(stderr, format, args);
+ char* buf = NULL;
+ if (vasprintf(&buf, format, args) < 0)
+ gold_nomem();
va_end(args);
- putc('\n', stderr);
-
- gold_exit(false);
+ gold_error(_("%s: %s"), this->name().c_str(), buf);
+ free(buf);
}
// Return a view of the contents of a section.
@@ -101,13 +99,8 @@ Object::read_section_data(elfcpp::Elf_file<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
}
}
diff --git a/gold/object.h b/gold/object.h
index 8f0a3b7726..1b8c1e2440 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -233,7 +233,7 @@ class Object
// Report an error.
void
- error(const char* format, ...) ATTRIBUTE_PRINTF_2;
+ error(const char* format, ...) const ATTRIBUTE_PRINTF_2;
// A location in the file.
struct Location
diff --git a/gold/options.cc b/gold/options.cc
index 89eecf66bb..0458139a59 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -215,7 +215,7 @@ help(int, char**, char*, gold::Command_line*)
std::puts(options[i].doc);
}
- gold::gold_exit(true);
+ ::exit(true);
return 0;
}
@@ -226,7 +226,7 @@ int
version(int, char**, char* opt, gold::Command_line*)
{
gold::print_version(opt[0] == 'v' && opt[1] == '\0');
- gold::gold_exit(true);
+ ::exit(true);
return 0;
}
@@ -767,7 +767,7 @@ Command_line::usage()
fprintf(stderr,
_("%s: use the --help option for usage information\n"),
program_name);
- gold_exit(false);
+ ::exit(false);
}
void
diff --git a/gold/output.cc b/gold/output.cc
index f539deac83..99a2954f8f 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -1028,10 +1028,9 @@ Output_section::add_input_section(Relobj* object, unsigned int shndx,
elfcpp::Elf_Xword addralign = shdr.get_sh_addralign();
if ((addralign & (addralign - 1)) != 0)
{
- fprintf(stderr, _("%s: %s: invalid alignment %lu for section \"%s\"\n"),
- program_name, object->name().c_str(),
- static_cast<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;
}
diff --git a/gold/parameters.cc b/gold/parameters.cc
index 337469a4ba..817268b162 100644
--- a/gold/parameters.cc
+++ b/gold/parameters.cc
@@ -30,8 +30,9 @@ namespace gold
// Initialize the parameters from the options.
-Parameters::Parameters(const General_options* options)
- : sysroot_(options->sysroot()),
+Parameters::Parameters(const General_options* options, Errors* errors)
+ : errors_(errors), output_file_name_(options->output_file_name()),
+ sysroot_(options->sysroot()),
is_doing_static_link_valid_(false), doing_static_link_(false),
is_size_and_endian_valid_(false), size_(0), is_big_endian_(false),
optimization_level_(options->optimization_level())
@@ -89,9 +90,9 @@ const Parameters* parameters;
// Initialize the global variable.
void
-initialize_parameters(const General_options* options)
+initialize_parameters(const General_options* options, Errors* errors)
{
- parameters = static_parameters = new Parameters(options);
+ parameters = static_parameters = new Parameters(options, errors);
}
// Set whether we are doing a static link.
diff --git a/gold/parameters.h b/gold/parameters.h
index 3b480c211b..c4e3fe311e 100644
--- a/gold/parameters.h
+++ b/gold/parameters.h
@@ -27,6 +27,7 @@ namespace gold
{
class General_options;
+class Errors;
// Here we define the Parameters class which simply holds simple
// general parameters which apply to the entire link. We use a global
@@ -39,7 +40,17 @@ class General_options;
class Parameters
{
public:
- Parameters(const General_options*);
+ Parameters(const General_options*, Errors*);
+
+ // Return the error object.
+ Errors*
+ errors() const
+ { return this->errors_; }
+
+ // Return the output file name.
+ const char*
+ output_file_name() const
+ { return this->output_file_name_; }
// Whether we are generating a regular executable.
bool
@@ -135,6 +146,11 @@ class Parameters
STRIP_DEBUG
};
+ // A pointer to the error handling object.
+ Errors* errors_;
+
+ // The output file name.
+ const char* output_file_name_;
// The type of the output file.
Output_file_type output_file_type_;
// The target system root directory.
@@ -160,7 +176,7 @@ class Parameters
extern const Parameters* parameters;
// Initialize the global variable.
-extern void initialize_parameters(const General_options*);
+extern void initialize_parameters(const General_options*, Errors*);
// Set the size and endianness of the global parameters variable.
extern void set_parameters_size_and_endianness(int size, bool is_big_endian);
diff --git a/gold/po/POTFILES.in b/gold/po/POTFILES.in
index a65d3a5223..bb32fdf9d9 100644
--- a/gold/po/POTFILES.in
+++ b/gold/po/POTFILES.in
@@ -10,6 +10,8 @@ dynobj.cc
dynobj.h
ehframe.cc
ehframe.h
+errors.cc
+errors.h
fileread.cc
fileread.h
gold.cc
diff --git a/gold/po/gold.pot b/gold/po/gold.pot
index 620182bc5c..12770a6482 100644
--- a/gold/po/gold.pot
+++ b/gold/po/gold.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-10-10 12:27-0700\n"
+"POT-Creation-Date: 2007-10-13 23:40-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <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 ""
diff --git a/gold/readsyms.cc b/gold/readsyms.cc
index 87e4fa4c03..45be6fb6e1 100644
--- a/gold/readsyms.cc
+++ b/gold/readsyms.cc
@@ -82,7 +82,8 @@ Read_symbols::run(Workqueue* workqueue)
}
Input_file* input_file = new Input_file(&this->input_argument_->file());
- input_file->open(this->options_, this->dirpath_);
+ if (!input_file->open(this->options_, this->dirpath_))
+ return;
// Read enough of the file to pick up the entire ELF header.
@@ -90,9 +91,9 @@ Read_symbols::run(Workqueue* workqueue)
if (filesize == 0)
{
- fprintf(stderr, _("%s: %s: file is empty\n"),
- program_name, input_file->file().filename().c_str());
- gold_exit(false);
+ gold_error(_("%s: file is empty"),
+ input_file->file().filename().c_str());
+ return;
}
unsigned char ehdr_buf[elfcpp::Elf_sizes<64>::ehdr_size];
@@ -116,6 +117,8 @@ Read_symbols::run(Workqueue* workqueue)
Object* obj = make_elf_object(input_file->filename(),
input_file, 0, ehdr_buf, read_size);
+ if (obj == NULL)
+ return;
// We don't have a way to record a non-archive in an input
// group. If this is an ordinary object file, we can't
@@ -123,10 +126,9 @@ Read_symbols::run(Workqueue* workqueue)
// object, then including it a second time changes nothing.
if (this->input_group_ != NULL && !obj->is_dynamic())
{
- fprintf(stderr,
- _("%s: %s: ordinary object found in input group\n"),
- program_name, input_file->name());
- gold_exit(false);
+ gold_error(_("%s: ordinary object found in input group"),
+ input_file->name());
+ return;
}
Read_symbols_data* sd = new Read_symbols_data;
@@ -172,9 +174,8 @@ Read_symbols::run(Workqueue* workqueue)
return;
// Here we have to handle any other input file types we need.
- fprintf(stderr, _("%s: %s: not an object or archive\n"),
- program_name, input_file->file().filename().c_str());
- gold_exit(false);
+ gold_error(_("%s: not an object or archive"),
+ input_file->file().filename().c_str());
}
// Handle a group. We need to walk through the arguments over and
diff --git a/gold/reloc.cc b/gold/reloc.cc
index bf4b2d66ea..7647edf511 100644
--- a/gold/reloc.cc
+++ b/gold/reloc.cc
@@ -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;
diff --git a/gold/resolve.cc b/gold/resolve.cc
index 87c175ad34..d5167d934a 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -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:
diff --git a/gold/script.cc b/gold/script.cc
index 365cedf9c2..b672385e98 100644
--- a/gold/script.cc
+++ b/gold/script.cc
@@ -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.
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 00caed7224..28729a8802 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -514,11 +514,9 @@ Symbol_table::add_from_relobj(
unsigned int st_name = psym->get_st_name();
if (st_name >= sym_name_size)
{
- fprintf(stderr,
- _("%s: %s: bad global symbol name offset %u at %lu\n"),
- program_name, relobj->name().c_str(), st_name,
- static_cast<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.
diff --git a/gold/symtab.h b/gold/symtab.h
index 0dabd517d1..58c0e50ccf 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -728,9 +728,11 @@ class Warnings
void
note_warnings(Symbol_table* symtab);
- // Issue a warning for a reference to SYM at LOCATION.
+ // Issue a warning for a reference to SYM at RELINFO's location.
+ template<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
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index 2ebd3c9791..8b87963f57 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -187,24 +187,19 @@ relocate_section(
if (offset < 0 || offset >= view_size)
{
- fprintf(stderr, _("%s: %s: reloc has bad offset %zu\n"),
- program_name, relinfo->location(i, offset).c_str(),
- static_cast<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);
}
}
diff --git a/gold/tls.h b/gold/tls.h
index 9324701c10..7103d3febb 100644
--- a/gold/tls.h
+++ b/gold/tls.h
@@ -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"));
}
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index ea20c4281f..e454e246e8 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -151,9 +151,7 @@ class Target_x86_64 : public Sized_target<64, false>
if (this->skip_call_tls_get_addr_)
{
// FIXME: This needs to specify the location somehow.
- fprintf(stderr, _("%s: missing expected TLS relocation\n"),
- program_name);
- gold_exit(false);
+ gold_error(_("missing expected TLS relocation\n"));
}
}
@@ -699,8 +697,8 @@ void
Target_x86_64::Scan::unsupported_reloc_local(Sized_relobj<64, false>* object,
unsigned int r_type)
{
- fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"),
- program_name, object->name().c_str(), r_type);
+ gold_error(_("%s: unsupported reloc %u against local symbol"),
+ object->name().c_str(), r_type);
}
// Scan a relocation for a local symbol.
@@ -777,9 +775,8 @@ Target_x86_64::Scan::local(const General_options&,
case elfcpp::R_X86_64_TPOFF64:
case elfcpp::R_X86_64_DTPMOD64:
case elfcpp::R_X86_64_TLSDESC:
- fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
- program_name, object->name().c_str(), r_type);
- gold_exit(false);
+ gold_error(_("%s: unexpected reloc %u in object file"),
+ object->name().c_str(), r_type);
break;
// These are initial tls relocs, which are expected when linking
@@ -840,8 +837,8 @@ Target_x86_64::Scan::local(const General_options&,
case elfcpp::R_X86_64_SIZE32: // TODO(csilvers): correct?
case elfcpp::R_X86_64_SIZE64: // TODO(csilvers): correct?
default:
- fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"),
- program_name, object->name().c_str(), r_type);
+ gold_error(_("%s: unsupported reloc %u against local symbol"),
+ object->name().c_str(), r_type);
break;
}
}
@@ -854,9 +851,8 @@ Target_x86_64::Scan::unsupported_reloc_global(Sized_relobj<64, false>* object,
unsigned int r_type,
Symbol* gsym)
{
- fprintf(stderr,
- _("%s: %s: unsupported reloc %u against global symbol %s\n"),
- program_name, object->name().c_str(), r_type, gsym->name());
+ gold_error(_("%s: unsupported reloc %u against global symbol %s"),
+ object->name().c_str(), r_type, gsym->name());
}
// Scan a relocation for a global symbol.
@@ -966,9 +962,8 @@ Target_x86_64::Scan::global(const General_options& options,
case elfcpp::R_X86_64_TPOFF64:
case elfcpp::R_X86_64_DTPMOD64:
case elfcpp::R_X86_64_TLSDESC:
- fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
- program_name, object->name().c_str(), r_type);
- gold_exit(false);
+ gold_error(_("%s: unexpected reloc %u in object file"),
+ object->name().c_str(), r_type);
break;
// These are initial tls relocs, which are expected for global()
@@ -1026,9 +1021,8 @@ Target_x86_64::Scan::global(const General_options& options,
case elfcpp::R_X86_64_SIZE32: // TODO(csilvers): correct?
case elfcpp::R_X86_64_SIZE64: // TODO(csilvers): correct?
default:
- fprintf(stderr,
- _("%s: %s: unsupported reloc %u against global symbol %s\n"),
- program_name, object->name().c_str(), r_type, gsym->name());
+ gold_error(_("%s: unsupported reloc %u against global symbol %s"),
+ object->name().c_str(), r_type, gsym->name());
break;
}
}
@@ -1050,9 +1044,9 @@ Target_x86_64::scan_relocs(const General_options& options,
{
if (sh_type == elfcpp::SHT_REL)
{
- fprintf(stderr, _("%s: %s: unsupported REL reloc section\n"),
- program_name, object->name().c_str());
- gold_exit(false);
+ gold_error(_("%s: unsupported REL reloc section"),
+ object->name().c_str());
+ return;
}
gold::scan_relocs<64, false, Target_x86_64, elfcpp::SHT_RELA,
@@ -1140,15 +1134,14 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
|| gsym == NULL
|| strcmp(gsym->name(), "__tls_get_addr") != 0)
{
- fprintf(stderr, _("%s: %s: missing expected TLS relocation\n"),
- program_name,
- relinfo->location(relnum, rela.get_r_offset()).c_str());
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
+ _("missing expected TLS relocation"));
+ }
+ else
+ {
+ this->skip_call_tls_get_addr_ = false;
+ return false;
}
-
- this->skip_call_tls_get_addr_ = false;
-
- return false;
}
// Pick the value to use for symbols defined in shared objects.
@@ -1318,11 +1311,9 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
case elfcpp::R_X86_64_TPOFF64:
case elfcpp::R_X86_64_DTPMOD64:
case elfcpp::R_X86_64_TLSDESC:
- fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
- program_name,
- relinfo->location(relnum, rela.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
+ _("unexpected reloc %u in object file"),
+ r_type);
break;
// These are initial tls relocs, which are expected when linking
@@ -1342,11 +1333,9 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
case elfcpp::R_X86_64_SIZE64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_PLTOFF64: // TODO(csilvers): implement me!
default:
- fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
- program_name,
- relinfo->location(relnum, rela.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
+ _("unsupported reloc %u"),
+ r_type);
break;
}
@@ -1369,10 +1358,9 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
Output_segment* tls_segment = relinfo->layout->tls_segment();
if (tls_segment == NULL)
{
- fprintf(stderr, _("%s: %s: TLS reloc but no TLS segment\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str());
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("TLS reloc but no TLS segment"));
+ return;
}
elfcpp::Elf_types<64>::Elf_Addr value = psymval->value(relinfo->object, 0);
@@ -1397,11 +1385,9 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
view_size);
break;
}
- fprintf(stderr, _("%s: %s: unsupported reloc type %u\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("unsupported reloc type %u"),
+ r_type);
break;
case elfcpp::R_X86_64_TLSGD:
@@ -1414,11 +1400,8 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
view_size);
break;
}
- fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("unsupported reloc %u"), r_type);
break;
case elfcpp::R_X86_64_TLSLD:
@@ -1426,11 +1409,8 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
{
// FIXME: implement ld_to_le
}
- fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str(),
- r_type);
- gold_exit(false);
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("unsupported reloc %u"), r_type);
break;
case elfcpp::R_X86_64_DTPOFF32:
@@ -1554,12 +1534,8 @@ Target_x86_64::Relocate::check_range(const Relocate_info<64, false>* relinfo,
{
off_t offset = rel.get_r_offset() + off;
if (offset < 0 || offset > view_size)
- {
- fprintf(stderr, _("%s: %s: TLS relocation out of range\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str());
- gold_exit(false);
- }
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("TLS relocation out of range"));
}
// Check the validity of a TLS relocation. This is like assert.
@@ -1571,13 +1547,8 @@ Target_x86_64::Relocate::check_tls(const Relocate_info<64, false>* relinfo,
bool valid)
{
if (!valid)
- {
- fprintf(stderr,
- _("%s: %s: TLS relocation against invalid instruction\n"),
- program_name,
- relinfo->location(relnum, rel.get_r_offset()).c_str());
- gold_exit(false);
- }
+ gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
+ _("TLS relocation against invalid instruction"));
}
// Relocate section data.
OpenPOWER on IntegriCloud