+ Mapfile* mapfile_;
+};
+
+// This class holds information about the comdat group or
+// .gnu.linkonce section that will be kept for a given signature.
+
+class Kept_section
+{
+ private:
+ // For a comdat group, we build a mapping from the name of each
+ // section in the group to the section index and the size in object.
+ // When we discard a group in some other object file, we use this
+ // map to figure out which kept section the discarded section is
+ // associated with. We then use that mapping when processing relocs
+ // against discarded sections.
+ struct Comdat_section_info
+ {
+ // The section index.
+ unsigned int shndx;
+ // The section size.
+ uint64_t size;
+
+ Comdat_section_info(unsigned int a_shndx, uint64_t a_size)
+ : shndx(a_shndx), size(a_size)
+ { }
+ };
+
+ // Most comdat groups have only one or two sections, so we use a
+ // std::map rather than an Unordered_map to optimize for that case
+ // without paying too heavily for groups with more sections.
+ typedef std::map<std::string, Comdat_section_info> Comdat_group;
+
+ public:
+ Kept_section()
+ : object_(NULL), shndx_(0), is_comdat_(false), is_group_name_(false)
+ { this->u_.linkonce_size = 0; }
+
+ // We need to support copies for the signature map in the Layout
+ // object, but we should never copy an object after it has been
+ // marked as a comdat section.
+ Kept_section(const Kept_section& k)
+ : object_(k.object_), shndx_(k.shndx_), is_comdat_(false),
+ is_group_name_(k.is_group_name_)
+ {
+ gold_assert(!k.is_comdat_);
+ this->u_.linkonce_size = 0;
+ }
+
+ ~Kept_section()
+ {
+ if (this->is_comdat_)
+ delete this->u_.group_sections;
+ }
+
+ // The object where this section lives.
+ Relobj*
+ object() const
+ { return this->object_; }
+
+ // Set the object.
+ void
+ set_object(Relobj* object)
+ {
+ gold_assert(this->object_ == NULL);
+ this->object_ = object;
+ }
+
+ // The section index.
+ unsigned int
+ shndx() const
+ { return this->shndx_; }
+
+ // Set the section index.
+ void
+ set_shndx(unsigned int shndx)
+ {
+ gold_assert(this->shndx_ == 0);
+ this->shndx_ = shndx;
+ }
+
+ // Whether this is a comdat group.
+ bool
+ is_comdat() const
+ { return this->is_comdat_; }
+
+ // Set that this is a comdat group.
+ void
+ set_is_comdat()
+ {
+ gold_assert(!this->is_comdat_);
+ this->is_comdat_ = true;
+ this->u_.group_sections = new Comdat_group();
+ }
+
+ // Whether this is associated with the name of a group or section
+ // rather than the symbol name derived from a linkonce section.
+ bool
+ is_group_name() const
+ { return this->is_group_name_; }
+
+ // Note that this represents a comdat group rather than a single
+ // linkonce section.
+ void
+ set_is_group_name()
+ { this->is_group_name_ = true; }
+
+ // Add a section to the group list.
+ void
+ add_comdat_section(const std::string& name, unsigned int shndx,
+ uint64_t size)
+ {
+ gold_assert(this->is_comdat_);
+ Comdat_section_info sinfo(shndx, size);
+ this->u_.group_sections->insert(std::make_pair(name, sinfo));
+ }
+
+ // 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
+ {
+ gold_assert(this->is_comdat_);
+ Comdat_group::const_iterator p = this->u_.group_sections->find(name);
+ if (p == this->u_.group_sections->end())
+ return false;
+ *pshndx = p->second.shndx;
+ *psize = p->second.size;
+ return true;
+ }
+
+ // 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
+ {
+ gold_assert(this->is_comdat_);
+ if (this->u_.group_sections->size() != 1)
+ return false;
+ Comdat_group::const_iterator p = this->u_.group_sections->begin();
+ *pshndx = p->second.shndx;
+ *psize = p->second.size;
+ return true;
+ }
+
+ // Return the size of a linkonce section.
+ uint64_t
+ linkonce_size() const
+ {
+ gold_assert(!this->is_comdat_);
+ return this->u_.linkonce_size;
+ }
+
+ // Set the size of a linkonce section.
+ void
+ set_linkonce_size(uint64_t size)
+ {
+ gold_assert(!this->is_comdat_);
+ this->u_.linkonce_size = size;
+ }
+
+ private:
+ // No assignment.
+ Kept_section& operator=(const Kept_section&);
+
+ // The object containing the comdat group or .gnu.linkonce section.
+ Relobj* object_;
+ // Index of the group section for comdats and the section itself for
+ // .gnu.linkonce.
+ unsigned int shndx_;
+ // True if this is for a comdat group rather than a .gnu.linkonce
+ // section.
+ bool is_comdat_;
+ // The Kept_sections are values of a mapping, that maps names to
+ // them. This field is true if this struct is associated with the
+ // name of a comdat or .gnu.linkonce, false if it is associated with
+ // the name of a symbol obtained from the .gnu.linkonce.* name
+ // through some heuristics.
+ bool is_group_name_;
+ union
+ {
+ // If the is_comdat_ field is true, this holds a map from names of
+ // the sections in the group to section indexes in object_ and to
+ // section sizes.
+ Comdat_group* group_sections;
+ // If the is_comdat_ field is false, this holds the size of the
+ // single section.
+ uint64_t linkonce_size;
+ } u_;
+};
+
+// The ordering for output sections. This controls how output
+// sections are ordered within a PT_LOAD output segment.
+
+enum Output_section_order
+{
+ // Unspecified. Used for non-load segments. Also used for the file
+ // and segment headers.
+ ORDER_INVALID,
+
+ // The PT_INTERP section should come first, so that the dynamic
+ // linker can pick it up quickly.
+ ORDER_INTERP,
+
+ // Loadable read-only note sections come next so that the PT_NOTE
+ // segment is on the first page of the executable.
+ ORDER_RO_NOTE,
+
+ // Put read-only sections used by the dynamic linker early in the
+ // executable to minimize paging.
+ ORDER_DYNAMIC_LINKER,
+
+ // Put reloc sections used by the dynamic linker after other
+ // sections used by the dynamic linker; otherwise, objcopy and strip
+ // get confused.
+ ORDER_DYNAMIC_RELOCS,
+
+ // Put the PLT reloc section after the other dynamic relocs;
+ // otherwise, prelink gets confused.
+ ORDER_DYNAMIC_PLT_RELOCS,
+
+ // The .init section.
+ ORDER_INIT,
+
+ // The PLT.
+ ORDER_PLT,
+
+ // The hot text sections, prefixed by .text.hot.
+ ORDER_TEXT_HOT,
+
+ // The regular text sections.
+ ORDER_TEXT,
+
+ // The startup text sections, prefixed by .text.startup.
+ ORDER_TEXT_STARTUP,
+
+ // The startup text sections, prefixed by .text.startup.
+ ORDER_TEXT_EXIT,
+
+ // The unlikely text sections, prefixed by .text.unlikely.
+ ORDER_TEXT_UNLIKELY,
+
+ // The .fini section.
+ ORDER_FINI,
+
+ // The read-only sections.
+ ORDER_READONLY,
+
+ // The exception frame sections.
+ ORDER_EHFRAME,
+
+ // The TLS sections come first in the data section.
+ ORDER_TLS_DATA,
+ ORDER_TLS_BSS,
+
+ // Local RELRO (read-only after relocation) sections come before
+ // non-local RELRO sections. This data will be fully resolved by
+ // the prelinker.
+ ORDER_RELRO_LOCAL,
+
+ // Non-local RELRO sections are grouped together after local RELRO
+ // sections. All RELRO sections must be adjacent so that they can
+ // all be put into a PT_GNU_RELRO segment.
+ ORDER_RELRO,
+
+ // We permit marking exactly one output section as the last RELRO
+ // section. We do this so that the read-only GOT can be adjacent to
+ // the writable GOT.
+ ORDER_RELRO_LAST,
+
+ // Similarly, we permit marking exactly one output section as the
+ // first non-RELRO section.
+ ORDER_NON_RELRO_FIRST,
+
+ // The regular data sections come after the RELRO sections.
+ ORDER_DATA,
+
+ // Large data sections normally go in large data segments.
+ ORDER_LARGE_DATA,
+
+ // Group writable notes so that we can have a single PT_NOTE
+ // segment.
+ ORDER_RW_NOTE,
+
+ // The small data sections must be at the end of the data sections,
+ // so that they can be adjacent to the small BSS sections.
+ ORDER_SMALL_DATA,
+
+ // The BSS sections start here.
+
+ // The small BSS sections must be at the start of the BSS sections,
+ // so that they can be adjacent to the small data sections.
+ ORDER_SMALL_BSS,
+
+ // The regular BSS sections.
+ ORDER_BSS,
+
+ // The large BSS sections come after the other BSS sections.
+ ORDER_LARGE_BSS,
+
+ // Maximum value.
+ ORDER_MAX