class Free_list
{
public:
+ 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>::const_iterator Const_iterator;
+
Free_list()
- : list_(), last_remove_(list_.begin()), extend_(false), length_(0)
+ : list_(), last_remove_(list_.begin()), extend_(false), length_(0),
+ min_hole_(0)
{ }
+ // Initialize the free list for a section of length LEN.
+ // If EXTEND is true, free space may be allocated past the end.
void
init(off_t len, bool extend);
+ // Set the minimum hole size that is allowed when allocating
+ // from the free list.
+ void
+ set_min_hole_size(off_t min_hole)
+ { this->min_hole_ = min_hole; }
+
+ // Remove a chunk from the free list.
void
remove(off_t start, off_t end);
+ // Allocate a chunk of space from the free list of length LEN,
+ // with alignment ALIGN, and minimum offset MINOFF.
off_t
allocate(off_t len, uint64_t align, off_t minoff);
+ // Return an iterator for the beginning of the free list.
+ Const_iterator
+ begin() const
+ { return this->list_.begin(); }
+
+ // Return an iterator for the end of the free list.
+ Const_iterator
+ end() const
+ { return this->list_.end(); }
+
+ // Dump the free list (for debugging).
void
dump();
+ // Print usage statistics.
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.
// The total length of the section, segment, or file.
off_t length_;
+ // The minimum hole size allowed. When allocating from the free list,
+ // we must not leave a hole smaller than this.
+ off_t min_hole_;
+
// Statistics:
// The total number of free lists used.
static unsigned int num_lists;
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
+ std::map<Section_id, unsigned int>*
+ get_section_order_map()
+ { return &this->section_order_map_; }
+
+ bool
+ is_section_ordering_specified()
+ { return this->section_ordering_specified_; }
+
+ void
+ set_section_ordering_specified()
+ { this->section_ordering_specified_ = true; }
+
// For incremental updates, allocate a block of memory from the
// free list. Find a block starting at or after MINOFF.
off_t
unsigned int
find_section_order_index(const std::string&);
+ // Read the sequence of input sections from the file specified with
+ // linker option --section-ordering-file.
void
read_layout_from_file();
dynpool() const
{ return &this->dynpool_; }
+ // Return the .dynamic output section. This is only valid after the
+ // layout has been finalized.
+ Output_section*
+ dynamic_section() const
+ { return this->dynamic_section_; }
+
// Return the symtab_xindex section used to hold large section
// indexes for the normal symbol table.
Output_symtab_xindex*
bool resized_signatures_;
// Whether we have created a .stab*str output section.
bool have_stabstr_section_;
+ // True if the input sections in the output sections should be sorted
+ // as specified in a section ordering file.
+ bool section_ordering_specified_;
// In incremental build, holds information check the inputs and build the
// .gnu_incremental_inputs section.
Incremental_inputs* incremental_inputs_;
Segment_states* segment_states_;
// A relaxation debug checker. We only create one when in debugging mode.
Relaxation_debug_check* relaxation_debug_check_;
+ // Plugins specify section_ordering using this map. This is set in
+ // update_section_order in plugin.cc
+ std::map<Section_id, unsigned int> section_order_map_;
// Hash a pattern to its position in the section ordering file.
Unordered_map<std::string, unsigned int> input_section_position_;
// Vector of glob only patterns in the section_ordering file.