+ if (is_pass_two && parameters->options().gc_sections())
+ {
+ // This is executed during the second pass of garbage
+ // collection. do_layout has been called before and some
+ // sections have been already discarded. Simply ignore
+ // such sections this time around.
+ if (out_sections[i] == NULL)
+ {
+ gold_assert(out_section_offsets[i] == invalid_address);
+ continue;
+ }
+ if (((shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0)
+ && symtab->gc()->is_section_garbage(this, i))
+ {
+ if (parameters->options().print_gc_sections())
+ gold_info(_("%s: removing unused section from '%s'"
+ " in file '%s'"),
+ program_name, this->section_name(i).c_str(),
+ this->name().c_str());
+ out_sections[i] = NULL;
+ out_section_offsets[i] = invalid_address;
+ continue;
+ }
+ }
+
+ if (is_pass_two && parameters->options().icf_enabled())
+ {
+ if (out_sections[i] == NULL)
+ {
+ gold_assert(out_section_offsets[i] == invalid_address);
+ continue;
+ }
+ if (((shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0)
+ && symtab->icf()->is_section_folded(this, i))
+ {
+ if (parameters->options().print_icf_sections())
+ {
+ Section_id folded =
+ symtab->icf()->get_folded_section(this, i);
+ Relobj* folded_obj =
+ reinterpret_cast<Relobj*>(folded.first);
+ gold_info(_("%s: ICF folding section '%s' in file '%s' "
+ "into '%s' in file '%s'"),
+ program_name, this->section_name(i).c_str(),
+ this->name().c_str(),
+ folded_obj->section_name(folded.second).c_str(),
+ folded_obj->name().c_str());
+ }
+ out_sections[i] = NULL;
+ out_section_offsets[i] = invalid_address;
+ continue;
+ }
+ }
+
+ // Defer layout here if input files are claimed by plugins. When gc
+ // is turned on this function is called twice; we only want to do this
+ // on the first pass.
+ if (!is_pass_two
+ && this->is_deferred_layout()
+ && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC))
+ {
+ this->deferred_layout_.push_back(Deferred_layout(i, name,
+ pshdrs,
+ reloc_shndx[i],
+ reloc_type[i]));
+ // Put dummy values here; real values will be supplied by
+ // do_layout_deferred_sections.
+ out_sections[i] = reinterpret_cast<Output_section*>(2);
+ out_section_offsets[i] = invalid_address;
+ continue;
+ }
+
+ // During gc_pass_two if a section that was previously deferred is
+ // found, do not layout the section as layout_deferred_sections will
+ // do it later from gold.cc.
+ if (is_pass_two
+ && (out_sections[i] == reinterpret_cast<Output_section*>(2)))
+ continue;
+
+ if (is_pass_one)
+ {
+ // This is during garbage collection. The out_sections are
+ // assigned in the second call to this function.
+ out_sections[i] = reinterpret_cast<Output_section*>(1);
+ out_section_offsets[i] = invalid_address;
+ }
+ else
+ {
+ // When garbage collection is switched on the actual layout
+ // only happens in the second call.
+ this->layout_section(layout, i, name, shdr, reloc_shndx[i],
+ reloc_type[i]);
+
+ // When generating a .gdb_index section, we do additional
+ // processing of .debug_info and .debug_types sections after all
+ // the other sections for the same reason as above.
+ if (!relocatable
+ && parameters->options().gdb_index()
+ && !(shdr.get_sh_flags() & elfcpp::SHF_ALLOC))
+ {
+ if (strcmp(name, ".debug_info") == 0
+ || strcmp(name, ".zdebug_info") == 0)
+ debug_info_sections.push_back(i);
+ else if (strcmp(name, ".debug_types") == 0
+ || strcmp(name, ".zdebug_types") == 0)
+ debug_types_sections.push_back(i);
+ }
+ }
+ }
+
+ if (!is_pass_two)
+ layout->layout_gnu_stack(seen_gnu_stack, gnu_stack_flags, this);
+
+ // Handle the .eh_frame sections after the other sections.
+ gold_assert(!is_pass_one || eh_frame_sections.empty());
+ for (std::vector<unsigned int>::const_iterator p = eh_frame_sections.begin();
+ p != eh_frame_sections.end();
+ ++p)
+ {
+ unsigned int i = *p;
+ const unsigned char* pshdr;
+ pshdr = section_headers_data + i * This::shdr_size;
+ typename This::Shdr shdr(pshdr);
+
+ this->layout_eh_frame_section(layout,
+ symbols_data,
+ symbols_size,
+ symbol_names_data,
+ symbol_names_size,
+ i,
+ shdr,
+ reloc_shndx[i],
+ reloc_type[i]);
+ }
+
+ // When doing a relocatable link handle the reloc sections at the
+ // end. Garbage collection and Identical Code Folding is not
+ // turned on for relocatable code.
+ if (emit_relocs)
+ this->size_relocatable_relocs();
+
+ gold_assert(!is_two_pass || reloc_sections.empty());
+
+ for (std::vector<unsigned int>::const_iterator p = reloc_sections.begin();
+ p != reloc_sections.end();
+ ++p)
+ {
+ unsigned int i = *p;
+ const unsigned char* pshdr;
+ pshdr = section_headers_data + i * This::shdr_size;
+ typename This::Shdr shdr(pshdr);
+
+ unsigned int data_shndx = this->adjust_shndx(shdr.get_sh_info());
+ if (data_shndx >= shnum)
+ {
+ // We already warned about this above.
+ continue;
+ }
+
+ Output_section* data_section = out_sections[data_shndx];
+ if (data_section == reinterpret_cast<Output_section*>(2))
+ {
+ if (is_pass_two)
+ continue;
+ // The layout for the data section was deferred, so we need
+ // to defer the relocation section, too.
+ const char* name = pnames + shdr.get_sh_name();
+ this->deferred_layout_relocs_.push_back(
+ Deferred_layout(i, name, pshdr, 0, elfcpp::SHT_NULL));
+ out_sections[i] = reinterpret_cast<Output_section*>(2);
+ out_section_offsets[i] = invalid_address;
+ continue;
+ }
+ if (data_section == NULL)
+ {
+ out_sections[i] = NULL;
+ out_section_offsets[i] = invalid_address;
+ continue;
+ }
+
+ Relocatable_relocs* rr = new Relocatable_relocs();
+ this->set_relocatable_relocs(i, rr);
+
+ Output_section* os = layout->layout_reloc(this, i, shdr, data_section,
+ rr);
+ out_sections[i] = os;
+ out_section_offsets[i] = invalid_address;
+ }
+
+ // When building a .gdb_index section, scan the .debug_info and
+ // .debug_types sections.
+ gold_assert(!is_pass_one
+ || (debug_info_sections.empty() && debug_types_sections.empty()));
+ for (std::vector<unsigned int>::const_iterator p
+ = debug_info_sections.begin();
+ p != debug_info_sections.end();
+ ++p)
+ {
+ unsigned int i = *p;
+ layout->add_to_gdb_index(false, this, symbols_data, symbols_size,
+ i, reloc_shndx[i], reloc_type[i]);
+ }
+ for (std::vector<unsigned int>::const_iterator p
+ = debug_types_sections.begin();
+ p != debug_types_sections.end();
+ ++p)
+ {
+ unsigned int i = *p;
+ layout->add_to_gdb_index(true, this, symbols_data, symbols_size,
+ i, reloc_shndx[i], reloc_type[i]);
+ }
+
+ if (is_pass_two)
+ {
+ delete[] gc_sd->section_headers_data;
+ delete[] gc_sd->section_names_data;
+ delete[] gc_sd->symbols_data;
+ delete[] gc_sd->symbol_names_data;
+ this->set_symbols_data(NULL);
+ }
+ else
+ {
+ delete sd->section_headers;
+ sd->section_headers = NULL;
+ delete sd->section_names;
+ sd->section_names = NULL;
+ }
+}
+
+// Layout sections whose layout was deferred while waiting for
+// input files from a plugin.
+
+template<int size, bool big_endian>
+void
+Sized_relobj_file<size, big_endian>::do_layout_deferred_sections(Layout* layout)
+{
+ typename std::vector<Deferred_layout>::iterator deferred;
+
+ for (deferred = this->deferred_layout_.begin();
+ deferred != this->deferred_layout_.end();
+ ++deferred)
+ {
+ typename This::Shdr shdr(deferred->shdr_data_);
+
+ if (!parameters->options().relocatable()
+ && deferred->name_ == ".eh_frame"
+ && this->check_eh_frame_flags(&shdr))