X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fmerge.cc;h=ba23cf5dbf513a1e8fc19eb750554b4249b64600;hb=a38d71189b5895bae7bb476aa34d8a7ba75376d6;hp=5d93c74ce4b0bd310650fdb0965b9ffb25b190af;hpb=dbe40a889191708b6e32441b1c64937844645574;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/merge.cc b/gold/merge.cc index 5d93c74ce4..ba23cf5dbf 100644 --- a/gold/merge.cc +++ b/gold/merge.cc @@ -1,6 +1,6 @@ // merge.cc -- handle section merging for gold -// Copyright (C) 2006-2015 Free Software Foundation, Inc. +// Copyright (C) 2006-2019 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -45,17 +45,17 @@ Object_merge_map::~Object_merge_map() // Get the Input_merge_map to use for an input section, or NULL. -Object_merge_map::Input_merge_map* -Object_merge_map::get_input_merge_map(unsigned int shndx) +const Object_merge_map::Input_merge_map* +Object_merge_map::get_input_merge_map(unsigned int shndx) const { gold_assert(shndx != -1U); - if (shndx == this->first_shnum_) - return &this->first_map_; - if (shndx == this->second_shnum_) - return &this->second_map_; - Section_merge_maps::const_iterator p = this->section_merge_maps_.find(shndx); - if (p != this->section_merge_maps_.end()) - return p->second; + const Section_merge_maps &maps = this->section_merge_maps_; + for (Section_merge_maps::const_iterator i = maps.begin(), e = maps.end(); + i != e; ++i) + { + if (i->first == shndx) + return i->second; + } return NULL; } @@ -73,23 +73,10 @@ Object_merge_map::get_or_make_input_merge_map( return map; } - // We need to create a new entry. - if (this->first_shnum_ == -1U) - { - this->first_shnum_ = shndx; - this->first_map_.output_data = output_data; - return &this->first_map_; - } - if (this->second_shnum_ == -1U) - { - this->second_shnum_ = shndx; - this->second_map_.output_data = output_data; - return &this->second_map_; - } - Input_merge_map* new_map = new Input_merge_map; new_map->output_data = output_data; - this->section_merge_maps_[shndx] = new_map; + Section_merge_maps &maps = this->section_merge_maps_; + maps.push_back(std::make_pair(shndx, new_map)); return new_map; } @@ -103,11 +90,17 @@ Object_merge_map::add_mapping(const Output_section_data* output_data, section_offset_type output_offset) { Input_merge_map* map = this->get_or_make_input_merge_map(output_data, shndx); + map->add_mapping(input_offset, length, output_offset); +} +void +Object_merge_map::Input_merge_map::add_mapping( + section_offset_type input_offset, section_size_type length, + section_offset_type output_offset) { // Try to merge the new entry in the last one we saw. - if (!map->entries.empty()) + if (!this->entries.empty()) { - Input_merge_entry& entry(map->entries.back()); + Input_merge_entry& entry(this->entries.back()); // Use section_size_type to avoid signed/unsigned warnings. section_size_type input_offset_u = input_offset; @@ -120,7 +113,7 @@ Object_merge_map::add_mapping(const Output_section_data* output_data, gold_assert(input_offset < entry.input_offset); gold_assert(input_offset_u + length <= static_cast(entry.input_offset)); - map->sorted = false; + this->sorted = false; } else if (entry.input_offset + entry.length == input_offset_u && (output_offset == -1 @@ -136,7 +129,7 @@ Object_merge_map::add_mapping(const Output_section_data* output_data, entry.input_offset = input_offset; entry.length = length; entry.output_offset = output_offset; - map->entries.push_back(entry); + this->entries.push_back(entry); } // Get the output offset for an input address. @@ -179,12 +172,13 @@ Object_merge_map::get_output_offset(unsigned int shndx, // Return whether this is the merge map for section SHNDX. -bool -Object_merge_map::is_merge_section_for(const Output_section_data* output_data, - unsigned int shndx) -{ - Input_merge_map* map = this->get_input_merge_map(shndx); - return map != NULL && map->output_data == output_data; +const Output_section_data* +Object_merge_map::find_merge_section(unsigned int shndx) const { + const Object_merge_map::Input_merge_map* map = + this->get_input_merge_map(shndx); + if (map == NULL) + return NULL; + return map->output_data; } // Initialize a mapping from input offsets to output addresses. @@ -356,6 +350,10 @@ Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx) this->input_count_ += len / entsize; + Object_merge_map* merge_map = object->get_or_create_merge_map(); + Object_merge_map::Input_merge_map* input_merge_map = + merge_map->get_or_make_input_merge_map(this, shndx); + for (section_size_type i = 0; i < len; i += entsize, p += entsize) { // Add the constant to the section contents. If we find that it @@ -374,7 +372,7 @@ Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx) } // Record the offset of this constant in the output section. - object->add_merge_mapping(this, shndx, i, entsize, k); + input_merge_map->add_mapping(i, entsize, k); } // For script processing, we keep the input sections. @@ -442,9 +440,11 @@ Output_merge_string::do_add_input_section(Relobj* object, { section_size_type sec_len; bool is_new; + uint64_t addralign = this->addralign(); const unsigned char* pdata = object->decompressed_section_contents(shndx, &sec_len, - &is_new); + &is_new, + &addralign); const Char_type* p = reinterpret_cast(pdata); const Char_type* pend = p + sec_len / sizeof(Char_type); @@ -496,7 +496,7 @@ Output_merge_string::do_add_input_section(Relobj* object, // aligned, so each string within the section must retain the same // modulo. uintptr_t init_align_modulo = (reinterpret_cast(pdata) - & (this->addralign() - 1)); + & (addralign - 1)); bool has_misaligned_strings = false; while (p < pend) @@ -505,7 +505,7 @@ Output_merge_string::do_add_input_section(Relobj* object, // Within merge input section each string must be aligned. if (len != 0 - && ((reinterpret_cast(p) & (this->addralign() - 1)) + && ((reinterpret_cast(p) & (addralign - 1)) != init_align_modulo)) has_misaligned_strings = true; @@ -556,6 +556,11 @@ Output_merge_string::finalize_merged_data() { section_offset_type last_input_offset = 0; section_offset_type last_output_offset = 0; + Relobj *object = (*l)->object; + Object_merge_map* merge_map = object->get_or_create_merge_map(); + Object_merge_map::Input_merge_map* input_merge_map = + merge_map->get_or_make_input_merge_map(this, (*l)->shndx); + for (typename Merged_strings::const_iterator p = (*l)->merged_strings.begin(); p != (*l)->merged_strings.end(); @@ -563,8 +568,8 @@ Output_merge_string::finalize_merged_data() { section_size_type length = p->offset - last_input_offset; if (length > 0) - (*l)->object->add_merge_mapping(this, (*l)->shndx, - last_input_offset, length, last_output_offset); + input_merge_map->add_mapping(last_input_offset, length, + last_output_offset); last_input_offset = p->offset; if (p->stringpool_key != 0) last_output_offset =