aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2006-12-06 06:28:56 +0000
committerIan Lance Taylor <iant@google.com>2006-12-06 06:28:56 +0000
commit008db82ec1ba308dba0fcf7767b93c1d56897bcc (patch)
tree93fef89fd7f3241e644fc770a3e59129a01f3407 /gold
parent8f2e9323f0b754011d0fa089bac65c9d28b73483 (diff)
downloadfsf-binutils-gdb-008db82ec1ba308dba0fcf7767b93c1d56897bcc.zip
fsf-binutils-gdb-008db82ec1ba308dba0fcf7767b93c1d56897bcc.tar.gz
fsf-binutils-gdb-008db82ec1ba308dba0fcf7767b93c1d56897bcc.tar.bz2
Don't emit symbols seen only in dynamic object, don't read duplicate
dynamic object.
Diffstat (limited to 'gold')
-rw-r--r--gold/dynobj.cc12
-rw-r--r--gold/object.cc26
-rw-r--r--gold/object.h12
-rw-r--r--gold/po/gold.pot36
-rw-r--r--gold/readsyms.cc15
-rw-r--r--gold/resolve.cc7
-rw-r--r--gold/symtab.cc13
-rw-r--r--gold/symtab.h12
8 files changed, 96 insertions, 37 deletions
diff --git a/gold/dynobj.cc b/gold/dynobj.cc
index 7afaaa5..1bd5a85 100644
--- a/gold/dynobj.cc
+++ b/gold/dynobj.cc
@@ -1324,12 +1324,12 @@ Versions::finalize(const Target* target, Symbol_table* symtab,
// Create a version symbol if necessary.
if (!(*p)->is_symbol_created())
{
- Symbol* vsym =symtab->define_as_constant(target, (*p)->name(),
- (*p)->name(), 0, 0,
- elfcpp::STT_OBJECT,
- elfcpp::STB_GLOBAL,
- elfcpp::STV_DEFAULT, 0,
- false);
+ Symbol* vsym = symtab->define_as_constant(target, (*p)->name(),
+ (*p)->name(), 0, 0,
+ elfcpp::STT_OBJECT,
+ elfcpp::STB_GLOBAL,
+ elfcpp::STV_DEFAULT, 0,
+ false);
vsym->set_needs_dynsym_entry();
++dynsym_index;
syms->push_back(vsym);
diff --git a/gold/object.cc b/gold/object.cc
index 2086fed..01c4c16 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -718,15 +718,29 @@ Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of,
// Input_objects methods.
-// Add a regular relocatable object to the list.
+// Add a regular relocatable object to the list. Return false if this
+// object should be ignored.
-void
+bool
Input_objects::add_object(Object* obj)
{
- if (obj->is_dynamic())
- this->dynobj_list_.push_back(static_cast<Dynobj*>(obj));
- else
+ if (!obj->is_dynamic())
this->relobj_list_.push_back(static_cast<Relobj*>(obj));
+ else
+ {
+ // See if this is a duplicate SONAME.
+ Dynobj* dynobj = static_cast<Dynobj*>(obj);
+
+ std::pair<Unordered_set<std::string>::iterator, bool> ins =
+ this->sonames_.insert(dynobj->soname());
+ if (!ins.second)
+ {
+ // We have already seen a dynamic object with this soname.
+ return false;
+ }
+
+ this->dynobj_list_.push_back(dynobj);
+ }
Target* target = obj->target();
if (this->target_ == NULL)
@@ -737,6 +751,8 @@ Input_objects::add_object(Object* obj)
program_name, obj->name().c_str());
gold_exit(false);
}
+
+ return true;
}
// Relocate_info methods.
diff --git a/gold/object.h b/gold/object.h
index b823599..2df04ab 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -600,7 +600,7 @@ class Input_objects
{
public:
Input_objects()
- : relobj_list_(), target_(NULL)
+ : relobj_list_(), dynobj_list_(), target_(NULL), sonames_()
{ }
// The type of the list of input relocateable objects.
@@ -611,8 +611,9 @@ class Input_objects
typedef std::vector<Dynobj*> Dynobj_list;
typedef Dynobj_list::const_iterator Dynobj_iterator;
- // Add an object to the list.
- void
+ // Add an object to the list. Return true if all is well, or false
+ // if this object should be ignored.
+ bool
add_object(Object*);
// Get the target we should use for the output file.
@@ -649,9 +650,14 @@ class Input_objects
Input_objects(const Input_objects&);
Input_objects& operator=(const Input_objects&);
+ // The list of ordinary objects included in the link.
Relobj_list relobj_list_;
+ // The list of dynamic objects included in the link.
Dynobj_list dynobj_list_;
+ // The target.
Target* target_;
+ // SONAMEs that we have seen.
+ Unordered_set<std::string> sonames_;
};
// Some of the information we pass to the relocation routines. We
diff --git a/gold/po/gold.pot b/gold/po/gold.pot
index abce13a..f89d7ce 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: 2006-12-05 15:53-0800\n"
+"POT-Creation-Date: 2006-12-05 17:51-0800\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"
@@ -166,7 +166,7 @@ msgstr ""
msgid "%s: %s: size of dynamic symbols is not multiple of symbol size\n"
msgstr ""
-#: dynobj.cc:1240
+#: dynobj.cc:1241
#, c-format
msgid "%s: symbol %s has undefined version %s\n"
msgstr ""
@@ -360,42 +360,42 @@ msgstr ""
msgid "%s: %s: local symbol %u section name out of range: %u >= %u\n"
msgstr ""
-#: object.cc:799
+#: object.cc:815
#, c-format
msgid "%s: %s: unsupported ELF file type %d\n"
msgstr ""
-#: object.cc:818 object.cc:871 object.cc:892
+#: object.cc:834 object.cc:887 object.cc:908
#, c-format
msgid "%s: %s: ELF file too short\n"
msgstr ""
-#: object.cc:827
+#: object.cc:843
#, c-format
msgid "%s: %s: invalid ELF version 0\n"
msgstr ""
-#: object.cc:830
+#: object.cc:846
#, c-format
msgid "%s: %s: unsupported ELF version %d\n"
msgstr ""
-#: object.cc:838
+#: object.cc:854
#, c-format
msgid "%s: %s: invalid ELF class 0\n"
msgstr ""
-#: object.cc:845
+#: object.cc:861
#, c-format
msgid "%s: %s: unsupported ELF class %d\n"
msgstr ""
-#: object.cc:853
+#: object.cc:869
#, c-format
msgid "%s: %s: invalid ELF data encoding\n"
msgstr ""
-#: object.cc:860
+#: object.cc:876
#, c-format
msgid "%s: %s: unsupported ELF data encoding %d\n"
msgstr ""
@@ -592,42 +592,42 @@ msgstr ""
msgid "%s: %s: unsupported symbol binding %d for symbol %s\n"
msgstr ""
-#: symtab.cc:445 symtab.cc:542
+#: symtab.cc:450 symtab.cc:547
#, c-format
msgid "%s: %s: mixing 32-bit and 64-bit ELF objects\n"
msgstr ""
-#: symtab.cc:462
+#: symtab.cc:467
#, c-format
msgid "%s: %s: bad global symbol name offset %u at %lu\n"
msgstr ""
-#: symtab.cc:549
+#: symtab.cc:554
#, c-format
msgid "%s: %s: too few symbol versions\n"
msgstr ""
-#: symtab.cc:569
+#: symtab.cc:574
#, c-format
msgid "%s: %s: bad symbol name offset %u at %lu\n"
msgstr ""
-#: symtab.cc:613
+#: symtab.cc:618
#, c-format
msgid "%s: %s: versym for symbol %zu out of range: %u\n"
msgstr ""
-#: symtab.cc:621
+#: symtab.cc:626
#, c-format
msgid "%s: %s: versym for symbol %zu has no name: %u\n"
msgstr ""
-#: symtab.cc:1093 symtab.cc:1265
+#: symtab.cc:1106 symtab.cc:1278
#, c-format
msgid "%s: %s: unsupported symbol section 0x%x\n"
msgstr ""
-#: symtab.cc:1458
+#: symtab.cc:1471
#, c-format
msgid "%s: %s: warning: %s\n"
msgstr ""
diff --git a/gold/readsyms.cc b/gold/readsyms.cc
index ba3e85e..86828fc 100644
--- a/gold/readsyms.cc
+++ b/gold/readsyms.cc
@@ -240,10 +240,17 @@ Add_symbols::locks(Workqueue* workqueue)
void
Add_symbols::run(Workqueue*)
{
- this->input_objects_->add_object(this->object_);
- this->object_->layout(this->options_, this->symtab_, this->layout_,
- this->sd_);
- this->object_->add_symbols(this->symtab_, this->sd_);
+ if (!this->input_objects_->add_object(this->object_))
+ {
+ // FIXME: We need to close the descriptor here.
+ delete this->object_;
+ }
+ else
+ {
+ this->object_->layout(this->options_, this->symtab_, this->layout_,
+ this->sd_);
+ this->object_->add_symbols(this->symtab_, this->sd_);
+ }
delete this->sd_;
this->sd_ = NULL;
}
diff --git a/gold/resolve.cc b/gold/resolve.cc
index 1272e05..1d87486 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -156,7 +156,12 @@ Symbol_table::resolve(Sized_symbol<size>* to,
gold_exit(false);
}
- if (object->is_dynamic())
+ if (!object->is_dynamic())
+ {
+ // Record that we've seen this symbol in a regular object.
+ to->set_in_reg();
+ }
+ else
{
frombits |= (1 << 1);
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 5b61152..01e000d 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -39,6 +39,7 @@ Symbol::init_fields(const char* name, const char* version,
this->is_def_ = false;
this->is_forwarder_ = false;
this->needs_dynsym_entry_ = false;
+ this->in_reg_ = false;
this->in_dyn_ = false;
this->has_got_offset_ = false;
this->has_warning_ = false;
@@ -57,6 +58,7 @@ Symbol::init_base(const char* name, const char* version, Object* object,
// FIXME: Handle SHN_XINDEX.
this->u_.from_object.shndx = sym.get_st_shndx();
this->source_ = FROM_OBJECT;
+ this->in_reg_ = !object->is_dynamic();
this->in_dyn_ = object->is_dynamic();
}
@@ -72,6 +74,7 @@ Symbol::init_base(const char* name, Output_data* od, elfcpp::STT type,
this->u_.in_output_data.output_data = od;
this->u_.in_output_data.offset_is_from_end = offset_is_from_end;
this->source_ = IN_OUTPUT_DATA;
+ this->in_reg_ = true;
}
// Initialize the fields in the base class Symbol for a symbol defined
@@ -86,6 +89,7 @@ Symbol::init_base(const char* name, Output_segment* os, elfcpp::STT type,
this->u_.in_output_segment.output_segment = os;
this->u_.in_output_segment.offset_base = offset_base;
this->source_ = IN_OUTPUT_SEGMENT;
+ this->in_reg_ = true;
}
// Initialize the fields in the base class Symbol for a symbol defined
@@ -98,6 +102,7 @@ Symbol::init_base(const char* name, elfcpp::STT type,
{
this->init_fields(name, NULL, type, binding, visibility, nonvis);
this->source_ = CONSTANT;
+ this->in_reg_ = true;
}
// Initialize the fields in Sized_symbol for SYM in OBJECT.
@@ -1078,6 +1083,14 @@ Symbol_table::sized_finalize(unsigned index, off_t off, Stringpool* pool)
if (sym->has_symtab_index())
continue;
+ if (!sym->in_reg())
+ {
+ gold_assert(!sym->has_symtab_index());
+ sym->set_symtab_index(-1U);
+ gold_assert(sym->dynsym_index() == -1U);
+ continue;
+ }
+
typename Sized_symbol<size>::Value_type value;
switch (sym->source())
diff --git a/gold/symtab.h b/gold/symtab.h
index 6e4344d4..66e98bc 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -185,6 +185,16 @@ class Symbol
set_needs_dynsym_entry()
{ this->needs_dynsym_entry_ = true; }
+ // Return whether this symbol has been seen in a regular object.
+ bool
+ in_reg() const
+ { return this->in_reg_; }
+
+ // Mark this symbol as having been seen in a regular object.
+ void
+ set_in_reg()
+ { this->in_reg_ = true; }
+
// Mark this symbol as having been seen in a dynamic object.
void
set_in_dyn()
@@ -469,6 +479,8 @@ class Symbol
bool is_forwarder_ : 1;
// True if this symbol needs to be in the dynamic symbol table.
bool needs_dynsym_entry_ : 1;
+ // True if we've seen this symbol in a regular object.
+ bool in_reg_ : 1;
// True if we've seen this symbol in a dynamic object.
bool in_dyn_ : 1;
// True if the symbol has an entry in the GOT section.