// inremental.h -- incremental linking support for gold -*- C++ -*-
-// Copyright 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2009-2019 Free Software Foundation, Inc.
// Written by Mikolaj Zalewski <mikolajz@google.com>.
// This file is part of gold.
class Incremental_binary;
class Incremental_library;
class Object;
-class Script_info;
// Incremental input type as stored in .gnu_incremental_inputs.
static const int INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT = 30;
+// Return TRUE if a section of type SH_TYPE can be updated in place
+// during an incremental update.
+bool
+can_incremental_update(unsigned int sh_type);
+
// Create an Incremental_binary object for FILE. Returns NULL is this is not
// possible, e.g. FILE is not an ELF file or has an unsupported target.
{
public:
Script_info(const std::string& filename)
- : filename_(filename), incremental_script_entry_(NULL)
+ : filename_(filename), input_file_index_(0),
+ incremental_script_entry_(NULL)
+ { }
+
+ Script_info(const std::string& filename, unsigned int input_file_index)
+ : filename_(filename), input_file_index_(input_file_index),
+ incremental_script_entry_(NULL)
{ }
// Store a pointer to the incremental information for this script.
filename() const
{ return this->filename_; }
+ // Return the input file index.
+ unsigned int
+ input_file_index() const
+ { return this->input_file_index_; }
+
// Return the pointer to the incremental information for this script.
Incremental_script_entry*
incremental_info() const
private:
const std::string filename_;
+ unsigned int input_file_index_;
Incremental_script_entry* incremental_script_entry_;
};
{
public:
Incremental_script_entry(Stringpool::Key filename_key,
- unsigned int arg_serial, Script_info* script,
+ unsigned int arg_serial, Script_info* /*script*/,
Timespec mtime)
: Incremental_input_entry(filename_key, arg_serial, mtime),
- script_(script), objects_()
+ objects_()
{ }
// Add a member object to the archive.
{ return this; }
private:
- // Information about the script file.
- Script_info* script_;
// Objects that have been included by this script.
std::vector<Incremental_input_entry*> objects_;
};
typedef elfcpp::Swap<64, big_endian> Swap64;
public:
+ // Size of the .gnu_incremental_inputs header.
+ // (3 x 4-byte fields, plus 4 bytes padding.)
+ static const unsigned int header_size = 16;
+ // Size of an input file entry.
+ // (2 x 4-byte fields, 1 x 12-byte field, 2 x 2-byte fields.)
+ static const unsigned int input_entry_size = 24;
+ // Size of the first part of the supplemental info block for
+ // relocatable objects and archive members.
+ // (7 x 4-byte fields, plus 4 bytes padding.)
+ static const unsigned int object_info_size = 32;
+ // Size of an input section entry.
+ // (2 x 4-byte fields, 2 x address-sized fields.)
+ static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
+ // Size of a global symbol entry in the supplemental info block.
+ // (5 x 4-byte fields.)
+ static const unsigned int global_sym_entry_size = 20;
+
Incremental_inputs_reader()
: p_(NULL), strtab_(NULL, 0), input_file_count_(0)
{ }
// Reader class for an input file entry and its supplemental info.
class Incremental_input_entry_reader
{
+ private:
+ static const unsigned int object_info_size =
+ Incremental_inputs_reader<size, big_endian>::object_info_size;
+ static const unsigned int input_section_entry_size =
+ Incremental_inputs_reader<size, big_endian>::input_section_entry_size;
+ static const unsigned int global_sym_entry_size =
+ Incremental_inputs_reader<size, big_endian>::global_sym_entry_size;
+
public:
Incremental_input_entry_reader(const Incremental_inputs_reader* inputs,
unsigned int offset)
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
unsigned int section_count = this->get_input_section_count();
- return (this->info_offset_ + 28
- + section_count * input_section_entry_size
- + symndx * 20);
+ return (this->info_offset_
+ + this->object_info_size
+ + section_count * this->input_section_entry_size
+ + symndx * this->global_sym_entry_size);
}
// Return the global symbol count -- for objects & shared libraries only.
{
Input_section_info info;
const unsigned char* p = (this->inputs_->p_
- + this->info_offset_ + 28
- + n * input_section_entry_size);
+ + this->info_offset_
+ + this->object_info_size
+ + n * this->input_section_entry_size);
unsigned int name_offset = Swap32::readval(p);
info.name = this->inputs_->get_string(name_offset);
info.output_shndx = Swap32::readval(p + 4);
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
unsigned int section_count = this->get_input_section_count();
const unsigned char* p = (this->inputs_->p_
- + this->info_offset_ + 28
- + section_count * input_section_entry_size
- + n * 20);
+ + this->info_offset_
+ + this->object_info_size
+ + section_count * this->input_section_entry_size
+ + n * this->global_sym_entry_size);
return Incremental_global_symbol_reader<big_endian>(p);
}
unsigned int section_count = this->get_input_section_count();
unsigned int symbol_count = this->get_global_symbol_count();
const unsigned char* p = (this->inputs_->p_
- + this->info_offset_ + 28
- + section_count * input_section_entry_size
- + symbol_count * 20
+ + this->info_offset_
+ + this->object_info_size
+ + section_count * this->input_section_entry_size
+ + symbol_count * this->global_sym_entry_size
+ n * 4);
unsigned int name_offset = Swap32::readval(p);
return this->inputs_->get_string(name_offset);
}
private:
- // Size of an input section entry.
- static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
// The reader instance for the containing section.
const Incremental_inputs_reader* inputs_;
// The flags, including the type of input file.
input_file_offset(unsigned int n) const
{
gold_assert(n < this->input_file_count_);
- return 16 + n * 24;
+ return this->header_size + n * this->input_entry_size;
}
// Return the index of an input file entry given its OFFSET.
unsigned int
input_file_index(unsigned int offset) const
{
- int n = (offset - 16) / 24;
+ int n = ((offset - this->header_size) / this->input_entry_size);
gold_assert(input_file_offset(n) == offset);
return n;
}
Incremental_input_entry_reader
input_file_at_offset(unsigned int offset) const
{
- gold_assert(offset < 16 + this->input_file_count_ * 24);
+ gold_assert(offset < (this->header_size
+ + this->input_file_count_ * this->input_entry_size));
return Incremental_input_entry_reader(this, offset);
}
class Incremental_binary
{
public:
- Incremental_binary(Output_file* output, Target* target)
+ Incremental_binary(Output_file* output, Target* /*target*/)
: input_args_map_(), library_map_(), script_map_(),
- output_(output), target_(target)
+ output_(output)
{ }
virtual
Input_reader()
{ }
+ Input_reader(const Input_reader&)
+ { }
+
virtual
~Input_reader()
{ }
// Return an Incremental_library for the given input file.
Incremental_library*
- get_library(unsigned int n)
+ get_library(unsigned int n) const
{ return this->library_map_[n]; }
// Return a Script_info for the given input file.
Script_info*
- get_script_info(unsigned int n)
+ get_script_info(unsigned int n) const
{ return this->script_map_[n]; }
// Initialize the layout of the output file based on the existing
private:
// Edited output file object.
Output_file* output_;
- // Target of the output file.
- Target* target_;
};
template<int size, bool big_endian>
: Input_reader(), reader_(r)
{ }
+ Sized_input_reader(const Sized_input_reader& r)
+ : Input_reader(), reader_(r.reader_)
+ { }
+
virtual
~Sized_input_reader()
{ }
// Get the name of a section.
std::string
- do_section_name(unsigned int shndx);
+ do_section_name(unsigned int shndx) const;
// Return a view of the contents of a section.
- Object::Location
- do_section_contents(unsigned int shndx);
+ const unsigned char*
+ do_section_contents(unsigned int shndx, section_size_type* plen,
+ bool cache);
// Return section flags.
uint64_t
do_get_global_symbols() const
{ return &this->symbols_; }
+ // Return the value of a local symbol.
+ uint64_t
+ do_local_symbol_value(unsigned int, uint64_t) const
+ { gold_unreachable(); }
+
+ unsigned int
+ do_local_plt_offset(unsigned int) const
+ { gold_unreachable(); }
+
+ bool
+ do_local_is_tls(unsigned int) const
+ { gold_unreachable(); }
+
// Return the number of local symbols.
unsigned int
do_local_symbol_count() const
unsigned int local_dynsym_offset_;
// The entries in the symbol table for the external symbols.
Symbols symbols_;
+ // Number of symbols defined in object file itself.
+ size_t defined_count_;
// The offset of the first incremental relocation for this object.
unsigned int incr_reloc_offset_;
// The number of incremental relocations for this object.
// Get the name of a section.
std::string
- do_section_name(unsigned int shndx);
+ do_section_name(unsigned int shndx) const;
// Return a view of the contents of a section.
- Object::Location
- do_section_contents(unsigned int shndx);
+ const unsigned char*
+ do_section_contents(unsigned int shndx, section_size_type* plen,
+ bool cache);
// Return section flags.
uint64_t
Input_entry_reader input_reader_;
// The entries in the symbol table for the external symbols.
Symbols symbols_;
+ // Number of symbols defined in object file itself.
+ size_t defined_count_;
};
// Allocate an incremental object of the appropriate size and endianness.