dynamic object.
// 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);
// 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)
program_name, obj->name().c_str());
gold_exit(false);
}
+
+ return true;
}
// Relocate_info methods.
{
public:
Input_objects()
- : relobj_list_(), target_(NULL)
+ : relobj_list_(), dynobj_list_(), target_(NULL), sonames_()
{ }
// The type of the list of input relocateable 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.
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
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"
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 ""
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 ""
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 ""
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;
}
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);
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;
// 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();
}
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
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
{
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.
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())
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()
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.