diff options
-rw-r--r-- | gold/merge.cc | 39 | ||||
-rw-r--r-- | gold/merge.h | 12 | ||||
-rw-r--r-- | gold/output.cc | 14 | ||||
-rw-r--r-- | gold/output.h | 6 |
4 files changed, 49 insertions, 22 deletions
diff --git a/gold/merge.cc b/gold/merge.cc index fc6bffb..beb0906 100644 --- a/gold/merge.cc +++ b/gold/merge.cc @@ -49,7 +49,8 @@ class Object_merge_map // Add a mapping for MERGE_MAP, for the bytes from OFFSET to OFFSET // + LENGTH in the input section SHNDX to OUTPUT_OFFSET in the // output section. An OUTPUT_OFFSET of -1 means that the bytes are - // discarded. + // 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); @@ -58,7 +59,8 @@ class Object_merge_map // input address is at offset OFFSET in section SHNDX. 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. + // true if the 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, section_offset_type offset, @@ -86,10 +88,28 @@ class Object_merge_map { return i1.input_offset < i2.input_offset; } }; - // A list of entries for a particular section. + // A list of entries for a particular input section. struct Input_merge_map { - // The Merge_map for this section. + // We store these with the Relobj, and we look them up by input + // section. It is possible to have two different merge maps + // associated with a single output section. For example, this + // happens routinely with .rodata, when merged string constants + // and merged fixed size constants are both put into .rodata. The + // output offset that we store is not the offset from the start of + // the output section; it is the offset from the start of the + // merged data in the output section. That means that the caller + // is going to add the offset of the merged data within the output + // section, which means that the caller needs to know which set of + // merged data it found the entry in. So it's not enough to find + // this data based on the input section and the output section; we + // also have to find it based on a set of merged data in the + // output section. In order to verify that we are looking at the + // right data, we store a pointer to the Merge_map here, and we + // pass in a pointer when looking at the data. If we are asked to + // 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; // The list of mappings. std::vector<Input_merge_entry> entries; @@ -162,7 +182,7 @@ Object_merge_map::get_or_make_input_merge_map(const Merge_map* merge_map, if (map != NULL) { // For a given input section in a given object, every mapping - // must be donw with the same Merge_map. + // must be done with the same Merge_map. gold_assert(map->merge_map == merge_map); return map; } @@ -277,8 +297,8 @@ Object_merge_map::get_output_offset(const Merge_map* merge_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 a merged -// output section. +// 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, @@ -297,8 +317,9 @@ Merge_map::add_mapping(Relobj* object, unsigned int shndx, // 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 returns -// true if the mapping is known, false otherwise. +// *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, diff --git a/gold/merge.h b/gold/merge.h index bf6a407..c232ab0 100644 --- a/gold/merge.h +++ b/gold/merge.h @@ -44,7 +44,9 @@ class 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. + // 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, @@ -54,7 +56,9 @@ class Merge_map // 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. + // 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, @@ -84,7 +88,9 @@ class Output_merge_base : public Output_section_data { return this->entsize_; } // Add a mapping from an OFFSET in input section SHNDX in object - // OBJECT to an OUTPUT_OFFSET in the output section. + // 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) diff --git a/gold/output.cc b/gold/output.cc index fa2bff0..793d6a3 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -1347,7 +1347,9 @@ Output_section::Input_section::finalize_data_size() this->u2_.posd->finalize_data_size(); } -// Try to turn an input offset into an output offset. +// Try to turn an input offset into an output offset. We want to +// return the output offset relative to the start of this +// Input_section in the output section. inline bool Output_section::Input_section::output_offset( @@ -1362,11 +1364,7 @@ Output_section::Input_section::output_offset( { if (this->shndx_ != shndx || this->u2_.object != object) return false; - section_offset_type output_offset; - Output_section* os = object->output_section(shndx, &output_offset); - gold_assert(os != NULL); - gold_assert(output_offset != -1); - *poutput = output_offset + offset; + *poutput = offset; return true; } } @@ -1655,8 +1653,8 @@ Output_section::is_input_address_mapped(const Relobj* object, // Given an address OFFSET relative to the start of input section // SHNDX in object OBJECT, return the output offset relative to the -// start of the section. This should only be called if SHNDX in -// OBJECT has a special mapping. +// start of the input section in the output section. This should only +// be called if SHNDX in OBJECT has a special mapping. section_offset_type Output_section::output_offset(const Relobj* object, unsigned int shndx, diff --git a/gold/output.h b/gold/output.h index 38e5c48..a244fa5 100644 --- a/gold/output.h +++ b/gold/output.h @@ -1895,8 +1895,10 @@ class Output_section : public Output_data // Given an input OBJECT, an input section index SHNDX within that // object, and an OFFSET relative to the start of that input // section, return whether or not the output offset is known. If - // this function returns true, it sets *POUTPUT to the output - // offset. + // this function returns true, it sets *POUTPUT to the offset in + // the output section, relative to the start of the input section + // in the output section. *POUTPUT may be different from OFFSET + // for a merged section. bool output_offset(const Relobj* object, unsigned int shndx, section_offset_type offset, |