From aecf301fb9a06b3d05280260758bcd3e85d7413e Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 29 Jun 2011 00:39:54 +0000 Subject: PR gold/12898 * layout.cc (Layout::segment_precedes): Don't crash if a linker script create indistinguishable segments. (Layout::set_segment_offsets): Use stable_sort when sorting segments. Pass this to Compare_segments constructor. * layout.h (class Layout): Make segment_precedes non-static. (class Compare_segments): Change from struct to class. Add layout_ field. Add constructor. * script-sections.cc (Script_sections::attach_sections_using_phdrs_clause): Rename local orphan to is_orphan. Don't report failure to put empty section in segment. On attachment failure, report name of section, and attach to first PT_LOAD segment. --- gold/script-sections.cc | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'gold/script-sections.cc') diff --git a/gold/script-sections.cc b/gold/script-sections.cc index 005f6673e7..1fad88dd81 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -4050,15 +4050,37 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout) p != this->sections_elements_->end(); ++p) { - bool orphan; + bool is_orphan; String_list* old_phdr_names = phdr_names; - Output_section* os = (*p)->allocate_to_segment(&phdr_names, &orphan); + Output_section* os = (*p)->allocate_to_segment(&phdr_names, &is_orphan); if (os == NULL) continue; + elfcpp::Elf_Word seg_flags = + Layout::section_flags_to_segment(os->flags()); + if (phdr_names == NULL) { - gold_error(_("allocated section not in any segment")); + // Don't worry about empty orphan sections. + if (is_orphan && os->current_data_size() > 0) + gold_error(_("allocated section %s not in any segment"), + os->name()); + + // To avoid later crashes drop this section into the first + // PT_LOAD segment. + for (Phdrs_elements::const_iterator ppe = + this->phdrs_elements_->begin(); + ppe != this->phdrs_elements_->end(); + ++ppe) + { + Output_segment* oseg = (*ppe)->segment(); + if (oseg->type() == elfcpp::PT_LOAD) + { + oseg->add_output_section_to_load(layout, os, seg_flags); + break; + } + } + continue; } @@ -4073,7 +4095,7 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout) // PT_INTERP segment will pick up following orphan sections, // which does not make sense. If this is not an orphan section, // we trust the linker script. - if (orphan) + if (is_orphan) { // Enable PT_LOAD segments only filtering until we see another // list of segment names. @@ -4094,9 +4116,6 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout) && r->second->type() != elfcpp::PT_LOAD) continue; - elfcpp::Elf_Word seg_flags = - Layout::section_flags_to_segment(os->flags()); - if (r->second->type() != elfcpp::PT_LOAD) r->second->add_output_section_to_nonload(os, seg_flags); else -- cgit v1.2.1