+// If NAME is the name of the special section which indicates that
+// this object was compiled with -fsplit-stack, mark it accordingly.
+
+bool
+Object::handle_split_stack_section(const char* name)
+{
+ if (strcmp(name, ".note.GNU-split-stack") == 0)
+ {
+ this->uses_split_stack_ = true;
+ return true;
+ }
+ if (strcmp(name, ".note.GNU-no-split-stack") == 0)
+ {
+ this->has_no_split_stack_ = true;
+ return true;
+ }
+ return false;
+}
+
+// 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.
+
+void
+Relobj::copy_symbols_data(Symbols_data* gc_sd, Read_symbols_data* sd,
+ unsigned int section_header_size)
+{
+ gc_sd->section_headers_data =
+ new unsigned char[(section_header_size)];
+ memcpy(gc_sd->section_headers_data, sd->section_headers->data(),
+ section_header_size);
+ gc_sd->section_names_data =
+ new unsigned char[sd->section_names_size];
+ memcpy(gc_sd->section_names_data, sd->section_names->data(),
+ sd->section_names_size);
+ gc_sd->section_names_size = sd->section_names_size;
+ if (sd->symbols != NULL)
+ {
+ gc_sd->symbols_data =
+ new unsigned char[sd->symbols_size];
+ memcpy(gc_sd->symbols_data, sd->symbols->data(),
+ sd->symbols_size);
+ }
+ else
+ {
+ gc_sd->symbols_data = NULL;
+ }
+ gc_sd->symbols_size = sd->symbols_size;
+ gc_sd->external_symbols_offset = sd->external_symbols_offset;
+ if (sd->symbol_names != NULL)
+ {
+ gc_sd->symbol_names_data =
+ new unsigned char[sd->symbol_names_size];
+ memcpy(gc_sd->symbol_names_data, sd->symbol_names->data(),
+ sd->symbol_names_size);
+ }
+ else
+ {
+ gc_sd->symbol_names_data = NULL;
+ }
+ gc_sd->symbol_names_size = sd->symbol_names_size;
+}
+
+// This function determines if a particular section name must be included
+// in the link. This is used during garbage collection to determine the
+// roots of the worklist.
+
+bool
+Relobj::is_section_name_included(const char* name)
+{
+ if (is_prefix_of(".ctors", name)
+ || is_prefix_of(".dtors", name)
+ || is_prefix_of(".note", name)
+ || is_prefix_of(".init", name)
+ || is_prefix_of(".fini", name)
+ || is_prefix_of(".gcc_except_table", name)
+ || is_prefix_of(".jcr", name)
+ || is_prefix_of(".preinit_array", name)
+ || (is_prefix_of(".text", name)
+ && strstr(name, "personality"))
+ || (is_prefix_of(".data", name)
+ && strstr(name, "personality"))
+ || (is_prefix_of(".sdata", name)
+ && strstr(name, "personality"))
+ || (is_prefix_of(".gnu.linkonce.d", name)
+ && strstr(name, "personality"))
+ || (is_prefix_of(".rodata", name)
+ && strstr(name, "nptl_version")))
+ {
+ return true;
+ }
+ return false;
+}
+
+// Finalize the incremental relocation information. Allocates a block
+// of relocation entries for each symbol, and sets the reloc_bases_
+// array to point to the first entry in each block. If CLEAR_COUNTS
+// is TRUE, also clear the per-symbol relocation counters.
+
+void
+Relobj::finalize_incremental_relocs(Layout* layout, bool clear_counts)
+{
+ unsigned int nsyms = this->get_global_symbols()->size();
+ this->reloc_bases_ = new unsigned int[nsyms];
+
+ gold_assert(this->reloc_bases_ != NULL);
+ gold_assert(layout->incremental_inputs() != NULL);
+
+ unsigned int rindex = layout->incremental_inputs()->get_reloc_count();
+ for (unsigned int i = 0; i < nsyms; ++i)
+ {
+ this->reloc_bases_[i] = rindex;
+ rindex += this->reloc_counts_[i];
+ if (clear_counts)
+ this->reloc_counts_[i] = 0;
+ }
+ layout->incremental_inputs()->set_reloc_count(rindex);
+}
+