// Class Symbol.
-// Initialize fields in Symbol. This initializes everything except u_
-// and source_.
+// Initialize fields in Symbol. This initializes everything except
+// u1_, u2_ and source_.
void
Symbol::init_fields(const char* name, const char* version,
this->undef_binding_weak_ = false;
this->is_predefined_ = false;
this->is_protected_ = false;
+ this->non_zero_localentry_ = false;
}
// Return the demangled version of the symbol's name, but only
{
this->init_fields(name, version, sym.get_st_type(), sym.get_st_bind(),
sym.get_st_visibility(), sym.get_st_nonvis());
- this->u_.from_object.object = object;
- this->u_.from_object.shndx = st_shndx;
+ this->u1_.object = object;
+ this->u2_.shndx = st_shndx;
this->is_ordinary_shndx_ = is_ordinary;
this->source_ = FROM_OBJECT;
this->in_reg_ = !object->is_dynamic();
bool is_predefined)
{
this->init_fields(name, version, type, binding, visibility, nonvis);
- this->u_.in_output_data.output_data = od;
- this->u_.in_output_data.offset_is_from_end = offset_is_from_end;
+ this->u1_.output_data = od;
+ this->u2_.offset_is_from_end = offset_is_from_end;
this->source_ = IN_OUTPUT_DATA;
this->in_reg_ = true;
this->in_real_elf_ = true;
bool is_predefined)
{
this->init_fields(name, version, type, binding, visibility, nonvis);
- this->u_.in_output_segment.output_segment = os;
- this->u_.in_output_segment.offset_base = offset_base;
+ this->u1_.output_segment = os;
+ this->u2_.offset_base = offset_base;
this->source_ = IN_OUTPUT_SEGMENT;
this->in_reg_ = true;
this->in_real_elf_ = true;
{
gold_assert(this->is_common());
this->source_ = IN_OUTPUT_DATA;
- this->u_.in_output_data.output_data = od;
- this->u_.in_output_data.offset_is_from_end = false;
+ this->u1_.output_data = od;
+ this->u2_.offset_is_from_end = false;
}
// Initialize the fields in Sized_symbol for SYM in OBJECT.
{
case FROM_OBJECT:
{
- unsigned int shndx = this->u_.from_object.shndx;
+ unsigned int shndx = this->u2_.shndx;
if (shndx != elfcpp::SHN_UNDEF && this->is_ordinary_shndx_)
{
- gold_assert(!this->u_.from_object.object->is_dynamic());
- gold_assert(this->u_.from_object.object->pluginobj() == NULL);
- Relobj* relobj = static_cast<Relobj*>(this->u_.from_object.object);
+ gold_assert(!this->u1_.object->is_dynamic());
+ gold_assert(this->u1_.object->pluginobj() == NULL);
+ Relobj* relobj = static_cast<Relobj*>(this->u1_.object);
return relobj->output_section(shndx);
}
return NULL;
}
case IN_OUTPUT_DATA:
- return this->u_.in_output_data.output_data->output_section();
+ return this->u1_.output_data->output_section();
case IN_OUTPUT_SEGMENT:
case IS_CONSTANT:
break;
case IS_CONSTANT:
this->source_ = IN_OUTPUT_DATA;
- this->u_.in_output_data.output_data = os;
- this->u_.in_output_data.offset_is_from_end = false;
+ this->u1_.output_data = os;
+ this->u2_.offset_is_from_end = false;
break;
case IN_OUTPUT_SEGMENT:
case IS_UNDEFINED:
{
gold_assert(this->is_predefined_);
this->source_ = IN_OUTPUT_SEGMENT;
- this->u_.in_output_segment.output_segment = os;
- this->u_.in_output_segment.offset_base = base;
+ this->u1_.output_segment = os;
+ this->u2_.offset_base = base;
}
// Set the symbol to undefined. This is used for pre-defined
const char* name = sym_names + st_name;
if (!parameters->options().relocatable()
- && strcmp (name, "__gnu_lto_slim") == 0)
+ && name[0] == '_'
+ && name[1] == '_'
+ && strcmp (name + (name[2] == '_'), "__gnu_lto_slim") == 0)
gold_info(_("%s: plugin needed to handle lto object"),
relobj->name().c_str());
Sized_symbol<size>*
Symbol_table::define_special_symbol(const char** pname, const char** pversion,
bool only_if_ref,
+ elfcpp::STV visibility,
Sized_symbol<size>** poldsym,
bool* resolve_oldsym, bool is_forced_local)
{
oldsym = this->lookup(*pname, *pversion);
if (oldsym == NULL && is_default_version)
oldsym = this->lookup(*pname, NULL);
- if (oldsym == NULL || !oldsym->is_undefined())
+ if (oldsym == NULL)
return NULL;
+ if (!oldsym->is_undefined())
+ {
+ // Skip if the old definition is from a regular object.
+ if (!oldsym->is_from_dynobj())
+ return NULL;
+
+ // If the symbol has hidden or internal visibility, ignore
+ // definition and reference from a dynamic object.
+ if ((visibility == elfcpp::STV_HIDDEN
+ || visibility == elfcpp::STV_INTERNAL)
+ && !oldsym->in_reg())
+ return NULL;
+ }
*pname = oldsym->name();
if (is_default_version)
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol<size, true>(&name, &version,
- only_if_ref, &oldsym,
+ only_if_ref,
+ visibility,
+ &oldsym,
&resolve_oldsym,
is_forced_local);
#else
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
sym = this->define_special_symbol<size, false>(&name, &version,
- only_if_ref, &oldsym,
+ only_if_ref,
+ visibility,
+ &oldsym,
&resolve_oldsym,
is_forced_local);
#else
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol<size, true>(&name, &version,
- only_if_ref, &oldsym,
+ only_if_ref,
+ visibility,
+ &oldsym,
&resolve_oldsym,
is_forced_local);
#else
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
sym = this->define_special_symbol<size, false>(&name, &version,
- only_if_ref, &oldsym,
+ only_if_ref,
+ visibility,
+ &oldsym,
&resolve_oldsym,
is_forced_local);
#else
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol<size, true>(&name, &version,
- only_if_ref, &oldsym,
+ only_if_ref,
+ visibility,
+ &oldsym,
&resolve_oldsym,
is_forced_local);
#else
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
sym = this->define_special_symbol<size, false>(&name, &version,
- only_if_ref, &oldsym,
+ only_if_ref,
+ visibility,
+ &oldsym,
&resolve_oldsym,
is_forced_local);
#else
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol<size, true>(&name, &version,
- false, &oldsym,
+ false,
+ elfcpp::STV_DEFAULT,
+ &oldsym,
&resolve_oldsym,
false);
#else
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
sym = this->define_special_symbol<size, false>(&name, &version,
- false, &oldsym,
+ false,
+ elfcpp::STV_DEFAULT,
+ &oldsym,
&resolve_oldsym,
false);
#else