dynamic_reloc_count() const
{ return this->dynamic_reloc_count_; }
+ // Whether the address is valid.
+ bool
+ is_address_valid() const
+ { return this->is_address_valid_; }
+
+ // Whether the file offset is valid.
+ bool
+ is_offset_valid() const
+ { return this->is_offset_valid_; }
+
+ // Whether the data size is valid.
+ bool
+ is_data_size_valid() const
+ { return this->is_data_size_valid_; }
+
protected:
// Functions that child classes may or in some cases must implement.
// Functions that child classes may call.
- // Whether the address is valid.
- bool
- is_address_valid() const
- { return this->is_address_valid_; }
-
- // Whether the file offset is valid.
- bool
- is_offset_valid() const
- { return this->is_offset_valid_; }
-
- // Whether the data size is valid.
- bool
- is_data_size_valid() const
- { return this->is_data_size_valid_; }
-
// Set the size of the data.
void
set_data_size(off_t data_size)
public:
Output_file_header(const Target*,
const Symbol_table*,
- const Output_segment_headers*);
+ const Output_segment_headers*,
+ const char* entry);
// Add information about the section headers. We lay out the ELF
// file header before we create the section headers.
void
do_sized_write(Output_file*);
+ // Return the value to use for the entry address.
+ template<int size>
+ typename elfcpp::Elf_types<size>::Elf_Addr
+ entry();
+
const Target* target_;
const Symbol_table* symtab_;
const Output_segment_headers* segment_header_;
const Output_section_headers* section_header_;
const Output_section* shstrtab_;
+ const char* entry_;
};
// Output sections are mainly comprised of input sections. However,
section_offset_type *poutput) const
{ return this->do_output_offset(object, shndx, offset, poutput); }
+ // Return whether this is the merge section for the input section
+ // SHNDX in OBJECT. This should return true when output_offset
+ // would return true for some values of OFFSET.
+ bool
+ is_merge_section_for(const Relobj* object, unsigned int shndx) const
+ { return this->do_is_merge_section_for(object, shndx); }
+
// Write the contents to a buffer. This is used for sections which
// require postprocessing, such as compression.
void
section_offset_type*) const
{ return false; }
+ // The child class may implement is_merge_section_for.
+ virtual bool
+ do_is_merge_section_for(const Relobj*, unsigned int) 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.
output_address(const Relobj* object, unsigned int shndx,
off_t offset) const;
+ // Return the output address of the start of the merged section for
+ // input section SHNDX in object OBJECT. This is not necessarily
+ // the offset corresponding to input offset 0 in the section, since
+ // the section may be mapped arbitrarily.
+ uint64_t
+ starting_output_address(const Relobj* object, unsigned int shndx) const;
+
// Write the section header into *OPHDR.
template<int size, bool big_endian>
void
section_offset_type offset,
section_offset_type *poutput) const;
+ // Return whether this is the merge section for the input section
+ // SHNDX in OBJECT.
+ bool
+ is_merge_section_for(const Relobj* object, unsigned int shndx) const;
+
// Write out the data. This does nothing for an input section.
void
write(Output_file*);
class Output_file
{
public:
- Output_file(const General_options& options, Target*);
-
- // Get a pointer to the target.
- Target*
- target() const
- { return this->target_; }
+ Output_file(const char* name);
// Open the output file. FILE_SIZE is the final size of the file.
void
// Write data to the output file.
void
- write(off_t offset, const void* data, off_t len)
+ write(off_t offset, const void* data, size_t len)
{ memcpy(this->base_ + offset, data, len); }
// Get a buffer to use to write to the file, given the offset into
// the file and the size.
unsigned char*
- get_output_view(off_t start, off_t size)
+ get_output_view(off_t start, size_t size)
{
- gold_assert(start >= 0 && size >= 0 && start + size <= this->file_size_);
+ gold_assert(start >= 0
+ && start + static_cast<off_t>(size) <= this->file_size_);
return this->base_ + start;
}
// VIEW must have been returned by get_output_view. Write the
// buffer to the file, passing in the offset and the size.
void
- write_output_view(off_t, off_t, unsigned char*)
+ write_output_view(off_t, size_t, unsigned char*)
{ }
// Get a read/write buffer. This is used when we want to write part
// of the file, read it in, and write it again.
unsigned char*
- get_input_output_view(off_t start, off_t size)
+ get_input_output_view(off_t start, size_t size)
{ return this->get_output_view(start, size); }
// Write a read/write buffer back to the file.
void
- write_input_output_view(off_t, off_t, unsigned char*)
+ write_input_output_view(off_t, size_t, unsigned char*)
{ }
// Get a read buffer. This is used when we just want to read part
// of the file back it in.
const unsigned char*
- get_input_view(off_t start, off_t size)
+ get_input_view(off_t start, size_t size)
{ return this->get_output_view(start, size); }
// Release a read bfufer.
void
- free_input_view(off_t, off_t, const unsigned char*)
+ free_input_view(off_t, size_t, const unsigned char*)
{ }
private:
void
unmap();
-
- // General options.
- const General_options& options_;
- // Target.
- Target* target_;
// File name.
const char* name_;
// File descriptor.