+2015-03-23 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+
+ * merge.cc (Object_merge_map::get_input_merge_map): Make it const.
+ (Object_merge_map::is_merge_section_for): Remove.
+ (Object_merge_map::find_merge_section): New.
+ * merge.h (Object_merge_map::is_merge_section_for): Remove.
+ (Object_merge_map::find_merge_section): New.
+ (Object_merge_map::get_input_merge_map): Add a const version.
+ * object.cc (Relobj::is_merge_section_for): Remove.
+ (Relobj::find_merge_section): New.
+ * object.h (Relobj::is_merge_section_for): Remove.
+ (Relobj::find_merge_section): New.
+ * output.cc
+ (Output_section::Input_section::is_merge_section_for): Remove.
+ (Output_section::add_merge_input_section): Don't call
+ add_merge_input_section.
+ (Output_section::find_merge_section): Return const. Use
+ object->find_merge_section.
+ (Output_section::build_lookup_maps): Don't build a map for
+ merge sections.
+ (Output_section::is_input_address_mapped): Return false if
+ section is not found.
+ (Output_section::find_starting_output_address): Use
+ find_merge_section instead of is_merge_section_for.
+ (Output_section::add_script_input_section): Don't build a map for
+ merge sections.
+ * output.h (Output_section_lookup_maps::merge_sections_by_id_): Remove.
+ (Output_section_lookup_maps::find_merge_section): Remove.
+ (Output_section_lookup_maps::add_merge_input_section) Remove.
+ (Output_section::find_merge_section): Return const.
+
2015-03-22 Cary Coutant <cary@google.com>
PR gold/18106
// 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 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.
section_offset_type offset,
section_offset_type* output_offset);
- // Return whether this is the merge map for section SHNDX.
- bool
- is_merge_section_for(const Output_section_data*, unsigned int shndx);
+ const Output_section_data*
+ find_merge_section(unsigned int shndx) const;
// Initialize an mapping from input offsets to output addresses for
// section SHNDX. STARTING_ADDRESS is the output address of the
// Return a pointer to the Input_merge_map to use for the input
// section SHNDX, or NULL.
- Input_merge_map*
- get_input_merge_map(unsigned int shndx);
+ const Input_merge_map*
+ get_input_merge_map(unsigned int shndx) const;
+
+ Input_merge_map *
+ get_input_merge_map(unsigned int shndx) {
+ return const_cast<Input_merge_map *>(static_cast<const 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.
return object_merge_map->get_output_offset(shndx, offset, poutput);
}
-bool
-Relobj::is_merge_section_for(const Output_section_data* output_data,
- unsigned int shndx) const {
+const Output_section_data*
+Relobj::find_merge_section(unsigned int shndx) const {
Object_merge_map* object_merge_map = this->object_merge_map_;
if (object_merge_map == NULL)
- return false;
- return object_merge_map->is_merge_section_for(output_data, shndx);
-
+ return NULL;
+ return object_merge_map->find_merge_section(shndx);
}
// To copy the symbols data read from the file to a local data structure.
merge_output_offset(unsigned int shndx, section_offset_type offset,
section_offset_type *poutput) const;
- bool
- is_merge_section_for(const Output_section_data* output_data,
- unsigned int shndx) const;
+ const Output_section_data*
+ find_merge_section(unsigned int shndx) const;
// Record the relocatable reloc info for an input reloc section.
void
}
}
-// Return whether this is the merge section for the input section
-// SHNDX in OBJECT.
-
-inline bool
-Output_section::Input_section::is_merge_section_for(const Relobj* object,
- unsigned int shndx) const
-{
- if (this->is_input_section())
- return false;
- return object->is_merge_section_for(this->u2_.posd, shndx);
-}
-
// Write out the data. We don't have to do anything for an input
// section--they are handled via Object::relocate--but this is where
// we write out the data for an Output_section_data.
this->lookup_maps_->add_merge_section(msp, pomb);
}
- // Add input section to new merge section and link input section to new
- // merge section in map.
- this->lookup_maps_->add_merge_input_section(object, shndx, pomb);
return true;
}
else
// Find the merge section into which an input section with index SHNDX in
// OBJECT has been added. Return NULL if none found.
-Output_section_data*
+const Output_section_data*
Output_section::find_merge_section(const Relobj* object,
unsigned int shndx) const
{
- if (!this->lookup_maps_->is_valid())
- this->build_lookup_maps();
- return this->lookup_maps_->find_merge_section(object, shndx);
+ return object->find_merge_section(shndx);
}
-// Build the lookup maps for merge and relaxed sections. This is needs
-// to be declared as a const methods so that it is callable with a const
+// Build the lookup maps for relaxed sections. This needs
+// to be declared as a const method so that it is callable with a const
// Output_section pointer. The method only updates states of the maps.
void
p != this->input_sections_.end();
++p)
{
- if (p->is_merge_section())
- {
- Output_merge_base* pomb = p->output_merge_base();
- Merge_section_properties msp(pomb->is_string(), pomb->entsize(),
- pomb->addralign());
- this->lookup_maps_->add_merge_section(msp, pomb);
- for (Output_merge_base::Input_sections::const_iterator is =
- pomb->input_sections_begin();
- is != pomb->input_sections_end();
- ++is)
- {
- const Const_section_id& csid = *is;
- this->lookup_maps_->add_merge_input_section(csid.first,
- csid.second, pomb);
- }
-
- }
- else if (p->is_relaxed_input_section())
+ if (p->is_relaxed_input_section())
{
Output_relaxed_input_section* poris = p->relaxed_input_section();
this->lookup_maps_->add_relaxed_input_section(poris->relobj(),
{
section_offset_type output_offset;
bool found = posd->output_offset(object, shndx, offset, &output_offset);
- gold_assert(found);
+ if (!found)
+ return false;
return output_offset != -1;
}
unsigned int shndx,
uint64_t* paddr) const
{
+ const Output_section_data* data = this->find_merge_section(object, shndx);
+ if (data == NULL)
+ return false;
+
// FIXME: This becomes a bottle-neck if we have many relaxed sections.
// Looking up the merge section map does not always work as we sometimes
// find a merge section without its address set.
// method to get the output offset of input offset 0.
// Unfortunately we don't know for sure that input offset 0 is
// mapped at all.
- if (p->is_merge_section_for(object, shndx))
+ if (!p->is_input_section() && p->output_section_data() == data)
{
*paddr = addr;
return true;
// Update fast lookup maps if necessary.
if (this->lookup_maps_->is_valid())
{
- if (sis.is_merge_section())
- {
- Output_merge_base* pomb = sis.output_merge_base();
- Merge_section_properties msp(pomb->is_string(), pomb->entsize(),
- pomb->addralign());
- this->lookup_maps_->add_merge_section(msp, pomb);
- for (Output_merge_base::Input_sections::const_iterator p =
- pomb->input_sections_begin();
- p != pomb->input_sections_end();
- ++p)
- this->lookup_maps_->add_merge_input_section(p->first, p->second,
- pomb);
- }
- else if (sis.is_relaxed_input_section())
+ if (sis.is_relaxed_input_section())
{
Output_relaxed_input_section* poris = sis.relaxed_input_section();
this->lookup_maps_->add_relaxed_input_section(poris->relobj(),
public:
Output_section_lookup_maps()
: is_valid_(true), merge_sections_by_properties_(),
- merge_sections_by_id_(), relaxed_input_sections_by_id_()
+ relaxed_input_sections_by_id_()
{ }
// Whether the maps are valid.
clear()
{
this->merge_sections_by_properties_.clear();
- this->merge_sections_by_id_.clear();
this->relaxed_input_sections_by_id_.clear();
// A cleared map is valid.
this->is_valid_ = true;
return p != this->merge_sections_by_properties_.end() ? p->second : NULL;
}
- // Find a merge section by section ID of a merge input section. Return NULL
- // if none is found.
- Output_merge_base*
- find_merge_section(const Object* object, unsigned int shndx) const
- {
- gold_assert(this->is_valid_);
- Merge_sections_by_id::const_iterator p =
- this->merge_sections_by_id_.find(Const_section_id(object, shndx));
- return p != this->merge_sections_by_id_.end() ? p->second : NULL;
- }
-
// Add a merge section pointed by POMB with properties MSP.
void
add_merge_section(const Merge_section_properties& msp,
gold_assert(result.second);
}
- // Add a mapping from a merged input section in OBJECT with index SHNDX
- // to a merge output section pointed by POMB.
- void
- add_merge_input_section(const Object* object, unsigned int shndx,
- Output_merge_base* pomb)
- {
- Const_section_id csid(object, shndx);
- std::pair<Const_section_id, Output_merge_base*> value(csid, pomb);
- std::pair<Merge_sections_by_id::iterator, bool> result =
- this->merge_sections_by_id_.insert(value);
- gold_assert(result.second);
- }
-
// Find a relaxed input section of OBJECT with index SHNDX.
Output_relaxed_input_section*
find_relaxed_input_section(const Object* object, unsigned int shndx) const
}
private:
- typedef Unordered_map<Const_section_id, Output_merge_base*,
- Const_section_id_hash>
- Merge_sections_by_id;
-
typedef Unordered_map<Merge_section_properties, Output_merge_base*,
Merge_section_properties::hash,
Merge_section_properties::equal_to>
bool is_valid_;
// Merge sections by merge section properties.
Merge_sections_by_properties merge_sections_by_properties_;
- // Merge sections by section IDs.
- Merge_sections_by_id merge_sections_by_id_;
// Relaxed sections by section IDs.
Relaxed_input_sections_by_id relaxed_input_sections_by_id_;
};
section_offset_type offset,
section_offset_type* poutput) const;
- // Return whether this is the merge section for the input section
- // SHNDX in OBJECT.
- bool
- is_merge_section_for(const Relobj* object, unsigned int shndx) const;
-
// Write out the data. This does nothing for an input section.
void
write(Output_file*);
// Find the merge section into which an input section with index SHNDX in
// OBJECT has been added. Return NULL if none found.
- Output_section_data*
+ const Output_section_data*
find_merge_section(const Relobj* object, unsigned int shndx) const;
// Build a relaxation map.