diff --git a/gold/ChangeLog b/gold/ChangeLog index 86ed4e8f6f5..b6cd629ab51 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,21 @@ +2009-12-16 Doug Kwan + + * arm.cc (Arm_relobj::scan_sections_for_stubs): Exclude ICF-eliminated + sections. + * object.cc (Sized_relobj::do_finalize_local_symbols): Handle + relaxed input sections. + * output.cc (Output_section::find_relaxed_input_section): Change + return type to Output_relaxed_input_section pointer. Adjust code + for new type of relaxed_input_section_map_. + * output.h (Output_section::find_relaxed_input_section): Change + return type to Output_relaxed_input_section pointer. + (Output_section::Output_relaxed_input_section_by_input_section_map): + New type. + (Output_section::relaxed_input_section_map_): Change type to + Output_section::Output_relaxed_input_section_by_input_section_map. + * symtab.cc (Symbol_table::compute_final_value): Handle relaxed + input section. + 2009-12-15 Ian Lance Taylor * layout.cc (Layout::create_shstrtab): Only write out after input diff --git a/gold/arm.cc b/gold/arm.cc index 03cc69798f6..b02afbe23ea 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -3645,10 +3645,12 @@ Arm_relobj::scan_sections_for_stubs( } Output_section* os = out_sections[index]; - if (os == NULL) + if (os == NULL + || symtab->is_section_folded(this, index)) { // This relocation section is against a section which we - // discarded. + // discarded or if the section is folded into another + // section due to ICF. continue; } Arm_address output_offset = this->get_output_section_offset(index); diff --git a/gold/object.cc b/gold/object.cc index 798e42d808d..9baf22768d9 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1683,7 +1683,15 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, os = folded_obj->output_section(folded.second); gold_assert(os != NULL); secoffset = folded_obj->get_output_section_offset(folded.second); - gold_assert(secoffset != invalid_address); + + // This could be a relaxed input section. + if (secoffset == invalid_address) + { + const Output_relaxed_input_section* relaxed_section = + os->find_relaxed_input_section(folded_obj, folded.second); + gold_assert(relaxed_section != NULL); + secoffset = relaxed_section->address() - os->address(); + } } if (os == NULL) diff --git a/gold/output.cc b/gold/output.cc index 61c2ba6f4b1..440d4f2b579 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -2224,7 +2224,7 @@ Output_section::find_merge_section(const Relobj* object, // Find an relaxed input section corresponding to an input section // in OBJECT with index SHNDX. -const Output_section_data* +const Output_relaxed_input_section* Output_section::find_relaxed_input_section(const Relobj* object, unsigned int shndx) const { @@ -2247,7 +2247,7 @@ Output_section::find_relaxed_input_section(const Relobj* object, } Input_section_specifier iss(object, shndx); - Output_section_data_by_input_section_map::const_iterator p = + Output_relaxed_input_section_by_input_section_map::const_iterator p = this->relaxed_input_section_map_.find(iss); if (p != this->relaxed_input_section_map_.end()) return p->second; diff --git a/gold/output.h b/gold/output.h index 6631aa1e849..3b060c86584 100644 --- a/gold/output.h +++ b/gold/output.h @@ -2599,7 +2599,7 @@ class Output_section : public Output_data // Find a relaxed input section to an input section in OBJECT // with index SHNDX. Return NULL if none is found. - const Output_section_data* + const Output_relaxed_input_section* find_relaxed_input_section(const Relobj* object, unsigned int shndx) const; // Print merge statistics to stderr. @@ -3190,6 +3190,12 @@ class Output_section : public Output_data Input_section_specifier::equal_to> Output_section_data_by_input_section_map; + // Map that link Input_section_specifier to Output_relaxed_input_section. + typedef Unordered_map + Output_relaxed_input_section_by_input_section_map; + // Map used during relaxation of existing sections. This map // an input section specifier to an input section list index. // We assume that Input_section_list is a vector. @@ -3358,7 +3364,8 @@ class Output_section : public Output_data // Map from input sections to relaxed input sections. This is mutable // because it is updated lazily. We may need to update it in a // const qualified method. - mutable Output_section_data_by_input_section_map relaxed_input_section_map_; + mutable Output_relaxed_input_section_by_input_section_map + relaxed_input_section_map_; // Whether relaxed_input_section_map_ is valid. mutable bool is_relaxed_input_section_map_valid_; }; diff --git a/gold/symtab.cc b/gold/symtab.cc index 7e8a89021d9..8cd4a40f1cf 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -2413,7 +2413,6 @@ Symbol_table::compute_final_value( { Relobj* relobj = static_cast(symobj); Output_section* os = relobj->output_section(shndx); - uint64_t secoff64 = relobj->output_section_offset(shndx); if (this->is_section_folded(relobj, shndx)) { @@ -2423,11 +2422,17 @@ Symbol_table::compute_final_value( shndx); gold_assert(folded.first != NULL); Relobj* folded_obj = reinterpret_cast(folded.first); - os = folded_obj->output_section(folded.second); + unsigned folded_shndx = folded.second; + + os = folded_obj->output_section(folded_shndx); gold_assert(os != NULL); - secoff64 = folded_obj->output_section_offset(folded.second); + + // Replace (relobj, shndx) with canonical ICF input section. + shndx = folded_shndx; + relobj = folded_obj; } + uint64_t secoff64 = relobj->output_section_offset(shndx); if (os == NULL) { bool static_or_reloc = (parameters->doing_static_link() ||