Remove empty class Merge_map.
2015-03-02 Rafael Ávila de Espíndola <rafael.espindola@gmail.com> * ehframe.cc (Cie::set_output_offset): Pass in and use a Output_section_data instead of a Merge_map. (Eh_frame::Eh_frame): Don't initialize merge_map_. (Eh_frame::read_cie): Use add_merge_mapping instead of Merge_map::add_mapping. (Eh_frame::read_fde): Ditto. (Eh_frame::set_final_data_size): Use this instead of this->merge_map_. (Eh_frame::do_output_offset): Use merge_output_offset istead of merge_map_->get_output_offset. (Eh_frame::do_is_merge_section_for): Delete. * ehframe.h (Fde::add_mapping): Pass in and use a Output_section_data instead of a Merge_map. (Cie::set_output_offset): Pass in a Output_section_data instead of a Merge_map. (Eh_frame::do_is_merge_section_for): Delete. (Eh_frame::merge_map_): Delete. * merge.cc (Object_merge_map::get_or_make_input_merge_map): Pass in and use a Output_section_data instead of a Merge_map. (Object_merge_map::add_mapping): Ditto. (Object_merge_map::get_output_offset): Remove the merge_map argument. (Object_merge_map::is_merge_section_for): Pass in and use a Output_section_data instead of a Merge_map. (Merge_map): Delete. (Output_merge_base::do_output_offset): Use merge_output_offset instead of merge_map_.get_output_offset. (Output_merge_base::do_is_merge_section_for): Delete. (Output_merge_data::do_add_input_section): Use object->add_merge_mapping instead of add_mapping. (Output_merge_string<Char_type>::finalize_merged_data): Ditto. * merge.h (Merge_map): Delete forward declaration. (Object_merge_map::add_mapping): Pass in and use a Output_section_data instead of a Merge_map. (Object_merge_map::get_output_offset): Remove the merge_map argument. (Object_merge_map::is_merge_section_for): Pass in and use a Output_section_data instead of a Merge_map. (Input_merge_map::Object_merge_map::merge_map): Replace with output_data. (Object_merge_map::get_or_make_input_merge_map): Pass in and use a Output_section_data instead of a Merge_map. (Merge_map): Delete. (Output_merge_base::Output_merge_base): Don't initialize merge_map_. (Output_merge_base::do_is_merge_section_for): Delete. (Output_merge_base::add_mapping): Delete. (Output_merge_base::merge_map_): Delete. * object.cc (Relobj::initialize_input_to_output_map): New. (Relobj::initialize_input_to_output_map): New. (Relobj::merge_output_offset): New. (Relobj::is_merge_section_for): New. (Relobj::initialize_input_to_output_map): Instantiate for 32 and 64 bits. * object.h (Relobj::merge_map): Delete. (initialize_input_to_output_map): New. (set_merge_map): Delete. (add_merge_mapping): New. (merge_output_offset): New. (is_merge_section_for): New. * output.cc (Output_section::Input_section::is_merge_section_for): Use object->is_merge_section_for. * output.h (Output_section_data::is_merge_section_for): Delete. (Output_section_data::do_is_merge_section_for): Delete. * reloc.cc (Merged_symbol_value<size>::initialize_input_to_output_map): Use object->initialize_input_to_output_map. (Merged_symbol_value<size>::value_from_output_section): Use object->merge_output_offset.
This commit is contained in:
parent
a8d9763abd
commit
dbe40a8891
10 changed files with 200 additions and 209 deletions
|
@ -1,3 +1,70 @@
|
|||
2015-03-02 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||
|
||||
* ehframe.cc (Cie::set_output_offset): Pass in and use a
|
||||
Output_section_data instead of a Merge_map.
|
||||
(Eh_frame::Eh_frame): Don't initialize merge_map_.
|
||||
(Eh_frame::read_cie): Use add_merge_mapping instead of
|
||||
Merge_map::add_mapping.
|
||||
(Eh_frame::read_fde): Ditto.
|
||||
(Eh_frame::set_final_data_size): Use this instead of this->merge_map_.
|
||||
(Eh_frame::do_output_offset): Use merge_output_offset istead of
|
||||
merge_map_->get_output_offset.
|
||||
(Eh_frame::do_is_merge_section_for): Delete.
|
||||
* ehframe.h (Fde::add_mapping): Pass in and use a Output_section_data
|
||||
instead of a Merge_map.
|
||||
(Cie::set_output_offset): Pass in a Output_section_data instead of a
|
||||
Merge_map.
|
||||
(Eh_frame::do_is_merge_section_for): Delete.
|
||||
(Eh_frame::merge_map_): Delete.
|
||||
* merge.cc (Object_merge_map::get_or_make_input_merge_map): Pass in
|
||||
and use a Output_section_data instead of a Merge_map.
|
||||
(Object_merge_map::add_mapping): Ditto.
|
||||
(Object_merge_map::get_output_offset): Remove the merge_map argument.
|
||||
(Object_merge_map::is_merge_section_for): Pass in and use a
|
||||
Output_section_data instead of a Merge_map.
|
||||
(Merge_map): Delete.
|
||||
(Output_merge_base::do_output_offset): Use merge_output_offset instead
|
||||
of merge_map_.get_output_offset.
|
||||
(Output_merge_base::do_is_merge_section_for): Delete.
|
||||
(Output_merge_data::do_add_input_section): Use
|
||||
object->add_merge_mapping instead of add_mapping.
|
||||
(Output_merge_string<Char_type>::finalize_merged_data): Ditto.
|
||||
* merge.h (Merge_map): Delete forward declaration.
|
||||
(Object_merge_map::add_mapping): Pass in and use a Output_section_data
|
||||
instead of a Merge_map.
|
||||
(Object_merge_map::get_output_offset): Remove the merge_map argument.
|
||||
(Object_merge_map::is_merge_section_for): Pass in and use a
|
||||
Output_section_data instead of a Merge_map.
|
||||
(Input_merge_map::Object_merge_map::merge_map): Replace with
|
||||
output_data.
|
||||
(Object_merge_map::get_or_make_input_merge_map): Pass in and use a
|
||||
Output_section_data instead of a Merge_map.
|
||||
(Merge_map): Delete.
|
||||
(Output_merge_base::Output_merge_base): Don't initialize merge_map_.
|
||||
(Output_merge_base::do_is_merge_section_for): Delete.
|
||||
(Output_merge_base::add_mapping): Delete.
|
||||
(Output_merge_base::merge_map_): Delete.
|
||||
* object.cc (Relobj::initialize_input_to_output_map): New.
|
||||
(Relobj::initialize_input_to_output_map): New.
|
||||
(Relobj::merge_output_offset): New.
|
||||
(Relobj::is_merge_section_for): New.
|
||||
(Relobj::initialize_input_to_output_map): Instantiate for 32 and 64
|
||||
bits.
|
||||
* object.h (Relobj::merge_map): Delete.
|
||||
(initialize_input_to_output_map): New.
|
||||
(set_merge_map): Delete.
|
||||
(add_merge_mapping): New.
|
||||
(merge_output_offset): New.
|
||||
(is_merge_section_for): New.
|
||||
* output.cc (Output_section::Input_section::is_merge_section_for):
|
||||
Use object->is_merge_section_for.
|
||||
* output.h (Output_section_data::is_merge_section_for): Delete.
|
||||
(Output_section_data::do_is_merge_section_for): Delete.
|
||||
* reloc.cc (Merged_symbol_value<size>::initialize_input_to_output_map):
|
||||
Use object->initialize_input_to_output_map.
|
||||
(Merged_symbol_value<size>::value_from_output_section): Use
|
||||
object->merge_output_offset.
|
||||
|
||||
2015-02-04 Peter Collingbourne <pcc@google.com>
|
||||
Cary Coutant <ccoutant@google.com>
|
||||
|
||||
|
|
|
@ -412,7 +412,7 @@ Cie::~Cie()
|
|||
section_offset_type
|
||||
Cie::set_output_offset(section_offset_type output_offset,
|
||||
unsigned int addralign,
|
||||
Merge_map* merge_map)
|
||||
Output_section_data *output_data)
|
||||
{
|
||||
size_t length = this->contents_.length();
|
||||
|
||||
|
@ -422,8 +422,9 @@ Cie::set_output_offset(section_offset_type output_offset,
|
|||
if (this->object_ != NULL)
|
||||
{
|
||||
// Add a mapping so that relocations are applied correctly.
|
||||
merge_map->add_mapping(this->object_, this->shndx_, this->input_offset_,
|
||||
length, output_offset);
|
||||
this->object_->add_merge_mapping(output_data, this->shndx_,
|
||||
this->input_offset_, length,
|
||||
output_offset);
|
||||
}
|
||||
|
||||
length = align_address(length, addralign);
|
||||
|
@ -432,7 +433,7 @@ Cie::set_output_offset(section_offset_type output_offset,
|
|||
p != this->fdes_.end();
|
||||
++p)
|
||||
{
|
||||
(*p)->add_mapping(output_offset + length, merge_map);
|
||||
(*p)->add_mapping(output_offset + length, output_data);
|
||||
|
||||
size_t fde_length = (*p)->length();
|
||||
fde_length = align_address(fde_length, addralign);
|
||||
|
@ -531,7 +532,6 @@ Eh_frame::Eh_frame()
|
|||
eh_frame_hdr_(NULL),
|
||||
cie_offsets_(),
|
||||
unmergeable_cie_offsets_(),
|
||||
merge_map_(),
|
||||
mappings_are_done_(false),
|
||||
final_data_size_(0)
|
||||
{
|
||||
|
@ -958,8 +958,8 @@ Eh_frame::read_cie(Sized_relobj_file<size, big_endian>* object,
|
|||
// know for sure that we are doing a special mapping for this
|
||||
// input section, but that's OK--if we don't do a special
|
||||
// mapping, nobody will ever ask for the mapping we add here.
|
||||
this->merge_map_.add_mapping(object, shndx, (pcie - 8) - pcontents,
|
||||
pcieend - (pcie - 8), -1);
|
||||
object->add_merge_mapping(this, shndx, (pcie - 8) - pcontents,
|
||||
pcieend - (pcie - 8), -1);
|
||||
}
|
||||
|
||||
// Record this CIE plus the offset in the input section.
|
||||
|
@ -1026,8 +1026,8 @@ Eh_frame::read_fde(Sized_relobj_file<size, big_endian>* object,
|
|||
{
|
||||
// This FDE applies to a section which we are discarding. We
|
||||
// can discard this FDE.
|
||||
this->merge_map_.add_mapping(object, shndx, (pfde - 8) - pcontents,
|
||||
pfdeend - (pfde - 8), -1);
|
||||
object->add_merge_mapping(this, shndx, (pfde - 8) - pcontents,
|
||||
pfdeend - (pfde - 8), -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1107,14 +1107,14 @@ Eh_frame::set_final_data_size()
|
|||
++p)
|
||||
output_offset = (*p)->set_output_offset(output_offset,
|
||||
this->addralign(),
|
||||
&this->merge_map_);
|
||||
this);
|
||||
|
||||
for (Cie_offsets::iterator p = this->cie_offsets_.begin();
|
||||
p != this->cie_offsets_.end();
|
||||
++p)
|
||||
output_offset = (*p)->set_output_offset(output_offset,
|
||||
this->addralign(),
|
||||
&this->merge_map_);
|
||||
this);
|
||||
|
||||
this->mappings_are_done_ = true;
|
||||
this->final_data_size_ = output_offset - output_start;
|
||||
|
@ -1130,16 +1130,7 @@ Eh_frame::do_output_offset(const Relobj* object, unsigned int shndx,
|
|||
section_offset_type offset,
|
||||
section_offset_type* poutput) const
|
||||
{
|
||||
return this->merge_map_.get_output_offset(object, shndx, offset, poutput);
|
||||
}
|
||||
|
||||
// Return whether this is the merge section for an input section.
|
||||
|
||||
bool
|
||||
Eh_frame::do_is_merge_section_for(const Relobj* object,
|
||||
unsigned int shndx) const
|
||||
{
|
||||
return this->merge_map_.is_merge_section_for(object, shndx);
|
||||
return object->merge_output_offset(shndx, offset, poutput);
|
||||
}
|
||||
|
||||
// Write the data to the output file.
|
||||
|
|
|
@ -192,10 +192,11 @@ class Fde
|
|||
// Add a mapping for this FDE to MERGE_MAP, so that relocations
|
||||
// against the FDE are applied to right part of the output file.
|
||||
void
|
||||
add_mapping(section_offset_type output_offset, Merge_map* merge_map) const
|
||||
add_mapping(section_offset_type output_offset,
|
||||
Output_section_data* output_data) const
|
||||
{
|
||||
if (this->object_ != NULL)
|
||||
merge_map->add_mapping(this->object_, this->u_.from_object.shndx,
|
||||
this->object_->add_merge_mapping(output_data, this->u_.from_object.shndx,
|
||||
this->u_.from_object.input_offset, this->length(),
|
||||
output_offset);
|
||||
}
|
||||
|
@ -308,7 +309,7 @@ class Cie
|
|||
// mapping. It returns the new output offset.
|
||||
section_offset_type
|
||||
set_output_offset(section_offset_type output_offset, unsigned int addralign,
|
||||
Merge_map*);
|
||||
Output_section_data*);
|
||||
|
||||
// Write the CIE to OVIEW starting at OFFSET. Round up the bytes to
|
||||
// ADDRALIGN. ADDRESS is the virtual address of OVIEW.
|
||||
|
@ -406,10 +407,6 @@ class Eh_frame : public Output_section_data
|
|||
section_offset_type offset,
|
||||
section_offset_type* poutput) const;
|
||||
|
||||
// Return whether this is the merge section for an input section.
|
||||
bool
|
||||
do_is_merge_section_for(const Relobj*, unsigned int shndx) const;
|
||||
|
||||
// Write the data to the file.
|
||||
void
|
||||
do_write(Output_file*);
|
||||
|
@ -504,8 +501,6 @@ class Eh_frame : public Output_section_data
|
|||
// A mapping from unmergeable CIEs to their offset in the output
|
||||
// file.
|
||||
Unmergeable_cie_offsets unmergeable_cie_offsets_;
|
||||
// A mapping from input sections to the output section.
|
||||
Merge_map merge_map_;
|
||||
// Whether we have created the mappings to the output section.
|
||||
bool mappings_are_done_;
|
||||
// The final data size. This is only set if mappings_are_done_ is
|
||||
|
|
|
@ -62,15 +62,14 @@ Object_merge_map::get_input_merge_map(unsigned int shndx)
|
|||
// Get or create the Input_merge_map to use for an input section.
|
||||
|
||||
Object_merge_map::Input_merge_map*
|
||||
Object_merge_map::get_or_make_input_merge_map(const Merge_map* merge_map,
|
||||
unsigned int shndx)
|
||||
{
|
||||
Object_merge_map::get_or_make_input_merge_map(
|
||||
const Output_section_data* output_data, unsigned int shndx) {
|
||||
Input_merge_map* map = this->get_input_merge_map(shndx);
|
||||
if (map != NULL)
|
||||
{
|
||||
// For a given input section in a given object, every mapping
|
||||
// must be done with the same Merge_map.
|
||||
gold_assert(map->merge_map == merge_map);
|
||||
gold_assert(map->output_data == output_data);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -78,18 +77,18 @@ Object_merge_map::get_or_make_input_merge_map(const Merge_map* merge_map,
|
|||
if (this->first_shnum_ == -1U)
|
||||
{
|
||||
this->first_shnum_ = shndx;
|
||||
this->first_map_.merge_map = merge_map;
|
||||
this->first_map_.output_data = output_data;
|
||||
return &this->first_map_;
|
||||
}
|
||||
if (this->second_shnum_ == -1U)
|
||||
{
|
||||
this->second_shnum_ = shndx;
|
||||
this->second_map_.merge_map = merge_map;
|
||||
this->second_map_.output_data = output_data;
|
||||
return &this->second_map_;
|
||||
}
|
||||
|
||||
Input_merge_map* new_map = new Input_merge_map;
|
||||
new_map->merge_map = merge_map;
|
||||
new_map->output_data = output_data;
|
||||
this->section_merge_maps_[shndx] = new_map;
|
||||
return new_map;
|
||||
}
|
||||
|
@ -97,12 +96,13 @@ Object_merge_map::get_or_make_input_merge_map(const Merge_map* merge_map,
|
|||
// Add a mapping.
|
||||
|
||||
void
|
||||
Object_merge_map::add_mapping(const Merge_map* merge_map, unsigned int shndx,
|
||||
Object_merge_map::add_mapping(const Output_section_data* output_data,
|
||||
unsigned int shndx,
|
||||
section_offset_type input_offset,
|
||||
section_size_type length,
|
||||
section_offset_type output_offset)
|
||||
{
|
||||
Input_merge_map* map = this->get_or_make_input_merge_map(merge_map, shndx);
|
||||
Input_merge_map* map = this->get_or_make_input_merge_map(output_data, shndx);
|
||||
|
||||
// Try to merge the new entry in the last one we saw.
|
||||
if (!map->entries.empty())
|
||||
|
@ -142,14 +142,12 @@ Object_merge_map::add_mapping(const Merge_map* merge_map, unsigned int shndx,
|
|||
// Get the output offset for an input address.
|
||||
|
||||
bool
|
||||
Object_merge_map::get_output_offset(const Merge_map* merge_map,
|
||||
unsigned int shndx,
|
||||
Object_merge_map::get_output_offset(unsigned int shndx,
|
||||
section_offset_type input_offset,
|
||||
section_offset_type* output_offset)
|
||||
{
|
||||
Input_merge_map* map = this->get_input_merge_map(shndx);
|
||||
if (map == NULL
|
||||
|| (merge_map != NULL && map->merge_map != merge_map))
|
||||
if (map == NULL)
|
||||
return false;
|
||||
|
||||
if (!map->sorted)
|
||||
|
@ -181,12 +179,12 @@ Object_merge_map::get_output_offset(const Merge_map* merge_map,
|
|||
|
||||
// Return whether this is the merge map for section SHNDX.
|
||||
|
||||
inline bool
|
||||
Object_merge_map::is_merge_section_for(const Merge_map* merge_map,
|
||||
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->merge_map == merge_map;
|
||||
return map != NULL && map->output_data == output_data;
|
||||
}
|
||||
|
||||
// Initialize a mapping from input offsets to output addresses.
|
||||
|
@ -228,57 +226,6 @@ Object_merge_map::initialize_input_to_output_map(
|
|||
}
|
||||
}
|
||||
|
||||
// Class Merge_map.
|
||||
|
||||
// Add a mapping for the bytes from OFFSET to OFFSET + LENGTH in input
|
||||
// section SHNDX in object OBJECT to an OUTPUT_OFFSET in merged data
|
||||
// in an output section.
|
||||
|
||||
void
|
||||
Merge_map::add_mapping(Relobj* object, unsigned int shndx,
|
||||
section_offset_type offset, section_size_type length,
|
||||
section_offset_type output_offset)
|
||||
{
|
||||
gold_assert(object != NULL);
|
||||
Object_merge_map* object_merge_map = object->merge_map();
|
||||
if (object_merge_map == NULL)
|
||||
{
|
||||
object_merge_map = new Object_merge_map();
|
||||
object->set_merge_map(object_merge_map);
|
||||
}
|
||||
|
||||
object_merge_map->add_mapping(this, shndx, offset, length, output_offset);
|
||||
}
|
||||
|
||||
// Return the output offset for an input address. The input address
|
||||
// is at offset OFFSET in section SHNDX in OBJECT. This sets
|
||||
// *OUTPUT_OFFSET to the offset in the merged data in the output
|
||||
// section. This returns true if the mapping is known, false
|
||||
// otherwise.
|
||||
|
||||
bool
|
||||
Merge_map::get_output_offset(const Relobj* object, unsigned int shndx,
|
||||
section_offset_type offset,
|
||||
section_offset_type* output_offset) const
|
||||
{
|
||||
Object_merge_map* object_merge_map = object->merge_map();
|
||||
if (object_merge_map == NULL)
|
||||
return false;
|
||||
return object_merge_map->get_output_offset(this, shndx, offset,
|
||||
output_offset);
|
||||
}
|
||||
|
||||
// Return whether this is the merge section for SHNDX in OBJECT.
|
||||
|
||||
bool
|
||||
Merge_map::is_merge_section_for(const Relobj* object, unsigned int shndx) const
|
||||
{
|
||||
Object_merge_map* object_merge_map = object->merge_map();
|
||||
if (object_merge_map == NULL)
|
||||
return false;
|
||||
return object_merge_map->is_merge_section_for(this, shndx);
|
||||
}
|
||||
|
||||
// Class Output_merge_base.
|
||||
|
||||
// Return the output offset for an input offset. The input address is
|
||||
|
@ -291,16 +238,7 @@ Output_merge_base::do_output_offset(const Relobj* object,
|
|||
section_offset_type offset,
|
||||
section_offset_type* poutput) const
|
||||
{
|
||||
return this->merge_map_.get_output_offset(object, shndx, offset, poutput);
|
||||
}
|
||||
|
||||
// Return whether this is the merge section for SHNDX in OBJECT.
|
||||
|
||||
bool
|
||||
Output_merge_base::do_is_merge_section_for(const Relobj* object,
|
||||
unsigned int shndx) const
|
||||
{
|
||||
return this->merge_map_.is_merge_section_for(object, shndx);
|
||||
return object->merge_output_offset(shndx, offset, poutput);
|
||||
}
|
||||
|
||||
// Record a merged input section for script processing.
|
||||
|
@ -436,7 +374,7 @@ Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx)
|
|||
}
|
||||
|
||||
// Record the offset of this constant in the output section.
|
||||
this->add_mapping(object, shndx, i, entsize, k);
|
||||
object->add_merge_mapping(this, shndx, i, entsize, k);
|
||||
}
|
||||
|
||||
// For script processing, we keep the input sections.
|
||||
|
@ -625,8 +563,8 @@ Output_merge_string<Char_type>::finalize_merged_data()
|
|||
{
|
||||
section_size_type length = p->offset - last_input_offset;
|
||||
if (length > 0)
|
||||
this->add_mapping((*l)->object, (*l)->shndx, last_input_offset,
|
||||
length, last_output_offset);
|
||||
(*l)->object->add_merge_mapping(this, (*l)->shndx,
|
||||
last_input_offset, length, last_output_offset);
|
||||
last_input_offset = p->offset;
|
||||
if (p->stringpool_key != 0)
|
||||
last_output_offset =
|
||||
|
|
78
gold/merge.h
78
gold/merge.h
|
@ -33,8 +33,6 @@
|
|||
namespace gold
|
||||
{
|
||||
|
||||
class Merge_map;
|
||||
|
||||
// For each object with merge sections, we store an Object_merge_map.
|
||||
// This is used to map locations in input sections to a merged output
|
||||
// section. The output section itself is not recorded here--it can be
|
||||
|
@ -57,8 +55,9 @@ class Object_merge_map
|
|||
// discarded. OUTPUT_OFFSET is relative to the start of the merged
|
||||
// data in the output section.
|
||||
void
|
||||
add_mapping(const Merge_map*, unsigned int shndx, section_offset_type offset,
|
||||
section_size_type length, section_offset_type output_offset);
|
||||
add_mapping(const Output_section_data*, unsigned int shndx,
|
||||
section_offset_type offset, section_size_type length,
|
||||
section_offset_type output_offset);
|
||||
|
||||
// Get the output offset for an input address. MERGE_MAP is the map
|
||||
// we are looking for, or NULL if we don't care. The input address
|
||||
|
@ -68,13 +67,13 @@ class Object_merge_map
|
|||
// mapping is known, false otherwise. *OUTPUT_OFFSET is relative to
|
||||
// the start of the merged data in the output section.
|
||||
bool
|
||||
get_output_offset(const Merge_map*, unsigned int shndx,
|
||||
get_output_offset(unsigned int shndx,
|
||||
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 Merge_map*, unsigned int shndx);
|
||||
is_merge_section_for(const Output_section_data*, unsigned int shndx);
|
||||
|
||||
// Initialize an mapping from input offsets to output addresses for
|
||||
// section SHNDX. STARTING_ADDRESS is the output address of the
|
||||
|
@ -133,14 +132,14 @@ class Object_merge_map
|
|||
// look up information for a different Merge_map, we report that
|
||||
// we don't have it, rather than trying a lookup and returning an
|
||||
// answer which will receive the wrong offset.
|
||||
const Merge_map* merge_map;
|
||||
const Output_section_data* output_data;
|
||||
// The list of mappings.
|
||||
Entries entries;
|
||||
// Whether the ENTRIES field is sorted by input_offset.
|
||||
bool sorted;
|
||||
|
||||
Input_merge_map()
|
||||
: merge_map(NULL), entries(), sorted(true)
|
||||
: output_data(NULL), entries(), sorted(true)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -155,7 +154,8 @@ 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 Merge_map* merge_map, unsigned int shndx);
|
||||
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
|
||||
|
@ -169,46 +169,6 @@ class Object_merge_map
|
|||
Section_merge_maps section_merge_maps_;
|
||||
};
|
||||
|
||||
// This class manages mappings from input sections to offsets in an
|
||||
// output section. This is used where input sections are merged. The
|
||||
// actual data is stored in fields in Object.
|
||||
|
||||
class Merge_map
|
||||
{
|
||||
public:
|
||||
Merge_map()
|
||||
{ }
|
||||
|
||||
// Add a mapping for the bytes from OFFSET to OFFSET + LENGTH in the
|
||||
// input section SHNDX in object OBJECT to OUTPUT_OFFSET in the
|
||||
// output section. An OUTPUT_OFFSET of -1 means that the bytes are
|
||||
// discarded. OUTPUT_OFFSET is not the offset from the start of the
|
||||
// output section, it is the offset from the start of the merged
|
||||
// data within the output section.
|
||||
void
|
||||
add_mapping(Relobj* object, unsigned int shndx,
|
||||
section_offset_type offset, section_size_type length,
|
||||
section_offset_type output_offset);
|
||||
|
||||
// Return the output offset for an input address. The input address
|
||||
// is at offset OFFSET in section SHNDX in OBJECT. This sets
|
||||
// *OUTPUT_OFFSET to the offset in the output section; this will be
|
||||
// -1 if the bytes are not being copied to the output. This returns
|
||||
// true if the mapping is known, false otherwise. This returns the
|
||||
// value stored by add_mapping, namely the offset from the start of
|
||||
// the merged data within the output section.
|
||||
bool
|
||||
get_output_offset(const Relobj* object, unsigned int shndx,
|
||||
section_offset_type offset,
|
||||
section_offset_type* output_offset) const;
|
||||
|
||||
// Return whether this is the merge mapping for section SHNDX in
|
||||
// OBJECT. This should return true when get_output_offset would
|
||||
// return true for some input offset.
|
||||
bool
|
||||
is_merge_section_for(const Relobj* object, unsigned int shndx) const;
|
||||
};
|
||||
|
||||
// A general class for SHF_MERGE data, to hold functions shared by
|
||||
// fixed-size constant data and string data.
|
||||
|
||||
|
@ -216,7 +176,7 @@ class Output_merge_base : public Output_section_data
|
|||
{
|
||||
public:
|
||||
Output_merge_base(uint64_t entsize, uint64_t addralign)
|
||||
: Output_section_data(addralign), merge_map_(), entsize_(entsize),
|
||||
: Output_section_data(addralign), entsize_(entsize),
|
||||
keeps_input_sections_(false), first_relobj_(NULL), first_shndx_(-1),
|
||||
input_sections_()
|
||||
{ }
|
||||
|
@ -285,21 +245,6 @@ class Output_merge_base : public Output_section_data
|
|||
section_offset_type offset,
|
||||
section_offset_type* poutput) const;
|
||||
|
||||
// Return whether this is the merge section for an input section.
|
||||
bool
|
||||
do_is_merge_section_for(const Relobj*, unsigned int shndx) const;
|
||||
|
||||
// Add a mapping from an OFFSET in input section SHNDX in object
|
||||
// OBJECT to an OUTPUT_OFFSET in the output section. OUTPUT_OFFSET
|
||||
// is the offset from the start of the merged data in the output
|
||||
// section.
|
||||
void
|
||||
add_mapping(Relobj* object, unsigned int shndx, section_offset_type offset,
|
||||
section_size_type length, section_offset_type output_offset)
|
||||
{
|
||||
this->merge_map_.add_mapping(object, shndx, offset, length, output_offset);
|
||||
}
|
||||
|
||||
// This may be overridden by the child class.
|
||||
virtual bool
|
||||
do_is_string()
|
||||
|
@ -315,9 +260,6 @@ class Output_merge_base : public Output_section_data
|
|||
record_input_section(Relobj* relobj, unsigned int shndx);
|
||||
|
||||
private:
|
||||
// A mapping from input object/section/offset to offset in output
|
||||
// section.
|
||||
Merge_map merge_map_;
|
||||
// The entry size. For fixed-size constants, this is the size of
|
||||
// the constants. For strings, this is the size of a character.
|
||||
uint64_t entsize_;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "plugin.h"
|
||||
#include "compressed_output.h"
|
||||
#include "incremental.h"
|
||||
#include "merge.h"
|
||||
|
||||
namespace gold
|
||||
{
|
||||
|
@ -268,6 +269,50 @@ Object::handle_split_stack_section(const char* name)
|
|||
|
||||
// Class Relobj
|
||||
|
||||
template<int size>
|
||||
void
|
||||
Relobj::initialize_input_to_output_map(unsigned int shndx,
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr starting_address,
|
||||
Unordered_map<section_offset_type,
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr>* output_addresses) const {
|
||||
Object_merge_map *map = this->object_merge_map_;
|
||||
map->initialize_input_to_output_map<size>(shndx, starting_address,
|
||||
output_addresses);
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
bool
|
||||
Relobj::merge_output_offset(unsigned int shndx, section_offset_type offset,
|
||||
section_offset_type *poutput) const {
|
||||
Object_merge_map* object_merge_map = this->object_merge_map_;
|
||||
if (object_merge_map == NULL)
|
||||
return false;
|
||||
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 {
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
// To copy the symbols data read from the file to a local data structure.
|
||||
// This function is called from do_layout only while doing garbage
|
||||
// collection.
|
||||
|
@ -3209,6 +3254,24 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset,
|
|||
|
||||
// Instantiate the templates we need.
|
||||
|
||||
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
|
||||
template
|
||||
void
|
||||
Relobj::initialize_input_to_output_map<64>(unsigned int shndx,
|
||||
typename elfcpp::Elf_types<64>::Elf_Addr starting_address,
|
||||
Unordered_map<section_offset_type,
|
||||
typename elfcpp::Elf_types<64>::Elf_Addr>* output_addresses) const;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
|
||||
template
|
||||
void
|
||||
Relobj::initialize_input_to_output_map<32>(unsigned int shndx,
|
||||
typename elfcpp::Elf_types<32>::Elf_Addr starting_address,
|
||||
Unordered_map<section_offset_type,
|
||||
typename elfcpp::Elf_types<32>::Elf_Addr>* output_addresses) const;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
template
|
||||
void
|
||||
|
|
|
@ -41,6 +41,7 @@ class Cref;
|
|||
class Layout;
|
||||
class Output_data;
|
||||
class Output_section;
|
||||
class Output_section_data;
|
||||
class Output_file;
|
||||
class Output_symtab_xindex;
|
||||
class Pluginobj;
|
||||
|
@ -1200,18 +1201,26 @@ class Relobj : public Object
|
|||
relocs_must_follow_section_writes() const
|
||||
{ return this->relocs_must_follow_section_writes_; }
|
||||
|
||||
// Return the object merge map.
|
||||
Object_merge_map*
|
||||
merge_map() const
|
||||
{ return this->object_merge_map_; }
|
||||
|
||||
// Set the object merge map.
|
||||
template<int size>
|
||||
void
|
||||
set_merge_map(Object_merge_map* object_merge_map)
|
||||
{
|
||||
gold_assert(this->object_merge_map_ == NULL);
|
||||
this->object_merge_map_ = object_merge_map;
|
||||
}
|
||||
initialize_input_to_output_map(unsigned int shndx,
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr starting_address,
|
||||
Unordered_map<section_offset_type,
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr>* output_address) const;
|
||||
|
||||
void
|
||||
add_merge_mapping(Output_section_data *output_data,
|
||||
unsigned int shndx, section_offset_type offset,
|
||||
section_size_type length,
|
||||
section_offset_type output_offset);
|
||||
|
||||
bool
|
||||
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;
|
||||
|
||||
// Record the relocatable reloc info for an input reloc section.
|
||||
void
|
||||
|
|
|
@ -2210,7 +2210,7 @@ Output_section::Input_section::is_merge_section_for(const Relobj* object,
|
|||
{
|
||||
if (this->is_input_section())
|
||||
return false;
|
||||
return this->u2_.posd->is_merge_section_for(object, shndx);
|
||||
return object->is_merge_section_for(this->u2_.posd, shndx);
|
||||
}
|
||||
|
||||
// Write out the data. We don't have to do anything for an input
|
||||
|
|
|
@ -675,13 +675,6 @@ class Output_section_data : public Output_data
|
|||
section_offset_type* poutput) const
|
||||
{ return this->do_output_offset(object, shndx, offset, poutput); }
|
||||
|
||||
// Return whether this is the merge section for the input section
|
||||
// SHNDX in OBJECT. This should return true when output_offset
|
||||
// would return true for some values of OFFSET.
|
||||
bool
|
||||
is_merge_section_for(const Relobj* object, unsigned int shndx) const
|
||||
{ return this->do_is_merge_section_for(object, shndx); }
|
||||
|
||||
// Write the contents to a buffer. This is used for sections which
|
||||
// require postprocessing, such as compression.
|
||||
void
|
||||
|
@ -715,11 +708,6 @@ class Output_section_data : public Output_data
|
|||
section_offset_type*) const
|
||||
{ return false; }
|
||||
|
||||
// The child class may implement is_merge_section_for.
|
||||
virtual bool
|
||||
do_is_merge_section_for(const Relobj*, unsigned int) const
|
||||
{ return false; }
|
||||
|
||||
// The child class may implement write_to_buffer. Most child
|
||||
// classes can not appear in a compressed section, and they do not
|
||||
// implement this.
|
||||
|
|
|
@ -1457,10 +1457,9 @@ Merged_symbol_value<size>::initialize_input_to_output_map(
|
|||
const Relobj* object,
|
||||
unsigned int input_shndx)
|
||||
{
|
||||
Object_merge_map* map = object->merge_map();
|
||||
map->initialize_input_to_output_map<size>(input_shndx,
|
||||
this->output_start_address_,
|
||||
&this->output_addresses_);
|
||||
object->initialize_input_to_output_map<size>(input_shndx,
|
||||
this->output_start_address_,
|
||||
&this->output_addresses_);
|
||||
}
|
||||
|
||||
// Get the output value corresponding to an input offset if we
|
||||
|
@ -1474,9 +1473,8 @@ Merged_symbol_value<size>::value_from_output_section(
|
|||
typename elfcpp::Elf_types<size>::Elf_Addr input_offset) const
|
||||
{
|
||||
section_offset_type output_offset;
|
||||
bool found = object->merge_map()->get_output_offset(NULL, input_shndx,
|
||||
input_offset,
|
||||
&output_offset);
|
||||
bool found = object->merge_output_offset(input_shndx, input_offset,
|
||||
&output_offset);
|
||||
|
||||
// If this assertion fails, it means that some relocation was
|
||||
// against a portion of an input merge section which we didn't map
|
||||
|
|
Loading…
Reference in a new issue