aboutsummaryrefslogtreecommitdiff
path: root/gold/output.h
diff options
context:
space:
mode:
Diffstat (limited to 'gold/output.h')
-rw-r--r--gold/output.h142
1 files changed, 93 insertions, 49 deletions
diff --git a/gold/output.h b/gold/output.h
index 95d95f6..fafd62b 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -432,15 +432,6 @@ class Output_section_data : public Output_data
add_input_section(Relobj* object, unsigned int shndx)
{ return this->do_add_input_section(object, shndx); }
- // This class may change the output section name. This is called
- // right before shstrtab is written, so after all input-section
- // layout processing is done. The input is the old name, and the
- // output should be a new name (which will be copied into permanent
- // storage) to change the name, or NULL to keep the name as-is.
- virtual const char*
- do_modified_output_section_name(const char*)
- { return NULL; }
-
// Given an input OBJECT, an input section index SHNDX within that
// object, and an OFFSET relative to the start of that input
// section, return whether or not the corresponding offset within
@@ -452,6 +443,12 @@ class Output_section_data : public Output_data
off_t *poutput) const
{ return this->do_output_offset(object, shndx, offset, poutput); }
+ // Write the contents to a buffer. This is used for sections which
+ // require postprocessing, such as compression.
+ void
+ write_to_buffer(unsigned char* buffer)
+ { this->do_write_to_buffer(buffer); }
+
protected:
// The child class must implement do_write.
@@ -472,6 +469,13 @@ class Output_section_data : public Output_data
do_output_offset(const Relobj*, unsigned int, off_t, off_t*) const
{ return false; }
+ // The child class may implement write_to_buffer. Most child
+ // classes can not appear in a compressed section, and they do not
+ // implement this.
+ virtual void
+ do_write_to_buffer(unsigned char*)
+ { gold_unreachable(); }
+
// Return the required alignment.
uint64_t
do_addralign() const
@@ -545,6 +549,11 @@ class Output_data_const : public Output_section_data
void
do_write(Output_file*);
+ // Write the data to a buffer.
+ void
+ do_write_to_buffer(unsigned char* buffer)
+ { memcpy(buffer, this->data_.data(), this->data_.size()); }
+
private:
std::string data_;
};
@@ -565,6 +574,11 @@ class Output_data_const_buffer : public Output_section_data
void
do_write(Output_file*);
+ // Write the data to a buffer.
+ void
+ do_write_to_buffer(unsigned char* buffer)
+ { memcpy(buffer, this->p_, this->data_size()); }
+
private:
const unsigned char* p_;
};
@@ -629,6 +643,11 @@ class Output_data_strtab : public Output_section_data
void
do_write(Output_file*);
+ // Write the data to a buffer.
+ void
+ do_write_to_buffer(unsigned char* buffer)
+ { this->strtab_->write_to_buffer(buffer, this->data_size()); }
+
private:
Stringpool* strtab_;
};
@@ -1317,8 +1336,7 @@ class Output_section : public Output_data
{
public:
// Create an output section, giving the name, type, and flags.
- Output_section(const General_options& options,
- const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword);
+ Output_section(const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword);
virtual ~Output_section();
// Add a new input section SHNDX, named NAME, with header SHDR, from
@@ -1341,13 +1359,6 @@ class Output_section : public Output_data
name() const
{ return this->name_; }
- // Modify the section name. This should be called only after this
- // section is done being constructed. The input should be a pointer
- // into layout's namepool_.
- void
- set_name(const char* newname)
- { this->name_ = newname; }
-
// Return the section type.
elfcpp::Elf_Word
type() const
@@ -1506,11 +1517,23 @@ class Output_section : public Output_data
requires_postprocessing() const
{ return this->requires_postprocessing_; }
- // Record that this section requires postprocessing after all
- // relocations have been applied.
+ // If a section requires postprocessing, return the buffer to use.
+ unsigned char*
+ postprocessing_buffer() const
+ {
+ gold_assert(this->postprocessing_buffer_ != NULL);
+ return this->postprocessing_buffer_;
+ }
+
+ // If a section requires postprocessing, create the buffer to use.
void
- set_requires_postprocessing()
- { this->requires_postprocessing_ = true; }
+ create_postprocessing_buffer();
+
+ // If a section requires postprocessing, this is the size of the
+ // buffer to which relocations should be applied.
+ off_t
+ postprocessing_buffer_size() const
+ { return this->current_data_size_for_child(); }
// Return whether the offset OFFSET in the input section SHNDX in
// object OBJECT is being included in the link.
@@ -1535,16 +1558,6 @@ class Output_section : public Output_data
write_header(const Layout*, const Stringpool*,
elfcpp::Shdr_write<size, big_endian>*) const;
- // This class may change the output section name. This is called
- // right before shstrtab is written, so after all input-section
- // layout processing is done. This calls
- // do_modified_output_section_name() on all its output_section_data
- // members, and changes the name if any member so suggests. If
- // several members would suggest, this takes the first, arbitrarily.
- // Return true if the name was modified, false else.
- bool
- maybe_modify_output_section_name();
-
protected:
// Return the section index in the output file.
unsigned int
@@ -1566,14 +1579,14 @@ class Output_section : public Output_data
// Output_section, there is nothing to do, but if there are any
// Output_section_data objects we need to set their final addresses
// here.
- void
+ virtual void
set_final_data_size();
// 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.
- void
+ virtual void
do_write(Output_file*);
// Return the address alignment--function required by parent class.
@@ -1596,6 +1609,36 @@ class Output_section : public Output_data
do_is_section_flag_set(elfcpp::Elf_Xword flag) const
{ return (this->flags_ & flag) != 0; }
+ // Modify the section name. This is only permitted for an
+ // unallocated section, and only before the size has been finalized.
+ // Otherwise the name will not get into Layout::namepool_.
+ void
+ set_name(const char* newname)
+ {
+ gold_assert((this->flags_ & elfcpp::SHF_ALLOC) == 0);
+ gold_assert(!this->is_data_size_valid());
+ this->name_ = newname;
+ }
+
+ // This may be implemented by a child class.
+ virtual void
+ do_finalize_name(Layout*)
+ { }
+
+ // 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
@@ -1685,19 +1728,15 @@ class Output_section : public Output_data
}
// Set the address and file offset. This is called during
- // Layout::finalize. SECOFF is the file offset of the enclosing
- // section.
+ // Layout::finalize. SECTION_FILE_OFFSET is the file offset of
+ // the enclosing section.
void
- set_address(uint64_t addr, off_t off, off_t secoff);
+ set_address_and_file_offset(uint64_t address, off_t file_offset,
+ off_t section_file_offset);
- // Call modified_output_section_name on the output-section-data object.
- const char*
- modified_output_section_name(const char* name) const
- {
- if (this->is_input_section())
- return NULL;
- return this->u2_.posd->do_modified_output_section_name(name);
- }
+ // Finalize the data size.
+ void
+ finalize_data_size();
// Add an input section, for SHF_MERGE sections.
bool
@@ -1721,6 +1760,11 @@ class Output_section : public Output_data
void
write(Output_file*);
+ // Write the data to a buffer. This does nothing for an input
+ // section.
+ void
+ write_to_buffer(unsigned char*);
+
private:
// Code values which appear in shndx_. If the value is not one of
// these codes, it is the input section index in the object file.
@@ -1813,8 +1857,7 @@ class Output_section : public Output_data
// handled.
bool
add_merge_input_section(Relobj* object, unsigned int shndx, uint64_t flags,
- uint64_t entsize, uint64_t addralign,
- bool can_compress_section);
+ uint64_t entsize, uint64_t addralign);
// Add an output SHF_MERGE section POSD to this output section.
// IS_STRING indicates whether it is a SHF_STRINGS section, and
@@ -1826,8 +1869,6 @@ class Output_section : public Output_data
// Most of these fields are only valid after layout.
- // General options.
- const General_options& options_;
// The name of the section. This will point into a Stringpool.
const char* name_;
// The section address is in the parent class.
@@ -1869,6 +1910,9 @@ class Output_section : public Output_data
// often will need fill sections without needing to keep track of
// input sections.
Fill_list fills_;
+ // If the section requires postprocessing, this buffer holds the
+ // section contents during relocation.
+ unsigned char* postprocessing_buffer_;
// Whether this output section needs a STT_SECTION symbol in the
// normal symbol table. This will be true if there is a relocation
// which needs it.