class General_options;
class Incremental_inputs;
+class Incremental_binary;
class Input_objects;
class Mapfile;
class Symbol_table;
extern bool
is_compressed_debug_section(const char* secname);
+// Maintain a list of free space within a section, segment, or file.
+// Used for incremental update links.
+
+class Free_list
+{
+ public:
+ Free_list()
+ : list_(), last_remove_(list_.begin()), extend_(false), length_(0)
+ { }
+
+ void
+ init(off_t len, bool extend);
+
+ void
+ remove(off_t start, off_t end);
+
+ off_t
+ allocate(off_t len, uint64_t align, off_t minoff);
+
+ void
+ dump();
+
+ static void
+ print_stats();
+
+ private:
+ struct Free_list_node
+ {
+ Free_list_node(off_t start, off_t end)
+ : start_(start), end_(end)
+ { }
+ off_t start_;
+ off_t end_;
+ };
+ typedef std::list<Free_list_node>::iterator Iterator;
+
+ // The free list.
+ std::list<Free_list_node> list_;
+
+ // The last node visited during a remove operation.
+ Iterator last_remove_;
+
+ // Whether we can extend past the original length.
+ bool extend_;
+
+ // The total length of the section, segment, or file.
+ off_t length_;
+
+ // Statistics:
+ // The total number of free lists used.
+ static unsigned int num_lists;
+ // The total number of free list nodes used.
+ static unsigned int num_nodes;
+ // The total number of calls to Free_list::remove.
+ static unsigned int num_removes;
+ // The total number of nodes visited during calls to Free_list::remove.
+ static unsigned int num_remove_visits;
+ // The total number of calls to Free_list::allocate.
+ static unsigned int num_allocates;
+ // The total number of nodes visited during calls to Free_list::allocate.
+ static unsigned int num_allocate_visits;
+};
+
// This task function handles mapping the input sections to output
// sections and laying them out in memory.
// Look for a section name in the group list, and return whether it
// was found. If found, returns the section index and size.
bool
- find_comdat_section(const std::string& name, unsigned int *pshndx,
- uint64_t *psize) const
+ find_comdat_section(const std::string& name, unsigned int* pshndx,
+ uint64_t* psize) const
{
gold_assert(this->is_comdat_);
Comdat_group::const_iterator p = this->u_.group_sections->find(name);
// If there is only one section in the group list, return true, and
// return the section index and size.
bool
- find_single_comdat_section(unsigned int *pshndx, uint64_t *psize) const
+ find_single_comdat_section(unsigned int* pshndx, uint64_t* psize) const
{
gold_assert(this->is_comdat_);
if (this->u_.group_sections->size() != 1)
delete this->segment_states_;
}
+ // For incremental links, record the base file to be modified.
+ void
+ set_incremental_base(Incremental_binary* base);
+
+ Incremental_binary*
+ incremental_base()
+ { return this->incremental_base_; }
+
+ // For incremental links, record the initial fixed layout of a section
+ // from the base file, and return a pointer to the Output_section.
+ template<int size, bool big_endian>
+ Output_section*
+ init_fixed_output_section(const char*, elfcpp::Shdr<size, big_endian>&);
+
// Given an input section SHNDX, named NAME, with data in SHDR, from
// the object file OBJECT, return the output section where this
// input section should go. RELOC_SHNDX is the index of a
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
+ // For incremental updates, allocate a block of memory from the
+ // free list. Find a block starting at or after MINOFF.
+ off_t
+ allocate(off_t len, uint64_t align, off_t minoff)
+ { return this->free_list_.allocate(len, align, minoff); }
+
unsigned int
find_section_order_index(const std::string&);
// .note.GNU-stack section. GNU_STACK_FLAGS is the section flags
// from that section if there was one.
void
- layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags);
+ layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags,
+ const Object*);
// Add an Output_section_data to the layout. This is used for
// special sections like the GOT section. ORDER is where the
return this->symtab_section_;
}
+ // Return the file offset of the normal symbol table.
+ off_t
+ symtab_section_offset() const;
+
// Return the dynamic symbol table.
Output_section*
dynsym_section() const
// Create a note section, filling in the header.
Output_section*
- create_note(const char* name, int note_type, const char *section_name,
+ create_note(const char* name, int note_type, const char* section_name,
size_t descsz, bool allocate, size_t* trailing_padding);
// Create a note section for gold version.
Incremental_inputs* incremental_inputs_;
// Whether we record output section data created in script
bool record_output_section_data_from_script_;
- // List of output data that needs to be removed at relexation clean up.
+ // List of output data that needs to be removed at relaxation clean up.
Output_section_data_list script_output_section_data_list_;
// Structure to save segment states before entering the relaxation loop.
Segment_states* segment_states_;
Unordered_map<std::string, unsigned int> input_section_position_;
// Vector of glob only patterns in the section_ordering file.
std::vector<std::string> input_section_glob_;
+ // For incremental links, the base file to be modified.
+ Incremental_binary* incremental_base_;
+ // For incremental links, a list of free space within the file.
+ Free_list free_list_;
};
// This task handles writing out data in output sections which is not