X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gold%2Fmips.cc;h=65572d8884f6d5ef0bbcd696d15211475f15478f;hb=refs%2Fheads%2Fsandbox%2Fakazmin%2Fgnu_prop_segment;hp=426817600ebb357f779f5c6d47bf305a4f1d8cf2;hpb=152c92b261fd9e4655688bef746ca32352f56bc4;p=external%2Fbinutils.git diff --git a/gold/mips.cc b/gold/mips.cc index 4268176..65572d8 100644 --- a/gold/mips.cc +++ b/gold/mips.cc @@ -1,6 +1,6 @@ // mips.cc -- mips target support for gold. -// Copyright (C) 2011-2017 Free Software Foundation, Inc. +// Copyright (C) 2011-2019 Free Software Foundation, Inc. // Written by Sasa Stankovic // and Aleksandar Simeonov . // This file contains borrowed and adapted code from bfd/elfxx-mips.c. @@ -474,22 +474,24 @@ class Mips_got_entry ? this->d.object->name().c_str() : this->d.sym->name()); size_t addend = this->addend_; - return name_hash_value ^ this->symndx_ ^ addend; + return name_hash_value ^ this->symndx_ ^ (addend << 16); } // Return whether this entry is equal to OTHER. bool equals(Mips_got_entry* other) const { + if (this->symndx_ != other->symndx_ + || this->tls_type_ != other->tls_type_) + return false; + if (this->tls_type_ == GOT_TLS_LDM) return true; - return ((this->tls_type_ == other->tls_type_) - && (this->symndx_ == other->symndx_) - && ((this->symndx_ != -1U) - ? (this->d.object == other->d.object) - : (this->d.sym == other->d.sym)) - && (this->addend_ == other->addend_)); + return (((this->symndx_ != -1U) + ? (this->d.object == other->d.object) + : (this->d.sym == other->d.sym)) + && (this->addend_ == other->addend_)); } // Return input object that needs this GOT entry. @@ -629,11 +631,11 @@ struct Got_page_range struct Got_page_entry { Got_page_entry() - : object(NULL), symndx(-1U), ranges(NULL), num_pages(0) + : object(NULL), symndx(-1U), ranges(NULL) { } Got_page_entry(Object* object_, unsigned int symndx_) - : object(object_), symndx(symndx_), ranges(NULL), num_pages(0) + : object(object_), symndx(symndx_), ranges(NULL) { } // The input object that needs the GOT page entry. @@ -642,8 +644,6 @@ struct Got_page_entry unsigned int symndx; // The ranges for this page entry. Got_page_range* ranges; - // The maximum number of page entries needed for RANGES. - unsigned int num_pages; }; // Hash for Got_page_entry. @@ -773,7 +773,7 @@ class Mips_got_info // Add FROM's GOT page entries. void - add_got_page_entries(Mips_got_info* from); + add_got_page_count(Mips_got_info* from); // Return GOT size. unsigned int @@ -926,7 +926,7 @@ class Mips_got_info Global_got_entry_set global_got_symbols_; // A hash table holding GOT entries. Got_entry_set got_entries_; - // A hash table of GOT page entries. + // A hash table of GOT page entries (only used in master GOT). Got_page_entry_set got_page_entries_; // The offset of first GOT page entry for this GOT. unsigned int got_page_offset_start_; @@ -1592,10 +1592,11 @@ class Mips_relobj : public Sized_relobj_file local_symbol_is_micromips_(), mips16_stub_sections_(), local_non_16bit_calls_(), local_16bit_calls_(), local_mips16_fn_stubs_(), 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), attributes_section_data_(NULL), abiflags_(NULL), - gprmask_(0), cprmask1_(0), cprmask2_(0), cprmask3_(0), cprmask4_(0) + merge_processor_specific_data_(true), got_info_(NULL), + section_is_mips16_fn_stub_(), section_is_mips16_call_stub_(), + section_is_mips16_call_fp_stub_(), pdr_shndx_(-1U), + attributes_section_data_(NULL), abiflags_(NULL), 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()); @@ -1836,6 +1837,11 @@ class Mips_relobj : public Sized_relobj_file has_reginfo_section() const { return this->has_reginfo_section_; } + // Return whether we want to merge processor-specific data. + bool + merge_processor_specific_data() const + { return this->merge_processor_specific_data_; } + // Return gprmask from the .reginfo section of this object. Valtype gprmask() const @@ -1926,6 +1932,8 @@ class Mips_relobj : public Sized_relobj_file bool is_n32_ : 1; // Whether the object contains a .reginfo section. bool has_reginfo_section_ : 1; + // Whether we merge processor-specific data of this object to output. + bool merge_processor_specific_data_ : 1; // The Mips_got_info for this object. Mips_got_info* got_info_; @@ -3974,7 +3982,9 @@ class Target_mips : public Sized_target mach_mips5 = 5, mach_mips_loongson_2e = 3001, mach_mips_loongson_2f = 3002, - mach_mips_loongson_3a = 3003, + mach_mips_gs464 = 3003, + mach_mips_gs464e = 3004, + mach_mips_gs264e = 3005, mach_mips_sb1 = 12310201, // octal 'SB', 01 mach_mips_octeon = 6501, mach_mips_octeonp = 6601, @@ -4140,7 +4150,9 @@ class Target_mips : public Sized_target this->add_extension(mach_mips_octeon2, mach_mips_octeonp); this->add_extension(mach_mips_octeonp, mach_mips_octeon); this->add_extension(mach_mips_octeon, mach_mipsisa64r2); - this->add_extension(mach_mips_loongson_3a, mach_mipsisa64r2); + this->add_extension(mach_mips_gs264e, mach_mips_gs464e); + this->add_extension(mach_mips_gs464e, mach_mips_gs464); + this->add_extension(mach_mips_gs464, mach_mipsisa64r2); // MIPS64 extensions. this->add_extension(mach_mipsisa64r2, mach_mipsisa64); @@ -5654,7 +5666,7 @@ class Mips_relocate_functions : public Relocate_functions : addend_a); Valtype x = psymval->value(object, addend); - x = ((x + (uint64_t) 0x800080008000) >> 48) & 0xffff; + x = ((x + (uint64_t) 0x800080008000llu) >> 48) & 0xffff; val = Bits<32>::bit_select32(val, x, 0xffff); if (calculate_only) @@ -5784,14 +5796,8 @@ Mips_got_info::record_got_page_entry( else this->got_page_entries_.insert(entry); - // Add the same entry to the OBJECT's GOT. - Got_page_entry* entry2 = NULL; + // Get the object's GOT, but we don't need to insert an entry here. Mips_got_info* g2 = object->get_or_create_got_info(); - if (g2->got_page_entries_.find(entry) == g2->got_page_entries_.end()) - { - entry2 = new Got_page_entry(*entry); - g2->got_page_entries_.insert(entry2); - } // Skip over ranges whose maximum extent cannot share a page entry // with ADDEND. @@ -5811,9 +5817,6 @@ Mips_got_info::record_got_page_entry( range->max_addend = addend; *range_ptr = range; - ++entry->num_pages; - if (entry2 != NULL) - ++entry2->num_pages; ++this->page_gotno_; ++g2->page_gotno_; return; @@ -5841,9 +5844,6 @@ Mips_got_info::record_got_page_entry( new_pages = range->get_max_pages(); if (old_pages != new_pages) { - entry->num_pages += new_pages - old_pages; - if (entry2 != NULL) - entry2->num_pages += new_pages - old_pages; this->page_gotno_ += new_pages - old_pages; g2->page_gotno_ += new_pages - old_pages; } @@ -6343,22 +6343,10 @@ Mips_got_info::add_got_entries( template void -Mips_got_info::add_got_page_entries( +Mips_got_info::add_got_page_count( Mips_got_info* from) { - for (typename Got_page_entry_set::iterator - p = from->got_page_entries_.begin(); - p != from->got_page_entries_.end(); - ++p) - { - Got_page_entry* entry = *p; - if (this->got_page_entries_.find(entry) == this->got_page_entries_.end()) - { - Got_page_entry* entry2 = new Got_page_entry(*entry); - this->got_page_entries_.insert(entry2); - this->page_gotno_ += entry->num_pages; - } - } + this->page_gotno_ += from->page_gotno_; } // Mips_output_data_got methods. @@ -6559,7 +6547,7 @@ Mips_output_data_got::merge_got_with( // Transfer the object's GOT information from FROM to TO. to->add_got_entries(from); - to->add_got_page_entries(from); + to->add_got_page_count(from); // Record that OBJECT should use output GOT TO. object->set_got_info(to); @@ -6818,6 +6806,16 @@ Mips_relobj::do_read_symbols(Read_symbols_data* sd) // Call parent class to read symbol information. this->base_read_symbols(sd); + // If this input file is a binary file, it has no processor + // specific data. + Input_file::Format format = this->input_file()->format(); + if (format != Input_file::FORMAT_ELF) + { + gold_assert(format == Input_file::FORMAT_BINARY); + this->merge_processor_specific_data_ = false; + return; + } + // Read processor-specific flags in ELF file header. const unsigned char* pehdr = this->get_view(elfcpp::file_header_offset, elfcpp::Elf_sizes::ehdr_size, @@ -6837,10 +6835,27 @@ Mips_relobj::do_read_symbols(Read_symbols_data* sd) const size_t shdr_size = elfcpp::Elf_sizes::shdr_size; const unsigned char* pshdrs = sd->section_headers->data(); const unsigned char* ps = pshdrs + shdr_size; + bool must_merge_processor_specific_data = false; for (unsigned int i = 1; i < this->shnum(); ++i, ps += shdr_size) { elfcpp::Shdr shdr(ps); + // Sometimes an object has no contents except the section name string + // table and an empty symbol table with the undefined symbol. We + // don't want to merge processor-specific data from such an object. + if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB) + { + // Symbol table is not empty. + const typename elfcpp::Elf_types::Elf_WXword sym_size = + elfcpp::Elf_sizes::sym_size; + if (shdr.get_sh_size() > sym_size) + must_merge_processor_specific_data = true; + } + else if (shdr.get_sh_type() != elfcpp::SHT_STRTAB) + // If this is neither an empty symbol table nor a string table, + // be conservative. + must_merge_processor_specific_data = true; + if (shdr.get_sh_type() == elfcpp::SHT_MIPS_REGINFO) { this->has_reginfo_section_ = true; @@ -7013,6 +7028,10 @@ Mips_relobj::do_read_symbols(Read_symbols_data* sd) this->pdr_shndx_ = i; } } + + // This is rare. + if (!must_merge_processor_specific_data) + this->merge_processor_specific_data_ = false; } // Discard MIPS16 stub secions that are not needed. @@ -8843,8 +8862,14 @@ Target_mips::elf_mips_mach(elfcpp::Elf_Word flags) case elfcpp::E_MIPS_MACH_LS2F: return mach_mips_loongson_2f; - case elfcpp::E_MIPS_MACH_LS3A: - return mach_mips_loongson_3a; + case elfcpp::E_MIPS_MACH_GS464: + return mach_mips_gs464; + + case elfcpp::E_MIPS_MACH_GS464E: + return mach_mips_gs464e; + + case elfcpp::E_MIPS_MACH_GS264E: + return mach_mips_gs264e; case elfcpp::E_MIPS_MACH_OCTEON3: return mach_mips_octeon3; @@ -8944,9 +8969,6 @@ Target_mips::mips_isa_ext_mach(unsigned int isa_ext) case elfcpp::AFL_EXT_LOONGSON_2F: return mach_mips_loongson_2f; - case elfcpp::AFL_EXT_LOONGSON_3A: - return mach_mips_loongson_3a; - case elfcpp::AFL_EXT_SB1: return mach_mips_sb1; @@ -9011,9 +9033,6 @@ Target_mips::mips_isa_ext(unsigned int mips_mach) case mach_mips_loongson_2f: return elfcpp::AFL_EXT_LOONGSON_2F; - case mach_mips_loongson_3a: - return elfcpp::AFL_EXT_LOONGSON_3A; - case mach_mips_sb1: return elfcpp::AFL_EXT_SB1; @@ -9145,7 +9164,7 @@ Target_mips::infer_abiflags( && abiflags->fp_abi != elfcpp::Val_GNU_MIPS_ABI_FP_SOFT && abiflags->fp_abi != elfcpp::Val_GNU_MIPS_ABI_FP_64A && abiflags->isa_level >= 32 - && abiflags->isa_ext != elfcpp::AFL_EXT_LOONGSON_3A) + && abiflags->ases != elfcpp::AFL_ASE_LOONGSON_EXT) abiflags->flags1 |= elfcpp::AFL_FLAGS1_ODDSPREG; } @@ -9600,6 +9619,8 @@ Target_mips::do_finalize_sections(Layout* layout, const Input_objects* input_objects, Symbol_table* symtab) { + const bool relocatable = parameters->options().relocatable(); + // Add +1 to MIPS16 and microMIPS init_ and _fini symbols so that DT_INIT and // DT_FINI have correct values. Mips_symbol* init = static_cast*>( @@ -9633,19 +9654,6 @@ Target_mips::do_finalize_sections(Layout* layout, if (this->got16_addends_.size() > 0) gold_error("Can't find matching LO16 reloc"); - // Check for any mips16 stub sections that we can discard. - if (!parameters->options().relocatable()) - { - for (Input_objects::Relobj_iterator p = input_objects->relobj_begin(); - p != input_objects->relobj_end(); - ++p) - { - Mips_relobj* object = - Mips_relobj::as_mips_relobj(*p); - object->discard_mips16_stub_sections(symtab); - } - } - Valtype gprmask = 0; Valtype cprmask1 = 0; Valtype cprmask2 = 0; @@ -9660,6 +9668,13 @@ Target_mips::do_finalize_sections(Layout* layout, Mips_relobj* relobj = Mips_relobj::as_mips_relobj(*p); + // Check for any mips16 stub sections that we can discard. + if (!relocatable) + relobj->discard_mips16_stub_sections(symtab); + + if (!relobj->merge_processor_specific_data()) + continue; + // Merge .reginfo contents of input objects. if (relobj->has_reginfo_section()) { @@ -9671,24 +9686,6 @@ Target_mips::do_finalize_sections(Layout* layout, cprmask4 |= relobj->cprmask4(); } - Input_file::Format format = relobj->input_file()->format(); - if (format != Input_file::FORMAT_ELF) - continue; - - // If all input sections will be discarded, don't use this object - // file for merging processor specific flags. - bool should_merge_processor_specific_flags = false; - - for (unsigned int i = 1; i < relobj->shnum(); ++i) - if (relobj->output_section(i) != NULL) - { - should_merge_processor_specific_flags = true; - break; - } - - if (!should_merge_processor_specific_flags) - continue; - // Merge processor specific flags. Mips_abiflags in_abiflags; @@ -9723,7 +9720,7 @@ Target_mips::do_finalize_sections(Layout* layout, elfcpp::SHF_ALLOC, abiflags_section, ORDER_INVALID, false); - if (!parameters->options().relocatable() && os != NULL) + if (!relocatable && os != NULL) { Output_segment* abiflags_segment = layout->make_output_segment(elfcpp::PT_MIPS_ABIFLAGS, elfcpp::PF_R); @@ -9744,7 +9741,7 @@ Target_mips::do_finalize_sections(Layout* layout, elfcpp::SHF_ALLOC, reginfo_section, ORDER_INVALID, false); - if (!parameters->options().relocatable() && os != NULL) + if (!relocatable && os != NULL) { Output_segment* reginfo_segment = layout->make_output_segment(elfcpp::PT_MIPS_REGINFO, @@ -9789,7 +9786,7 @@ Target_mips::do_finalize_sections(Layout* layout, false, false); } - if (!parameters->options().relocatable() && !parameters->doing_static_link()) + if (!relocatable && !parameters->doing_static_link()) // In case there is no .got section, create one. this->got_section(symtab, layout); @@ -9821,7 +9818,7 @@ Target_mips::do_finalize_sections(Layout* layout, symtab)); // Add NULL segment. - if (!parameters->options().relocatable()) + if (!relocatable) layout->make_output_segment(elfcpp::PT_NULL, 0); // Fill in some more dynamic tags. @@ -9833,7 +9830,7 @@ Target_mips::do_finalize_sections(Layout* layout, Output_data_dynamic* const odyn = layout->dynamic_data(); if (odyn != NULL - && !parameters->options().relocatable() + && !relocatable && !parameters->doing_static_link()) { unsigned int d_val; @@ -12537,8 +12534,12 @@ Target_mips::elf_mips_mach_name(elfcpp::Elf_Word e_flags) return "mips:loongson_2e"; case elfcpp::E_MIPS_MACH_LS2F: return "mips:loongson_2f"; - case elfcpp::E_MIPS_MACH_LS3A: - return "mips:loongson_3a"; + case elfcpp::E_MIPS_MACH_GS464: + return "mips:gs464"; + case elfcpp::E_MIPS_MACH_GS464E: + return "mips:gs464e"; + case elfcpp::E_MIPS_MACH_GS264E: + return "mips:gs264e"; case elfcpp::E_MIPS_MACH_OCTEON: return "mips:octeon"; case elfcpp::E_MIPS_MACH_OCTEON2: @@ -12614,6 +12615,7 @@ const Target::Target_info Target_mips::mips_info = NULL, // attributes_vendor "__start", // entry_symbol_name 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; template @@ -12654,6 +12656,7 @@ const Target::Target_info Target_mips_nacl::mips_nacl_info = NULL, // attributes_vendor "_start", // entry_symbol_name 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; // Target selector for Mips. Note this is never instantiated directly.