From 82e498727a5086d51656a7407977a69d3f45720c Mon Sep 17 00:00:00 2001 From: Vladimir Radosavljevic Date: Fri, 10 Jun 2016 15:32:33 -0700 Subject: [PATCH] Fix problems emitting MIPS .reginfo section. gold/ * mips.cc (Mips_relobj::Mips_relobj): Initialize has_reginfo_section_. (Mips_relobj::has_reginfo_section_): New data member. (Mips_relobj::has_reginfo_section): New method. (class Mips_output_section_reginfo): Change base class to Output_section_data, and set masks of the output .reginfo section in constructor. (Mips_output_section_reginfo::as_mips_output_section_reginfo): Remove. (Mips_output_section_reginfo::set_masks): Likewise. (Mips_output_section_reginfo::set_final_data_size): Likewise. (Mips_output_section_reginfo::do_print_to_mapfile): New method. (Target_mips::do_make_output_section): Remove. (Mips_relobj::do_read_symbols): Set has_reginfo_section_ to true if the object contains a .reginfo section. (Target_mips::do_finalize_sections): Create a .reginfo output section if needed. --- gold/ChangeLog | 20 +++++++ gold/mips.cc | 141 +++++++++++++++++++++---------------------------- 2 files changed, 80 insertions(+), 81 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 5171ad0a99b..9552d550126 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,23 @@ +2016-06-10 Vladimir Radosavljevic + + * mips.cc (Mips_relobj::Mips_relobj): Initialize + has_reginfo_section_. + (Mips_relobj::has_reginfo_section_): New data member. + (Mips_relobj::has_reginfo_section): New method. + (class Mips_output_section_reginfo): Change base class to + Output_section_data, and set masks of the output .reginfo section + in constructor. + (Mips_output_section_reginfo::as_mips_output_section_reginfo): + Remove. + (Mips_output_section_reginfo::set_masks): Likewise. + (Mips_output_section_reginfo::set_final_data_size): Likewise. + (Mips_output_section_reginfo::do_print_to_mapfile): New method. + (Target_mips::do_make_output_section): Remove. + (Mips_relobj::do_read_symbols): Set has_reginfo_section_ to true + if the object contains a .reginfo section. + (Target_mips::do_finalize_sections): Create a .reginfo output + section if needed. + 2016-06-09 Artemiy Volkov * mips.cc (Mips_output_data_got::do_write): Add missing template diff --git a/gold/mips.cc b/gold/mips.cc index e8a639b9828..59ce88e3098 100644 --- a/gold/mips.cc +++ b/gold/mips.cc @@ -1544,10 +1544,11 @@ class Mips_relobj : public Sized_relobj_file processor_specific_flags_(0), local_symbol_is_mips16_(), local_symbol_is_micromips_(), mips16_stub_sections_(), local_non_16bit_calls_(), local_16bit_calls_(), local_mips16_fn_stubs_(), - local_mips16_call_stubs_(), gp_(0), got_info_(NULL), - section_is_mips16_fn_stub_(), section_is_mips16_call_stub_(), - section_is_mips16_call_fp_stub_(), pdr_shndx_(-1U), gprmask_(0), - cprmask1_(0), cprmask2_(0), cprmask3_(0), cprmask4_(0) + local_mips16_call_stubs_(), gp_(0), has_reginfo_section_(false), + got_info_(NULL), section_is_mips16_fn_stub_(), + section_is_mips16_call_stub_(), section_is_mips16_call_fp_stub_(), + pdr_shndx_(-1U), gprmask_(0), cprmask1_(0), cprmask2_(0), cprmask3_(0), + cprmask4_(0) { this->is_pic_ = (ehdr.get_e_flags() & elfcpp::EF_MIPS_PIC) != 0; this->is_n32_ = elfcpp::abi_n32(ehdr.get_e_flags()); @@ -1783,6 +1784,11 @@ class Mips_relobj : public Sized_relobj_file void discard_mips16_stub_sections(Symbol_table* symtab); + // Return whether there is a .reginfo section. + bool + has_reginfo_section() const + { return this->has_reginfo_section_; } + // Return gprmask from the .reginfo section of this object. Valtype gprmask() const @@ -1861,6 +1867,8 @@ class Mips_relobj : public Sized_relobj_file bool is_pic_ : 1; // Whether the object uses N32 ABI. bool is_n32_ : 1; + // Whether the object contains a .reginfo section. + bool has_reginfo_section_ : 1; // The Mips_got_info for this object. Mips_got_info* got_info_; @@ -2713,40 +2721,25 @@ class Mips_output_data_mips_stubs : public Output_section_data // This class handles Mips .reginfo output section. template -class Mips_output_section_reginfo : public Output_section +class Mips_output_section_reginfo : public Output_section_data { typedef typename elfcpp::Swap::Valtype Valtype; public: - Mips_output_section_reginfo(const char* name, elfcpp::Elf_Word type, - elfcpp::Elf_Xword flags, - Target_mips* target) - : Output_section(name, type, flags), target_(target), gprmask_(0), - cprmask1_(0), cprmask2_(0), cprmask3_(0), cprmask4_(0) + Mips_output_section_reginfo(Target_mips* target, + Valtype gprmask, Valtype cprmask1, + Valtype cprmask2, Valtype cprmask3, + Valtype cprmask4) + : Output_section_data(24, 4, true), target_(target), + gprmask_(gprmask), cprmask1_(cprmask1), cprmask2_(cprmask2), + cprmask3_(cprmask3), cprmask4_(cprmask4) { } - // Downcast a base pointer to a Mips_output_section_reginfo pointer. - static Mips_output_section_reginfo* - as_mips_output_section_reginfo(Output_section* os) - { return static_cast*>(os); } - - // Set masks of the output .reginfo section. - void - set_masks(Valtype gprmask, Valtype cprmask1, Valtype cprmask2, - Valtype cprmask3, Valtype cprmask4) - { - this->gprmask_ = gprmask; - this->cprmask1_ = cprmask1; - this->cprmask2_ = cprmask2; - this->cprmask3_ = cprmask3; - this->cprmask4_ = cprmask4; - } - protected: - // Set the final data size. + // Write to a map file. void - set_final_data_size() - { this->set_data_size(24); } + do_print_to_mapfile(Mapfile* mapfile) const + { mapfile->print_output_data(this, _(".reginfo")); } // Write out reginfo section. void @@ -3545,18 +3538,6 @@ class Target_mips : public Sized_target const elfcpp::Ehdr&) { gold_unreachable(); } - // Make an output section. - Output_section* - do_make_output_section(const char* name, elfcpp::Elf_Word type, - elfcpp::Elf_Xword flags) - { - if (type == elfcpp::SHT_MIPS_REGINFO) - return new Mips_output_section_reginfo(name, type, - flags, this); - else - return new Output_section(name, type, flags); - } - // Adjust ELF file header. void do_adjust_elf_header(unsigned char* view, int len); @@ -6400,6 +6381,7 @@ Mips_relobj::do_read_symbols(Read_symbols_data* sd) if (shdr.get_sh_type() == elfcpp::SHT_MIPS_REGINFO) { + this->has_reginfo_section_ = true; // Read the gp value that was used to create this object. We need the // gp value while processing relocs. The .reginfo section is not used // in the 64-bit MIPS ELF ABI. @@ -8609,6 +8591,13 @@ Target_mips::do_finalize_sections(Layout* layout, } } + Valtype gprmask = 0; + Valtype cprmask1 = 0; + Valtype cprmask2 = 0; + Valtype cprmask3 = 0; + Valtype cprmask4 = 0; + bool has_reginfo_section = false; + // Merge processor-specific flags. for (Input_objects::Relobj_iterator p = input_objects->relobj_begin(); p != input_objects->relobj_end(); @@ -8617,6 +8606,17 @@ Target_mips::do_finalize_sections(Layout* layout, Mips_relobj* relobj = Mips_relobj::as_mips_relobj(*p); + // Merge .reginfo contents of input objects. + if (relobj->has_reginfo_section()) + { + has_reginfo_section = true; + gprmask |= relobj->gprmask(); + cprmask1 |= relobj->cprmask1(); + cprmask2 |= relobj->cprmask2(); + cprmask3 |= relobj->cprmask3(); + cprmask4 |= relobj->cprmask4(); + } + Input_file::Format format = relobj->input_file()->format(); if (format == Input_file::FORMAT_ELF) { @@ -8663,24 +8663,26 @@ Target_mips::do_finalize_sections(Layout* layout, this->merge_processor_specific_flags(dynobj->name(), in_flags, true); } - // Merge .reginfo contents of input objects. - Valtype gprmask = 0; - Valtype cprmask1 = 0; - Valtype cprmask2 = 0; - Valtype cprmask3 = 0; - Valtype cprmask4 = 0; - for (Input_objects::Relobj_iterator p = input_objects->relobj_begin(); - p != input_objects->relobj_end(); - ++p) + if (has_reginfo_section && !parameters->options().gc_sections()) { - Mips_relobj* relobj = - Mips_relobj::as_mips_relobj(*p); + // Create .reginfo output section. + Mips_output_section_reginfo* reginfo_section = + new Mips_output_section_reginfo(this, gprmask, + cprmask1, cprmask2, + cprmask3, cprmask4); - gprmask |= relobj->gprmask(); - cprmask1 |= relobj->cprmask1(); - cprmask2 |= relobj->cprmask2(); - cprmask3 |= relobj->cprmask3(); - cprmask4 |= relobj->cprmask4(); + Output_section* os = + layout->add_output_section_data(".reginfo", elfcpp::SHT_MIPS_REGINFO, + elfcpp::SHF_ALLOC, reginfo_section, + ORDER_INVALID, false); + + if (!parameters->options().relocatable() && os != NULL) + { + Output_segment* reginfo_segment = + layout->make_output_segment(elfcpp::PT_MIPS_REGINFO, + elfcpp::PF_R); + reginfo_segment->add_output_section_to_nonload(os, elfcpp::PF_R); + } } if (this->plt_ != NULL) @@ -8751,29 +8753,6 @@ Target_mips::do_finalize_sections(Layout* layout, if (!parameters->options().relocatable()) layout->make_output_segment(elfcpp::PT_NULL, 0); - for (Layout::Section_list::const_iterator p = layout->section_list().begin(); - p != layout->section_list().end(); - ++p) - { - if ((*p)->type() == elfcpp::SHT_MIPS_REGINFO) - { - Mips_output_section_reginfo* reginfo = - Mips_output_section_reginfo:: - as_mips_output_section_reginfo(*p); - - reginfo->set_masks(gprmask, cprmask1, cprmask2, cprmask3, cprmask4); - - if (!parameters->options().relocatable()) - { - Output_segment* reginfo_segment = - layout->make_output_segment(elfcpp::PT_MIPS_REGINFO, - elfcpp::PF_R); - reginfo_segment->add_output_section_to_nonload(reginfo, - elfcpp::PF_R); - } - } - } - // Fill in some more dynamic tags. // TODO(sasa): Add more dynamic tags. const Reloc_section* rel_plt = (this->plt_ == NULL