diff options
-rw-r--r-- | gold/ChangeLog | 14 | ||||
-rw-r--r-- | gold/merge.cc | 29 | ||||
-rw-r--r-- | gold/merge.h | 33 | ||||
-rw-r--r-- | gold/object.cc | 17 | ||||
-rw-r--r-- | gold/object.h | 3 |
5 files changed, 67 insertions, 29 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index f970e66..39e025e 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,17 @@ +2015-03-27 Rafael Ávila de Espíndola <rafael.espindola@gmail.com> + + * merge.cc (Object_merge_map::add_mapping): call + Object_merge_map::Input_merge_map::add_mapping. + (Object_merge_map::Input_merge_map::add_mapping): New. + (Output_merge_data::do_add_input_section): Call + get_or_make_input_merge_map before a loop. + (Output_merge_string<Char_type>::finalize_merged_data): Call + get_or_make_input_merge_map before a loop. + * merge.h (Object_merge_map): Make Input_merge_map public. + * object.cc (Relobj::add_merge_mapping): Use get_or_create_merge_map. + (Relobj::get_or_create_merge_map): New. + * object.h (Relobj::get_or_create_merge_map): New. + 2015-03-24 Alan Modra <amodra@gmail.com> PR 18147 diff --git a/gold/merge.cc b/gold/merge.cc index a579445..d395312 100644 --- a/gold/merge.cc +++ b/gold/merge.cc @@ -103,11 +103,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 +126,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<section_size_type>(entry.input_offset)); - map->sorted = false; + this->sorted = false; } else if (entry.input_offset + entry.length == input_offset_u && (output_offset == -1 @@ -136,7 +142,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. @@ -357,6 +363,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 @@ -375,7 +385,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. @@ -557,6 +567,11 @@ Output_merge_string<Char_type>::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(); @@ -564,8 +579,8 @@ Output_merge_string<Char_type>::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 = diff --git a/gold/merge.h b/gold/merge.h index 62efa13..54caed8 100644 --- a/gold/merge.h +++ b/gold/merge.h @@ -85,7 +85,6 @@ class Object_merge_map Unordered_map<section_offset_type, typename elfcpp::Elf_types<size>::Elf_Addr>*); - private: // Map input section offsets to a length and an output section // offset. An output section offset of -1 means that this part of // the input section is being discarded. @@ -99,17 +98,12 @@ class Object_merge_map section_offset_type output_offset; }; - // A less-than comparison routine for Input_merge_entry. - struct Input_merge_compare - { - bool - operator()(const Input_merge_entry& i1, const Input_merge_entry& i2) const - { return i1.input_offset < i2.input_offset; } - }; - // A list of entries for a particular input section. struct Input_merge_map { + void add_mapping(section_offset_type input_offset, section_size_type length, + section_offset_type output_offset); + typedef std::vector<Input_merge_entry> Entries; // We store these with the Relobj, and we look them up by input @@ -142,6 +136,21 @@ class Object_merge_map { } }; + // Get or make the Input_merge_map to use for the section SHNDX + // with MERGE_MAP. + Input_merge_map* + get_or_make_input_merge_map(const Output_section_data* merge_map, + unsigned int shndx); + + private: + // A less-than comparison routine for Input_merge_entry. + struct Input_merge_compare + { + bool + operator()(const Input_merge_entry& i1, const Input_merge_entry& i2) const + { return i1.input_offset < i2.input_offset; } + }; + // Map input section indices to merge maps. typedef std::map<unsigned int, Input_merge_map*> Section_merge_maps; @@ -156,12 +165,6 @@ class Object_merge_map this)->get_input_merge_map(shndx)); } - // Get or make the Input_merge_map to use for the section SHNDX - // with MERGE_MAP. - Input_merge_map* - get_or_make_input_merge_map(const Output_section_data* merge_map, - unsigned int shndx); - // Any given object file will normally only have a couple of input // sections with mergeable contents. So we keep the first two input // section numbers inline, and push any further ones into a map. A diff --git a/gold/object.cc b/gold/object.cc index cbe73ca..f28305b 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -285,13 +285,8 @@ Relobj::add_merge_mapping(Output_section_data *output_data, unsigned int shndx, section_offset_type offset, section_size_type length, section_offset_type output_offset) { - if (this->object_merge_map_ == NULL) - { - this->object_merge_map_ = new Object_merge_map(); - } - - this->object_merge_map_->add_mapping(output_data, shndx, offset, length, - output_offset); + Object_merge_map* object_merge_map = this->get_or_create_merge_map(); + object_merge_map->add_mapping(output_data, shndx, offset, length, output_offset); } bool @@ -411,6 +406,14 @@ Relobj::finalize_incremental_relocs(Layout* layout, bool clear_counts) layout->incremental_inputs()->set_reloc_count(rindex); } +Object_merge_map* +Relobj::get_or_create_merge_map() +{ + if (!this->object_merge_map_) + this->object_merge_map_ = new Object_merge_map(); + return this->object_merge_map_; +} + // Class Sized_relobj. // Iterate over local symbols, calling a visitor class V for each GOT offset diff --git a/gold/object.h b/gold/object.h index c26acf3..fc93abd 100644 --- a/gold/object.h +++ b/gold/object.h @@ -1215,6 +1215,9 @@ class Relobj : public Object relocs_must_follow_section_writes() const { return this->relocs_must_follow_section_writes_; } + Object_merge_map* + get_or_create_merge_map(); + template<int size> void initialize_input_to_output_map(unsigned int shndx, |