// symtab.h -- the gold symbol table -*- C++ -*-
-// Copyright (C) 2006-2017 Free Software Foundation, Inc.
+// Copyright (C) 2006-2019 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
object() const
{
gold_assert(this->source_ == FROM_OBJECT);
- return this->u_.from_object.object;
+ return this->u1_.object;
}
// Return the index of the section in the input relocatable or
{
gold_assert(this->source_ == FROM_OBJECT);
*is_ordinary = this->is_ordinary_shndx_;
- return this->u_.from_object.shndx;
+ return this->u2_.shndx;
}
// Return the output data section with which this symbol is
output_data() const
{
gold_assert(this->source_ == IN_OUTPUT_DATA);
- return this->u_.in_output_data.output_data;
+ return this->u1_.output_data;
}
// If this symbol was defined with respect to an output data
offset_is_from_end() const
{
gold_assert(this->source_ == IN_OUTPUT_DATA);
- return this->u_.in_output_data.offset_is_from_end;
+ return this->u2_.offset_is_from_end;
}
// Return the output segment with which this symbol is associated,
output_segment() const
{
gold_assert(this->source_ == IN_OUTPUT_SEGMENT);
- return this->u_.in_output_segment.output_segment;
+ return this->u1_.output_segment;
}
// If this symbol was defined with respect to an output segment,
offset_base() const
{
gold_assert(this->source_ == IN_OUTPUT_SEGMENT);
- return this->u_.in_output_segment.offset_base;
+ return this->u2_.offset_base;
}
// Return the symbol binding.
set_in_reg()
{ this->in_reg_ = true; }
+ // Forget this symbol was seen in a regular object.
+ void
+ clear_in_reg()
+ { this->in_reg_ = false; }
+
// Return whether this symbol has been seen in a dynamic object.
bool
in_dyn() const
set_in_dyn()
{ this->in_dyn_ = true; }
+ // Return whether this symbol is defined in a dynamic object.
+ bool
+ from_dyn() const
+ { return this->source_ == FROM_OBJECT && this->object()->is_dynamic(); }
+
// Return whether this symbol has been seen in a real ELF object.
// (IN_REG will return TRUE if the symbol has been seen in either
// a real ELF object or an object claimed by a plugin.)
set_non_zero_localentry()
{ this->non_zero_localentry_ = true; }
+ // Completely override existing symbol. Everything bar name_,
+ // version_, and is_forced_local_ flag are copied. version_ is
+ // cleared if from->version_ is clear. Returns true if this symbol
+ // should be forced local.
+ bool
+ clone(const Symbol* from);
+
protected:
// Instances of this class should always be created at a specific
// size.
Symbol()
- { memset(this, 0, sizeof *this); }
+ { memset(static_cast<void*>(this), 0, sizeof *this); }
// Initialize the general fields.
void
union
{
- // This struct is used if SOURCE_ == FROM_OBJECT.
- struct
- {
- // Object in which symbol is defined, or in which it was first
- // seen.
- Object* object;
- // Section number in object_ in which symbol is defined.
- unsigned int shndx;
- } from_object;
-
- // This struct is used if SOURCE_ == IN_OUTPUT_DATA.
- struct
- {
- // Output_data in which symbol is defined. Before
- // Layout::finalize the symbol's value is an offset within the
- // Output_data.
- Output_data* output_data;
- // True if the offset is from the end, false if the offset is
- // from the beginning.
- bool offset_is_from_end;
- } in_output_data;
-
- // This struct is used if SOURCE_ == IN_OUTPUT_SEGMENT.
- struct
- {
- // Output_segment in which the symbol is defined. Before
- // Layout::finalize the symbol's value is an offset.
- Output_segment* output_segment;
- // The base to use for the offset before Layout::finalize.
- Segment_offset_base offset_base;
- } in_output_segment;
- } u_;
+ // This is used if SOURCE_ == FROM_OBJECT.
+ // Object in which symbol is defined, or in which it was first
+ // seen.
+ Object* object;
+
+ // This is used if SOURCE_ == IN_OUTPUT_DATA.
+ // Output_data in which symbol is defined. Before
+ // Layout::finalize the symbol's value is an offset within the
+ // Output_data.
+ Output_data* output_data;
+
+ // This is used if SOURCE_ == IN_OUTPUT_SEGMENT.
+ // Output_segment in which the symbol is defined. Before
+ // Layout::finalize the symbol's value is an offset.
+ Output_segment* output_segment;
+ } u1_;
+
+ union
+ {
+ // This is used if SOURCE_ == FROM_OBJECT.
+ // Section number in object in which symbol is defined.
+ unsigned int shndx;
+
+ // This is used if SOURCE_ == IN_OUTPUT_DATA.
+ // True if the offset is from the end, false if the offset is
+ // from the beginning.
+ bool offset_is_from_end;
+
+ // This is used if SOURCE_ == IN_OUTPUT_SEGMENT.
+ // The base to use for the offset before Layout::finalize.
+ Segment_offset_base offset_base;
+ } u2_;
// The index of this symbol in the output file. If the symbol is
// not going into the output file, this value is -1U. This field
// non-zero value during Layout::finalize.
unsigned int dynsym_index_;
- // The GOT section entries for this symbol. A symbol may have more
- // than one GOT offset (e.g., when mixing modules compiled with two
- // different TLS models), but will usually have at most one.
- Got_offset_list got_offsets_;
-
// If this symbol has an entry in the PLT section, then this is the
// offset from the start of the PLT section. This is -1U if there
// is no PLT entry.
unsigned int plt_offset_;
+ // The GOT section entries for this symbol. A symbol may have more
+ // than one GOT offset (e.g., when mixing modules compiled with two
+ // different TLS models), but will usually have at most one.
+ Got_offset_list got_offsets_;
+
// Symbol type (bits 0 to 3).
elfcpp::STT type_ : 4;
// Symbol binding (bits 4 to 7).
// True if this symbol was forced to local visibility by a version
// script (bit 28).
bool is_forced_local_ : 1;
- // True if the field u_.from_object.shndx is an ordinary section
+ // True if the field u2_.shndx is an ordinary section
// index, not one of the special codes from SHN_LORESERVE to
// SHN_HIRESERVE (bit 29).
bool is_ordinary_shndx_ : 1;
void
allocate_common(Output_data*, Value_type value);
+ // Completely override existing symbol. Everything bar name_,
+ // version_, and is_forced_local_ flag are copied. version_ is
+ // cleared if from->version_ is clear. Returns true if this symbol
+ // should be forced local.
+ bool
+ clone(const Sized_symbol<size>* from);
+
private:
Sized_symbol(const Sized_symbol&);
Sized_symbol& operator=(const Sized_symbol&);
version_script() const
{ return version_script_; }
+ // Completely override existing symbol.
+ template<int size>
+ void
+ clone(Sized_symbol<size>* to, const Sized_symbol<size>* from)
+ {
+ if (to->clone(from))
+ this->force_local(to);
+ }
+
private:
Symbol_table(const Symbol_table&);
Symbol_table& operator=(const Symbol_table&);
template<int size, bool big_endian>
Sized_symbol<size>*
define_special_symbol(const char** pname, const char** pversion,
- bool only_if_ref, Sized_symbol<size>** poldsym,
+ bool only_if_ref, elfcpp::STV visibility,
+ Sized_symbol<size>** poldsym,
bool* resolve_oldsym, bool is_forced_local);
// Define a symbol in an Output_data, sized version.