#include "output.h"
#include "target-select.h"
-using elfcpp::Convert;
-
namespace gold {
// Version information. Will change frequently during the development, later
// we could think about backward (and forward?) compatibility.
const unsigned int INCREMENTAL_LINK_VERSION = 1;
-namespace internal {
-
-// Header of the .gnu_incremental_input section.
-struct Incremental_inputs_header_data
-{
- // Incremental linker version.
- elfcpp::Elf_Word version;
-
- // Numer of input files in the link.
- elfcpp::Elf_Word input_file_count;
-
- // Offset of command line options in .gnu_incremental_strtab.
- elfcpp::Elf_Word command_line_offset;
-
- // Padding.
- elfcpp::Elf_Word reserved;
-};
-
-// Data stored in .gnu_incremental_input after the header for each of the
-// Incremental_input_header_data::input_file_count input entries.
-struct Incremental_inputs_entry_data
-{
- // Offset of file name in .gnu_incremental_strtab section.
- elfcpp::Elf_Word filename_offset;
-
- // Offset of data in .gnu_incremental_input.
- elfcpp::Elf_Word data_offset;
-
- // Timestamp (in seconds).
- elfcpp::Elf_Xword timestamp_sec;
-
- // Nano-second part of timestamp (if supported).
- elfcpp::Elf_Word timestamp_nsec;
-
- // Type of the input entry.
- elfcpp::Elf_Half input_type;
-
- // Padding.
- elfcpp::Elf_Half reserved;
-};
-
-}
-
-// Accessors.
-
-// Reader class for .gnu_incremental_inputs header. See
-// internal::Incremental_inputs_header_data for fields descriptions.
-
-template<int size, bool big_endian>
-class Incremental_inputs_header
-{
- public:
- Incremental_inputs_header(const unsigned char *p)
- : p_(reinterpret_cast<const internal::Incremental_inputs_header_data*>(p))
- { }
-
- static const int data_size = sizeof(internal::Incremental_inputs_header_data);
-
- elfcpp::Elf_Word
- get_version() const
- { return Convert<32, big_endian>::convert_host(this->p_->version); }
-
- elfcpp::Elf_Word
- get_input_file_count() const
- { return Convert<32, big_endian>::convert_host(this->p_->input_file_count); }
-
- elfcpp::Elf_Word
- get_command_line_offset() const
- { return Convert<32, big_endian>::convert_host(this->p_->command_line_offset); }
-
- elfcpp::Elf_Word
- get_reserved() const
- { return Convert<32, big_endian>::convert_host(this->p_->reserved); }
-
- private:
- const internal::Incremental_inputs_header_data* p_;
-};
-
-// Writer class for .gnu_incremental_inputs header. See
-// internal::Incremental_inputs_header_data for fields descriptions.
-
-template<int size, bool big_endian>
-class Incremental_inputs_header_write
-{
- public:
- Incremental_inputs_header_write(unsigned char *p)
- : p_(reinterpret_cast<internal::Incremental_inputs_header_data*>(p))
- { }
-
- static const int data_size = sizeof(internal::Incremental_inputs_header_data);
-
- void
- put_version(elfcpp::Elf_Word v)
- { this->p_->version = Convert<32, big_endian>::convert_host(v); }
-
- void
- put_input_file_count(elfcpp::Elf_Word v)
- { this->p_->input_file_count = Convert<32, big_endian>::convert_host(v); }
-
- void
- put_command_line_offset(elfcpp::Elf_Word v)
- { this->p_->command_line_offset = Convert<32, big_endian>::convert_host(v); }
-
- void
- put_reserved(elfcpp::Elf_Word v)
- { this->p_->reserved = Convert<32, big_endian>::convert_host(v); }
-
- private:
- internal::Incremental_inputs_header_data* p_;
-};
-
-// Reader class for an .gnu_incremental_inputs entry. See
-// internal::Incremental_inputs_entry_data for fields descriptions.
-template<int size, bool big_endian>
-class Incremental_inputs_entry
-{
- public:
- Incremental_inputs_entry(const unsigned char *p)
- : p_(reinterpret_cast<const internal::Incremental_inputs_entry_data*>(p))
- { }
-
- static const int data_size = sizeof(internal::Incremental_inputs_entry_data);
-
- elfcpp::Elf_Word
- get_filename_offset(elfcpp::Elf_Word v)
- { return Convert<32, big_endian>::convert_host(this->p_->filename_offset); }
-
- elfcpp::Elf_Word
- get_data_offset(elfcpp::Elf_Word v)
- { return Convert<32, big_endian>::convert_host(this->p_->data_offset); }
-
- elfcpp::Elf_Xword
- get_timestamp_sec(elfcpp::Elf_Xword v)
- { return Convert<64, big_endian>::convert_host(this->p_->timestamp_sec); }
-
- elfcpp::Elf_Word
- get_timestamp_nsec(elfcpp::Elf_Word v)
- { return Convert<32, big_endian>::convert_host(this->p_->timestamp_nsec); }
-
- elfcpp::Elf_Word
- get_input_type(elfcpp::Elf_Word v)
- { return Convert<32, big_endian>::convert_host(this->p_->input_type); }
-
- elfcpp::Elf_Word
- get_reserved(elfcpp::Elf_Word v)
- { return Convert<32, big_endian>::convert_host(this->p_->reserved); }
-
- private:
- const internal::Incremental_inputs_entry_data* p_;
-};
-
-// Writer class for an .gnu_incremental_inputs entry. See
-// internal::Incremental_inputs_entry_data for fields descriptions.
-template<int size, bool big_endian>
-class Incremental_inputs_entry_write
-{
- public:
- Incremental_inputs_entry_write(unsigned char *p)
- : p_(reinterpret_cast<internal::Incremental_inputs_entry_data*>(p))
- { }
-
- static const int data_size = sizeof(internal::Incremental_inputs_entry_data);
-
- void
- put_filename_offset(elfcpp::Elf_Word v)
- { this->p_->filename_offset = Convert<32, big_endian>::convert_host(v); }
-
- void
- put_data_offset(elfcpp::Elf_Word v)
- { this->p_->data_offset = Convert<32, big_endian>::convert_host(v); }
-
- void
- put_timestamp_sec(elfcpp::Elf_Xword v)
- { this->p_->timestamp_sec = Convert<64, big_endian>::convert_host(v); }
-
- void
- put_timestamp_nsec(elfcpp::Elf_Word v)
- { this->p_->timestamp_nsec = Convert<32, big_endian>::convert_host(v); }
-
- void
- put_input_type(elfcpp::Elf_Word v)
- { this->p_->input_type = Convert<32, big_endian>::convert_host(v); }
-
- void
- put_reserved(elfcpp::Elf_Word v)
- { this->p_->reserved = Convert<32, big_endian>::convert_host(v); }
-
- private:
- internal::Incremental_inputs_entry_data* p_;
-};
-
// Inform the user why we don't do an incremental link. Not called in
// the obvious case of missing output file. TODO: Is this helpful?
return NULL;
}
+ if (!parameters->target_valid())
+ set_parameters_target(target);
+ else if (target != ¶meters->target())
+ gold_error(_("%s: incompatible target"), file->filename());
+
return new Sized_incremental_binary<size, big_endian>(file, ehdr, target);
}
int filename_offset =
this->strtab_->get_offset_from_key(it->second.filename_key);
entry.put_filename_offset(filename_offset);
+ switch (it->second.type)
+ {
+ case INCREMENTAL_INPUT_SCRIPT:
+ entry.put_data_offset(0);
+ break;
+ case INCREMENTAL_INPUT_ARCHIVE:
+ case INCREMENTAL_INPUT_OBJECT:
+ case INCREMENTAL_INPUT_SHARED_LIBRARY:
+ // TODO: add per input data. Currently we store
+ // an out-of-bounds offset for future version of gold to reject
+ // such an incremental_inputs section.
+ entry.put_data_offset(0xffffffff);
+ break;
+ default:
+ gold_unreachable();
+ }
// TODO: add per input data and timestamp. Currently we store
// an out-of-bounds offset for future version of gold to reject
// such an incremental_inputs section.