#include "target.h"
#include "object.h"
#include "symtab.h"
+#include "plugin.h"
namespace gold
{
// Symbol methods used in this file.
+// This symbol is being overridden by another symbol whose version is
+// VERSION. Update the VERSION_ field accordingly.
+
+inline void
+Symbol::override_version(const char* version)
+{
+ if (version == NULL)
+ {
+ // This is the case where this symbol is NAME/VERSION, and the
+ // version was not marked as hidden. That makes it the default
+ // version, so we create NAME/NULL. Later we see another symbol
+ // NAME/NULL, and that symbol is overriding this one. In this
+ // case, since NAME/VERSION is the default, we make NAME/NULL
+ // override NAME/VERSION as well. They are already the same
+ // Symbol structure. Setting the VERSION_ field to NULL ensures
+ // that it will be output with the correct, empty, version.
+ this->version_ = version;
+ }
+ else
+ {
+ // This is the case where this symbol is NAME/VERSION_ONE, and
+ // now we see NAME/VERSION_TWO, and NAME/VERSION_TWO is
+ // overriding NAME. If VERSION_ONE and VERSION_TWO are
+ // different, then this can only happen when VERSION_ONE is NULL
+ // and VERSION_TWO is not hidden.
+ gold_assert(this->version_ == version || this->version_ == NULL);
+ this->version_ = version;
+ }
+}
+
// Override the fields in Symbol.
template<int size, bool big_endian>
{
gold_assert(this->source_ == FROM_OBJECT);
this->u_.from_object.object = object;
- if (version != NULL && this->version() != version)
- {
- gold_assert(this->version() == NULL);
- this->version_ = version;
- }
+ this->override_version(version);
this->u_.from_object.shndx = st_shndx;
this->is_ordinary_shndx_ = is_ordinary;
this->type_ = sym.get_st_type();
// IS_ORDINARY is whether ST_SHNDX is a normal section index rather
// than a special code. ORIG_ST_SHNDX is the original section index,
// before any munging because of discarded sections, except that all
-// non-ordinary section indexes are mapped to SHN_UNDEF. VERSION of
+// non-ordinary section indexes are mapped to SHN_UNDEF. VERSION is
// the version of SYM.
template<int size, bool big_endian>
to->set_in_dyn();
}
+ // Record if we've seen this symbol in a real ELF object (i.e., the
+ // symbol is referenced from outside the world known to the plugin).
+ if (object->pluginobj() == NULL)
+ to->set_in_real_elf();
+
+ // If we're processing replacement files, allow new symbols to override
+ // the placeholders from the plugin objects.
+ if (to->source() == Symbol::FROM_OBJECT)
+ {
+ Pluginobj* obj = to->object()->pluginobj();
+ if (obj != NULL
+ && parameters->options().plugins()->in_replacement_phase())
+ {
+ this->override(to, sym, st_shndx, is_ordinary, object, version);
+ return;
+ }
+ }
+
unsigned int frombits = symbol_to_bits(sym.get_st_bind(),
object->is_dynamic(),
st_shndx, is_ordinary,
*adjust_common_sizes = false;
unsigned int tobits;
- if (to->source() != Symbol::FROM_OBJECT)
+ if (to->source() == Symbol::IS_UNDEFINED)
+ tobits = symbol_to_bits(to->binding(), false, elfcpp::SHN_UNDEF, true,
+ to->type());
+ else if (to->source() != Symbol::FROM_OBJECT)
tobits = symbol_to_bits(to->binding(), false, elfcpp::SHN_ABS, false,
to->type());
else
case IN_OUTPUT_SEGMENT:
this->u_.in_output_segment = from->u_.in_output_segment;
break;
- case CONSTANT:
+ case IS_CONSTANT:
+ case IS_UNDEFINED:
break;
default:
gold_unreachable();
break;
}
- if (from->version_ != NULL && this->version_ != from->version_)
- {
- gold_assert(this->version_ == NULL);
- this->version_ = from->version_;
- }
-
+ this->override_version(from->version_);
this->type_ = from->type_;
this->binding_ = from->binding_;
this->visibility_ = from->visibility_;