[GOLD] Reduce size of class Symbol

On 64-bit targets there is a 32-bit hole in symbol->u_, and another
due to symbol flags exceeding 32 bits.  By splitting the union,
the total size of the class reduces by one 64-bit word.

	* symtab.h (Symbol): Split u_ into u1_ and u2_.  Adjust accessors
	to suit.  Move plt_offset_ before got_offsets_.
	* symtab.cc (Symbol::init_fields): Adjust for union change.
	(Symbol::init_base_output_data): Likewise.
	(Symbol::init_base_output_segment): Likewise.
	(Symbol::allocate_base_common): Likewise.
	(Symbol::output_section): Likewise.
	(Symbol::set_output_section): Likewise.
	(Symbol::set_output_segment): Likewise.
	* resolve.cc (Symbol::override_base): Likewise.
	(Symbol::override_base_with_special): Likewise.
This commit is contained in:
Alan Modra 2017-08-29 15:52:45 +09:30
parent f2d394fce1
commit 34ca2bd7ac
4 changed files with 79 additions and 68 deletions

View File

@ -1,3 +1,17 @@
2017-08-29 Alan Modra <amodra@gmail.com>
* symtab.h (Symbol): Split u_ into u1_ and u2_. Adjust accessors
to suit. Move plt_offset_ before got_offsets_.
* symtab.cc (Symbol::init_fields): Adjust for union change.
(Symbol::init_base_output_data): Likewise.
(Symbol::init_base_output_segment): Likewise.
(Symbol::allocate_base_common): Likewise.
(Symbol::output_section): Likewise.
(Symbol::set_output_section): Likewise.
(Symbol::set_output_segment): Likewise.
* resolve.cc (Symbol::override_base): Likewise.
(Symbol::override_base_with_special): Likewise.
2017-08-28 Igor Kudrin <ikudrin@accesssoftek.com>
* aarch64.cc (Target_aarch64::Relocate::relocate_tls):

View File

@ -92,9 +92,9 @@ Symbol::override_base(const elfcpp::Sym<size, big_endian>& sym,
Object* object, const char* version)
{
gold_assert(this->source_ == FROM_OBJECT);
this->u_.from_object.object = object;
this->u1_.object = object;
this->override_version(version);
this->u_.from_object.shndx = st_shndx;
this->u2_.shndx = st_shndx;
this->is_ordinary_shndx_ = is_ordinary;
// Don't override st_type from plugin placeholder symbols.
if (object->pluginobj() == NULL)
@ -952,13 +952,10 @@ Symbol::override_base_with_special(const Symbol* from)
switch (from->source_)
{
case FROM_OBJECT:
this->u_.from_object = from->u_.from_object;
break;
case IN_OUTPUT_DATA:
this->u_.in_output_data = from->u_.in_output_data;
break;
case IN_OUTPUT_SEGMENT:
this->u_.in_output_segment = from->u_.in_output_segment;
this->u1_ = from->u1_;
this->u2_ = from->u2_;
break;
case IS_CONSTANT:
case IS_UNDEFINED:

View File

@ -47,8 +47,8 @@ namespace gold
// 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,
@ -120,8 +120,8 @@ Symbol::init_base_object(const char* name, const char* version, Object* object,
{
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();
@ -140,8 +140,8 @@ Symbol::init_base_output_data(const char* name, const char* version,
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;
@ -160,8 +160,8 @@ Symbol::init_base_output_segment(const char* name, const char* version,
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;
@ -206,8 +206,8 @@ Symbol::allocate_base_common(Output_data* od)
{
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.
@ -488,19 +488,19 @@ Symbol::output_section() const
{
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:
@ -527,8 +527,8 @@ Symbol::set_output_section(Output_section* os)
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:
@ -546,8 +546,8 @@ Symbol::set_output_segment(Output_segment* os, Segment_offset_base base)
{
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

View File

@ -159,7 +159,7 @@ class Symbol
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
@ -169,7 +169,7 @@ class Symbol
{
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
@ -179,7 +179,7 @@ class Symbol
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
@ -188,7 +188,7 @@ class Symbol
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,
@ -198,7 +198,7 @@ class Symbol
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,
@ -207,7 +207,7 @@ class Symbol
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.
@ -973,38 +973,38 @@ class Symbol
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 is used if SOURCE_ == FROM_OBJECT.
// Object in which symbol is defined, or in which it was first
// seen.
Object* 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 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 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_ == 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
@ -1018,16 +1018,16 @@ class Symbol
// 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).
@ -1069,7 +1069,7 @@ class Symbol
// 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;