- return ((this->shndx_ != invalid_shndx)
- ? this->u_.relobj
- : this->u_.relaxed_input_section->relobj());
- }
-
- // Return index of an input section.
- unsigned int
- shndx() const
- {
- return ((this->shndx_ != invalid_shndx)
- ? this->shndx_
- : this->u_.relaxed_input_section->shndx());
- }
-
- // Return the Output_relaxed_input_section object of a relaxed section.
- Output_relaxed_input_section*
- relaxed_input_section() const
- {
- gold_assert(this->shndx_ == invalid_shndx);
- return this->u_.relaxed_input_section;
- }
-
- private:
- // Pointer to either an Relobj or an Output_relaxed_input_section.
- union
- {
- Relobj* relobj;
- Output_relaxed_input_section* relaxed_input_section;
- } u_;
- // Section index for an non-relaxed section or invalid_shndx for
- // a relaxed section.
- unsigned int shndx_;
- };
-
- // Store the list of input sections for this Output_section into the
- // list passed in. This removes the input sections, leaving only
- // any Output_section_data elements. This returns the size of those
- // Output_section_data elements. ADDRESS is the address of this
- // output section. FILL is the fill value to use, in case there are
- // any spaces between the remaining Output_section_data elements.
- uint64_t
- get_input_sections(uint64_t address, const std::string& fill,
- std::list<Simple_input_section>*);
-
- // Add an input section from a script.
- void
- add_input_section_for_script(const Simple_input_section& input_section,
- off_t data_size, uint64_t addralign);
-
- // Set the current size of the output section.
- void
- set_current_data_size(off_t size)
- { this->set_current_data_size_for_child(size); }
-
- // Get the current size of the output section.
- off_t
- current_data_size() const
- { return this->current_data_size_for_child(); }
-
- // End of linker script support.
-
- // Save states before doing section layout.
- // This is used for relaxation.
- void
- save_states();
-
- // Restore states prior to section layout.
- void
- restore_states();
-
- // Print merge statistics to stderr.
- void
- print_merge_stats();
-
- protected:
- // Return the output section--i.e., the object itself.
- Output_section*
- do_output_section()
- { return this; }
-
- // Return the section index in the output file.
- unsigned int
- do_out_shndx() const
- {
- gold_assert(this->out_shndx_ != -1U);
- return this->out_shndx_;
- }
-
- // Set the output section index.
- void
- do_set_out_shndx(unsigned int shndx)
- {
- gold_assert(this->out_shndx_ == -1U || this->out_shndx_ == shndx);
- this->out_shndx_ = shndx;
- }
-
- // Set the final data size of the Output_section. For a typical
- // Output_section, there is nothing to do, but if there are any
- // Output_section_data objects we need to set their final addresses
- // here.
- virtual void
- set_final_data_size();
-
- // Reset the address and file offset.
- void
- do_reset_address_and_file_offset();
-
- // Return true if address and file offset already have reset values. In
- // other words, calling reset_address_and_file_offset will not change them.
- bool
- do_address_and_file_offset_have_reset_values() const;
-
- // Write the data to the file. For a typical Output_section, this
- // does nothing: the data is written out by calling Object::Relocate
- // on each input object. But if there are any Output_section_data
- // objects we do need to write them out here.
- virtual void
- do_write(Output_file*);
-
- // Return the address alignment--function required by parent class.
- uint64_t
- do_addralign() const
- { return this->addralign_; }
-
- // Return whether there is a load address.
- bool
- do_has_load_address() const
- { return this->has_load_address_; }
-
- // Return the load address.
- uint64_t
- do_load_address() const
- {
- gold_assert(this->has_load_address_);
- return this->load_address_;
- }
-
- // Return whether this is an Output_section.
- bool
- do_is_section() const
- { return true; }
-
- // Return whether this is a section of the specified type.
- bool
- do_is_section_type(elfcpp::Elf_Word type) const
- { return this->type_ == type; }
-
- // Return whether the specified section flag is set.
- bool
- do_is_section_flag_set(elfcpp::Elf_Xword flag) const
- { return (this->flags_ & flag) != 0; }
-
- // Set the TLS offset. Called only for SHT_TLS sections.
- void
- do_set_tls_offset(uint64_t tls_base);
-
- // Return the TLS offset, relative to the base of the TLS segment.
- // Valid only for SHT_TLS sections.
- uint64_t
- do_tls_offset() const
- { return this->tls_offset_; }
-
- // This may be implemented by a child class.
- virtual void
- do_finalize_name(Layout*)
- { }
-
- // Print to the map file.
- virtual void
- do_print_to_mapfile(Mapfile*) const;
-
- // Record that this section requires postprocessing after all
- // relocations have been applied. This is called by a child class.
- void
- set_requires_postprocessing()
- {
- this->requires_postprocessing_ = true;
- this->after_input_sections_ = true;
- }
-
- // Write all the data of an Output_section into the postprocessing
- // buffer.
- void
- write_to_postprocessing_buffer();
-
- private:
- // In some cases we need to keep a list of the input sections
- // associated with this output section. We only need the list if we
- // might have to change the offsets of the input section within the
- // output section after we add the input section. The ordinary
- // input sections will be written out when we process the object
- // file, and as such we don't need to track them here. We do need
- // to track Output_section_data objects here. We store instances of
- // this structure in a std::vector, so it must be a POD. There can
- // be many instances of this structure, so we use a union to save
- // some space.
- class Input_section
- {
- public:
- Input_section()
- : shndx_(0), p2align_(0)
- {
- this->u1_.data_size = 0;
- this->u2_.object = NULL;
- }
-
- // For an ordinary input section.
- Input_section(Relobj* object, unsigned int shndx, off_t data_size,
- uint64_t addralign)
- : shndx_(shndx),
- p2align_(ffsll(static_cast<long long>(addralign)))
- {
- gold_assert(shndx != OUTPUT_SECTION_CODE
- && shndx != MERGE_DATA_SECTION_CODE
- && shndx != MERGE_STRING_SECTION_CODE
- && shndx != RELAXED_INPUT_SECTION_CODE);
- this->u1_.data_size = data_size;
- this->u2_.object = object;