From: Alan Modra Date: Tue, 29 Aug 2017 06:22:45 +0000 (+0930) Subject: [GOLD] Reduce size of class Symbol X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=34ca2bd7ace5e208d46fea6e7a56a5376de0abfe;p=binutils-gdb.git [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. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index 7a1ea631005..04b68f846a6 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,17 @@ +2017-08-29 Alan Modra + + * 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 * aarch64.cc (Target_aarch64::Relocate::relocate_tls): diff --git a/gold/resolve.cc b/gold/resolve.cc index 7c226068007..042d03254de 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -92,9 +92,9 @@ Symbol::override_base(const elfcpp::Sym& 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: diff --git a/gold/symtab.cc b/gold/symtab.cc index 7e0a3f80d26..1555de6e5b3 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -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(this->u_.from_object.object); + gold_assert(!this->u1_.object->is_dynamic()); + gold_assert(this->u1_.object->pluginobj() == NULL); + Relobj* relobj = static_cast(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 diff --git a/gold/symtab.h b/gold/symtab.h index c371731b5eb..88d6c2782ba 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -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 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 @@ -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;