gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gold / layout.h
index 13fafd60705784e1657252ea2bae15f3d4ae8b1c..fd5878da18bc7d97e2c763f7263bac209d66e83a 100644 (file)
@@ -1,6 +1,6 @@
 // layout.h -- lay out output file sections for gold  -*- C++ -*-
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright (C) 2006-2020 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -23,7 +23,9 @@
 #ifndef GOLD_LAYOUT_H
 #define GOLD_LAYOUT_H
 
+#include <cstring>
 #include <list>
+#include <map>
 #include <string>
 #include <utility>
 #include <vector>
@@ -38,16 +40,128 @@ namespace gold
 {
 
 class General_options;
+class Incremental_inputs;
+class Incremental_binary;
 class Input_objects;
+class Mapfile;
 class Symbol_table;
 class Output_section_data;
 class Output_section;
 class Output_section_headers;
+class Output_segment_headers;
+class Output_file_header;
 class Output_segment;
 class Output_data;
+class Output_data_reloc_generic;
 class Output_data_dynamic;
+class Output_symtab_xindex;
+class Output_reduced_debug_abbrev_section;
+class Output_reduced_debug_info_section;
 class Eh_frame;
+class Gdb_index;
 class Target;
+struct Timespec;
+
+// Return TRUE if SECNAME is the name of a compressed debug section.
+extern bool
+is_compressed_debug_section(const char* secname);
+
+// Return the name of the corresponding uncompressed debug section.
+extern std::string
+corresponding_uncompressed_section_name(std::string secname);
+
+// Maintain a list of free space within a section, segment, or file.
+// Used for incremental update links.
+
+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),
+      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:
+  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_;
+
+  // 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;
+  // 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.
@@ -61,10 +175,11 @@ class Layout_task_runner : public Task_function_runner
   Layout_task_runner(const General_options& options,
                     const Input_objects* input_objects,
                     Symbol_table* symtab,
-                     Target* target,
-                    Layout* layout)
+                    Target* target,
+                    Layout* layout,
+                    Mapfile* mapfile)
     : options_(options), input_objects_(input_objects), symtab_(symtab),
-      target_(target), layout_(layout)
+      target_(target), layout_(layout), mapfile_(mapfile)
   { }
 
   // Run the operation.
@@ -80,6 +195,308 @@ class Layout_task_runner : public Task_function_runner
   Symbol_table* symtab_;
   Target* target_;
   Layout* layout_;
+  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
 };
 
 // This class handles the details of laying out input sections.
@@ -87,7 +504,27 @@ class Layout_task_runner : public Task_function_runner
 class Layout
 {
  public:
-  Layout(const General_options& options, Script_options*);
+  Layout(int number_of_input_files, Script_options*);
+
+  ~Layout()
+  {
+    delete this->relaxation_debug_check_;
+    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
@@ -98,9 +535,85 @@ class Layout
   // within the output section.
   template<int size, bool big_endian>
   Output_section*
-  layout(Sized_relobj<size, big_endian> *object, unsigned int shndx,
+  layout(Sized_relobj_file<size, big_endian> *object, unsigned int shndx,
         const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
-        unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
+        unsigned int sh_type, 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_; }
+
+  // Struct to store segment info when mapping some input sections to
+  // unique segments using linker plugins.  Mapping an input section to
+  // a unique segment is done by first placing such input sections in
+  // unique output sections and then mapping the output section to a
+  // unique segment.  NAME is the name of the output section.  FLAGS
+  // and ALIGN are the extra flags and alignment of the segment.
+  struct Unique_segment_info
+  {
+    // Identifier for the segment.  ELF segments don't have names.  This
+    // is used as the name of the output section mapped to the segment.
+    const char* name;
+    // Additional segment flags.
+    uint64_t flags;
+    // Segment alignment.
+    uint64_t align;
+  };
+
+  // Mapping from input section to segment.
+  typedef std::map<Const_section_id, Unique_segment_info*>
+  Section_segment_map;
+
+  // Maps section SECN to SEGMENT s.
+  void
+  insert_section_segment_map(Const_section_id secn, Unique_segment_info *s);
+
+  // Some input sections require special ordering, for compatibility
+  // with GNU ld.  Given the name of an input section, return -1 if it
+  // does not require special ordering.  Otherwise, return the index
+  // by which it should be ordered compared to other input sections
+  // that require special ordering.
+  static int
+  special_ordering_of_input_section(const char* name);
+
+  bool
+  is_section_ordering_specified()
+  { return this->section_ordering_specified_; }
+
+  void
+  set_section_ordering_specified()
+  { this->section_ordering_specified_ = true; }
+
+  bool
+  is_unique_segment_for_sections_specified() const
+  { return this->unique_segment_for_sections_specified_; }
+
+  void
+  set_unique_segment_for_sections_specified()
+  { this->unique_segment_for_sections_specified_ = true; }
+
+  bool
+  is_lto_slim_object () const
+  { return this->lto_slim_object_; }
+
+  void
+  set_lto_slim_object ()
+  { this->lto_slim_object_ = true; }
+
+  // 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&);
+
+  // Read the sequence of input sections from the file specified with
+  // linker option --section-ordering-file.
+  void
+  read_layout_from_file();
 
   // Layout an input reloc section when doing a relocatable link.  The
   // section is RELOC_SHNDX in OBJECT, with data in SHDR.
@@ -108,7 +621,7 @@ class Layout
   // relocatable information.
   template<int size, bool big_endian>
   Output_section*
-  layout_reloc(Sized_relobj<size, big_endian>* object,
+  layout_reloc(Sized_relobj_file<size, big_endian>* object,
               unsigned int reloc_shndx,
               const elfcpp::Shdr<size, big_endian>& shdr,
               Output_section* data_section,
@@ -118,12 +631,13 @@ class Layout
   template<int size, bool big_endian>
   void
   layout_group(Symbol_table* symtab,
-              Sized_relobj<size, big_endian>* object,
+              Sized_relobj_file<size, big_endian>* object,
               unsigned int group_shndx,
               const char* group_section_name,
               const char* signature,
               const elfcpp::Shdr<size, big_endian>& shdr,
-              const elfcpp::Elf_Word* contents);
+              elfcpp::Elf_Word flags,
+              std::vector<unsigned int>* shndxes);
 
   // Like layout, only for exception frame sections.  OBJECT is an
   // object file.  SYMBOLS is the contents of the symbol table
@@ -136,7 +650,7 @@ class Layout
   // returns the output section, and sets *OFFSET to the offset.
   template<int size, bool big_endian>
   Output_section*
-  layout_eh_frame(Sized_relobj<size, big_endian>* object,
+  layout_eh_frame(Sized_relobj_file<size, big_endian>* object,
                  const unsigned char* symbols,
                  off_t symbols_size,
                  const unsigned char* symbol_names,
@@ -146,19 +660,78 @@ class Layout
                  unsigned int reloc_shndx, unsigned int reloc_type,
                  off_t* offset);
 
+  // After processing all input files, we call this to make sure that
+  // the optimized .eh_frame sections have been added to the output
+  // section.
+  void
+  finalize_eh_frame_section();
+
+  // Add .eh_frame information for a PLT.  The FDE must start with a
+  // 4-byte PC-relative reference to the start of the PLT, followed by
+  // a 4-byte size of PLT.
+  void
+  add_eh_frame_for_plt(Output_data* plt, const unsigned char* cie_data,
+                      size_t cie_length, const unsigned char* fde_data,
+                      size_t fde_length);
+
+  // Remove all post-map .eh_frame information for a PLT.
+  void
+  remove_eh_frame_for_plt(Output_data* plt, const unsigned char* cie_data,
+                         size_t cie_length);
+
+  // Scan a .debug_info or .debug_types section, and add summary
+  // information to the .gdb_index section.
+  template<int size, bool big_endian>
+  void
+  add_to_gdb_index(bool is_type_unit,
+                  Sized_relobj<size, big_endian>* object,
+                  const unsigned char* symbols,
+                  off_t symbols_size,
+                  unsigned int shndx,
+                  unsigned int reloc_shndx,
+                  unsigned int reloc_type);
+
   // Handle a GNU stack note.  This is called once per input object
   // file.  SEEN_GNU_STACK is true if the object file has a
   // .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.
+  // Layout a .note.gnu.property section.
+  void
+  layout_gnu_property(unsigned int note_type,
+                     unsigned int pr_type,
+                     size_t pr_datasz,
+                     const unsigned char* pr_data,
+                     const Object* object);
+
+  // Merge per-object properties with program properties.
+  void
+  merge_gnu_properties(const Object* object);
+
+  // Add a target-specific property for the output .note.gnu.property section.
   void
+  add_gnu_property(unsigned int note_type,
+                  unsigned int pr_type,
+                  size_t pr_datasz,
+                  const unsigned char* pr_data);
+
+  // Add an Output_section_data to the layout.  This is used for
+  // special sections like the GOT section.  ORDER is where the
+  // section should wind up in the output segment.  IS_RELRO is true
+  // for relro sections.
+  Output_section*
   add_output_section_data(const char* name, elfcpp::Elf_Word type,
                          elfcpp::Elf_Xword flags,
-                         Output_section_data*);
+                         Output_section_data*, Output_section_order order,
+                         bool is_relro);
+
+  // Increase the size of the relro segment by this much.
+  void
+  increase_relro(unsigned int s)
+  { this->increase_relro_ += s; }
 
   // Create dynamic sections if necessary.
   void
@@ -168,6 +741,10 @@ class Layout
   void
   define_section_symbols(Symbol_table*);
 
+  // Create automatic note sections.
+  void
+  create_notes();
+
   // Create sections for linker scripts.
   void
   create_script_sections()
@@ -193,18 +770,72 @@ class Layout
   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*
+  symtab_xindex() const
+  { return this->symtab_xindex_; }
+
+  // Return the dynsym_xindex section used to hold large section
+  // indexes for the dynamic symbol table.
+  Output_symtab_xindex*
+  dynsym_xindex() const
+  { return this->dynsym_xindex_; }
+
   // Return whether a section is a .gnu.linkonce section, given the
   // section name.
   static inline bool
   is_linkonce(const char* name)
   { return strncmp(name, ".gnu.linkonce", sizeof(".gnu.linkonce") - 1) == 0; }
 
-  // Record the signature of a comdat section, and return whether to
-  // include it in the link.  The GROUP parameter is true for a
-  // section group signature, false for a signature derived from a
-  // .gnu.linkonce section.
+  // Whether we have added an input section.
+  bool
+  have_added_input_section() const
+  { return this->have_added_input_section_; }
+
+  // Return true if a section is a debugging section.
+  static inline bool
+  is_debug_info_section(const char* name)
+  {
+    // Debugging sections can only be recognized by name.
+    return (strncmp(name, ".debug", sizeof(".debug") - 1) == 0
+           || strncmp(name, ".zdebug", sizeof(".zdebug") - 1) == 0
+           || strncmp(name, ".gnu.linkonce.wi.",
+                      sizeof(".gnu.linkonce.wi.") - 1) == 0
+           || strncmp(name, ".line", sizeof(".line") - 1) == 0
+           || strncmp(name, ".stab", sizeof(".stab") - 1) == 0
+           || strncmp(name, ".pdr", sizeof(".pdr") - 1) == 0);
+  }
+
+  // Return true if RELOBJ is an input file whose base name matches
+  // FILE_NAME.  The base name must have an extension of ".o", and
+  // must be exactly FILE_NAME.o or FILE_NAME, one character, ".o".
+  static bool
+  match_file_name(const Relobj* relobj, const char* file_name);
+
+  // Return whether section SHNDX in RELOBJ is a .ctors/.dtors section
+  // with more than one word being mapped to a .init_array/.fini_array
+  // section.
+  bool
+  is_ctors_in_init_array(Relobj* relobj, unsigned int shndx) const;
+
+  // Check if a comdat group or .gnu.linkonce section with the given
+  // NAME is selected for the link.  If there is already a section,
+  // *KEPT_SECTION is set to point to the signature and the function
+  // returns false.  Otherwise, OBJECT, SHNDX,IS_COMDAT, and
+  // IS_GROUP_NAME are recorded for this NAME in the layout object,
+  // *KEPT_SECTION is set to the internal copy and the function return
+  // false.
   bool
-  add_comdat(const char*, bool group);
+  find_or_add_kept_section(const std::string& name, Relobj* object,
+                          unsigned int shndx, bool is_comdat,
+                          bool is_group_name, Kept_section** kept_section);
 
   // Finalize the layout after all the input sections have been added.
   off_t
@@ -234,6 +865,14 @@ class Layout
     return this->symtab_section_;
   }
 
+  // Return the file offset of the normal symbol table.
+  off_t
+  symtab_section_offset() const;
+
+  // Return the section index of the normal symbol tabl.e
+  unsigned int
+  symtab_section_shndx() const;
+
   // Return the dynamic symbol table.
   Output_section*
   dynsym_section() const
@@ -294,14 +933,36 @@ class Layout
   script_options() const
   { return this->script_options_; }
 
+  // Return the object managing inputs in incremental build. NULL in
+  // non-incremental builds.
+  Incremental_inputs*
+  incremental_inputs() const
+  { return this->incremental_inputs_; }
+
+  // For the target-specific code to add dynamic tags which are common
+  // to most targets.
+  void
+  add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
+                         const Output_data* plt_rel,
+                         const Output_data_reloc_generic* dyn_rel,
+                         bool add_debug, bool dynrel_includes_plt);
+
+  // Add a target-specific dynamic tag with constant value.
+  void
+  add_target_specific_dynamic_tag(elfcpp::DT tag, unsigned int val);
+
   // Compute and write out the build ID if needed.
   void
-  write_build_id(Output_file*) const;
+  write_build_id(Output_file*, unsigned char*, size_t) const;
 
   // Rewrite output file in binary format.
   void
   write_binary(Output_file* in) const;
 
+  // Print output sections to the map file.
+  void
+  print_to_mapfile(Mapfile*) const;
+
   // Dump statistical information to stderr.
   void
   print_stats() const;
@@ -323,9 +984,14 @@ class Layout
   void
   get_allocated_sections(Section_list*) const;
 
+  // Store the executable sections into the section list.
+  void
+  get_executable_sections(Section_list*) const;
+
   // Make a section for a linker script to hold data.
   Output_section*
-  make_output_section_for_script(const char* name);
+  make_output_section_for_script(const char* name,
+                                Script_sections::Section_type section_type);
 
   // Make a segment.  This is used by the linker script code.
   Output_segment*
@@ -342,22 +1008,59 @@ class Layout
 
   // Attach sections to segments.
   void
-  attach_sections_to_segments();
+  attach_sections_to_segments(const Target*);
+
+  // For relaxation clean up, we need to know output section data created
+  // from a linker script.
+  void
+  new_output_section_data_from_script(Output_section_data* posd)
+  {
+    if (this->record_output_section_data_from_script_)
+      this->script_output_section_data_list_.push_back(posd);
+  }
+
+  // Return section list.
+  const Section_list&
+  section_list() const
+  { return this->section_list_; }
+
+  // Returns TRUE iff NAME (an input section from RELOBJ) will
+  // be mapped to an output section that should be KEPT.
+  bool
+  keep_input_section(const Relobj*, const char*);
+
+  // Add a special output object that will be recreated afresh
+  // if there is another relaxation iteration.
+  void
+  add_relax_output(Output_data* data)
+  { this->relax_output_list_.push_back(data); }
+
+  // Clear out (and free) everything added by add_relax_output.
+  void
+  reset_relax_output();
 
  private:
   Layout(const Layout&);
   Layout& operator=(const Layout&);
 
-  // Mapping from .gnu.linkonce section names to output section names.
-  struct Linkonce_mapping
+  // Mapping from input section names to output section names.
+  struct Section_name_mapping
   {
     const char* from;
     int fromlen;
     const char* to;
     int tolen;
   };
-  static const Linkonce_mapping linkonce_mapping[];
-  static const int linkonce_mapping_count;
+  static const Section_name_mapping section_name_mapping[];
+  static const int section_name_mapping_count;
+  static const Section_name_mapping text_section_name_mapping[];
+  static const int text_section_name_mapping_count;
+
+  // Find section name NAME in map and return the mapped name if found
+  // with the length set in PLEN.
+  static const char* match_section_name(const Section_name_mapping* map,
+                                       const int count, const char* name,
+                                       size_t* plen);
 
   // During a relocatable link, a list of group sections and
   // signatures.
@@ -378,27 +1081,40 @@ class Layout
   };
   typedef std::vector<Group_signature> Group_signatures;
 
-  // Create a .note section, filling in the header.
+  // Create a note section, filling in the header.
   Output_section*
-  create_note(const char* name, int note_type, size_t descsz,
-             bool allocate, size_t* trailing_padding);
+  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 gnu program properties.
+  void
+  create_gnu_properties_note();
 
-  // Create a .note section for gold.
+  // Create a note section for gold version.
   void
   create_gold_note();
 
-  // Record whether the stack must be executable.
+  // Record whether the stack must be executable, and a user-supplied size.
   void
-  create_executable_stack_info(const Target*);
+  create_stack_segment();
 
   // Create a build ID note if needed.
   void
   create_build_id();
 
+  // Link .stab and .stabstr sections.
+  void
+  link_stabs_sections();
+
+  // Create .gnu_incremental_inputs and .gnu_incremental_strtab sections needed
+  // for the next run of incremental linking to check what has changed.
+  void
+  create_incremental_info_sections(Symbol_table*);
+
   // Find the first read-only PT_LOAD segment, creating one if
   // necessary.
   Output_segment*
-  find_first_load_seg();
+  find_first_load_seg(const Target*);
 
   // Count the local symbols in the regular symbol table and the dynamic
   // symbol table, and build the respective string pools.
@@ -407,7 +1123,8 @@ class Layout
 
   // Create the output sections for the symbol table.
   void
-  create_symtab_sections(const Input_objects*, Symbol_table*, off_t*);
+  create_symtab_sections(const Input_objects*, Symbol_table*,
+                        unsigned int, off_t*, unsigned int);
 
   // Create the .shstrtab section.
   Output_section*
@@ -415,13 +1132,14 @@ class Layout
 
   // Create the section header table.
   void
-  create_shdrs(off_t*);
+  create_shdrs(const Output_section* shstrtab_section, off_t*);
 
   // Create the dynamic symbol table.
   void
   create_dynamic_symtab(const Input_objects*, Symbol_table*,
                        Output_section** pdynstr,
                        unsigned int* plocal_dynamic_count,
+                       unsigned int* pforced_local_dynamic_count,
                        std::vector<Symbol*>* pdynamic_symbols,
                        Versions* versions);
 
@@ -433,6 +1151,10 @@ class Layout
   void
   finish_dynamic_section(const Input_objects*, const Symbol_table*);
 
+  // Set the size of the _DYNAMIC symbol.
+  void
+  set_dynamic_symbol_size(const Symbol_table*);
+
   // Create the .interp section and PT_INTERP segment.
   void
   create_interp(const Target* target);
@@ -456,43 +1178,58 @@ class Layout
   // Return whether to include this section in the link.
   template<int size, bool big_endian>
   bool
-  include_section(Sized_relobj<size, big_endian>* object, const char* name,
+  include_section(Sized_relobj_file<size, big_endian>* object, const char* name,
                  const elfcpp::Shdr<size, big_endian>&);
 
   // Return the output section name to use given an input section
   // name.  Set *PLEN to the length of the name.  *PLEN must be
   // initialized to the length of NAME.
   static const char*
-  output_section_name(const char* name, size_t* plen);
+  output_section_name(const Relobj*, const char* name, size_t* plen);
 
-  // Return the output section name to use for a linkonce section
-  // name.  PLEN is as for output_section_name.
-  static const char*
-  linkonce_output_name(const char* name, size_t* plen);
+  // Return the number of allocated output sections.
+  size_t
+  allocated_output_section_count() const;
 
   // Return the output section for NAME, TYPE and FLAGS.
   Output_section*
   get_output_section(const char* name, Stringpool::Key name_key,
-                    elfcpp::Elf_Word type, elfcpp::Elf_Xword flags);
+                    elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
+                    Output_section_order order, bool is_relro);
+
+  // Clear the input section flags that should not be copied to the
+  // output section.
+  elfcpp::Elf_Xword
+  get_output_section_flags (elfcpp::Elf_Xword input_section_flags);
 
   // Choose the output section for NAME in RELOBJ.
   Output_section*
   choose_output_section(const Relobj* relobj, const char* name,
                        elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
-                       bool is_input_section);
+                       bool is_input_section, Output_section_order order,
+                       bool is_relro, bool is_reloc, bool match_input_spec);
 
   // Create a new Output_section.
   Output_section*
   make_output_section(const char* name, elfcpp::Elf_Word type,
-                     elfcpp::Elf_Xword flags);
+                     elfcpp::Elf_Xword flags, Output_section_order order,
+                     bool is_relro);
 
   // Attach a section to a segment.
   void
-  attach_section_to_segment(Output_section*);
+  attach_section_to_segment(const Target*, Output_section*);
+
+  // Get section order.
+  Output_section_order
+  default_section_order(Output_section*, bool is_relro_local);
 
   // Attach an allocated section to a segment.
   void
-  attach_allocated_section_to_segment(Output_section*);
+  attach_allocated_section_to_segment(const Target*, Output_section*);
+
+  // Make the .eh_frame section.
+  Output_section*
+  make_eh_frame_section(const Relobj*);
 
   // Set the final file offsets of all the segments.
   off_t
@@ -527,12 +1264,44 @@ class Layout
   Output_segment*
   set_section_addresses_from_script(Symbol_table*);
 
+  // Find appropriate places or orphan sections in a script.
+  void
+  place_orphan_sections_in_script();
+
   // Return whether SEG1 comes before SEG2 in the output file.
-  static bool
+  bool
   segment_precedes(const Output_segment* seg1, const Output_segment* seg2);
 
-  // A mapping used for group signatures.
-  typedef Unordered_map<std::string, bool> Signatures;
+  // Use to save and restore segments during relaxation.
+  typedef Unordered_map<const Output_segment*, const Output_segment*>
+    Segment_states;
+
+  // Save states of current output segments.
+  void
+  save_segments(Segment_states*);
+
+  // Restore output segment states.
+  void
+  restore_segments(const Segment_states*);
+
+  // Clean up after relaxation so that it is possible to lay out the
+  // sections and segments again.
+  void
+  clean_up_after_relaxation();
+
+  // Doing preparation work for relaxation.  This is factored out to make
+  // Layout::finalized a bit smaller and easier to read.
+  void
+  prepare_for_relaxation();
+
+  // Main body of the relaxation loop, which lays out the section.
+  off_t
+  relaxation_loop_body(int, Target*, Symbol_table*, Output_segment**,
+                      Output_segment*, Output_segment_headers*,
+                      Output_file_header*, unsigned int*);
+
+  // A mapping used for kept comdats/.gnu.linkonce group signatures.
+  typedef Unordered_map<std::string, Kept_section> Signatures;
 
   // Mapping from input section name/type/flags to output section.  We
   // use canonicalized strings here.
@@ -550,15 +1319,73 @@ class Layout
 
   // A comparison class for segments.
 
-  struct Compare_segments
+  class Compare_segments
   {
+   public:
+    Compare_segments(Layout* layout)
+      : layout_(layout)
+    { }
+
     bool
     operator()(const Output_segment* seg1, const Output_segment* seg2)
-    { return Layout::segment_precedes(seg1, seg2); }
+    { return this->layout_->segment_precedes(seg1, seg2); }
+
+   private:
+    Layout* layout_;
   };
 
-  // A reference to the options on the command line.
-  const General_options& options_;
+  typedef std::vector<Output_section_data*> Output_section_data_list;
+
+  // Debug checker class.
+  class Relaxation_debug_check
+  {
+   public:
+    Relaxation_debug_check()
+      : section_infos_()
+    { }
+
+    // Check that sections and special data are in reset states.
+    void
+    check_output_data_for_reset_values(const Layout::Section_list&,
+                                      const Layout::Data_list& special_outputs,
+                                      const Layout::Data_list& relax_outputs);
+
+    // Record information of a section list.
+    void
+    read_sections(const Layout::Section_list&);
+
+    // Verify a section list with recorded information.
+    void
+    verify_sections(const Layout::Section_list&);
+
+   private:
+    // Information we care about a section.
+    struct Section_info
+    {
+      // Output section described by this.
+      Output_section* output_section;
+      // Load address.
+      uint64_t address;
+      // Data size.
+      off_t data_size;
+      // File offset.
+      off_t offset;
+    };
+
+    // Section information.
+    std::vector<Section_info> section_infos_;
+  };
+
+  // Program properties from .note.gnu.property sections.
+  struct Gnu_property
+  {
+    size_t pr_datasz;
+    unsigned char* pr_data;
+  };
+  typedef std::map<unsigned int, Gnu_property> Gnu_properties;
+
+  // The number of input files, for sizing tables.
+  int number_of_input_files_;
   // Information set by scripts or by command line options.
   Script_options* script_options_;
   // The output section names.
@@ -578,21 +1405,35 @@ class Layout
   // The list of output sections which are not attached to any output
   // segment.
   Section_list unattached_section_list_;
-  // Whether we have attached the sections to the segments.
-  bool sections_are_attached_;
   // The list of unattached Output_data objects which require special
   // handling because they are not Output_sections.
   Data_list special_output_list_;
+  // Like special_output_list_, but cleared and recreated on each
+  // iteration of relaxation.
+  Data_list relax_output_list_;
   // The section headers.
   Output_section_headers* section_headers_;
   // A pointer to the PT_TLS segment if there is one.
   Output_segment* tls_segment_;
+  // A pointer to the PT_GNU_RELRO segment if there is one.
+  Output_segment* relro_segment_;
+  // A pointer to the PT_INTERP segment if there is one.
+  Output_segment* interp_segment_;
+  // A backend may increase the size of the PT_GNU_RELRO segment if
+  // there is one.  This is the amount to increase it by.
+  unsigned int increase_relro_;
   // The SHT_SYMTAB output section.
   Output_section* symtab_section_;
+  // The SHT_SYMTAB_SHNDX for the regular symbol table if there is one.
+  Output_symtab_xindex* symtab_xindex_;
   // The SHT_DYNSYM output section if there is one.
   Output_section* dynsym_section_;
+  // The SHT_SYMTAB_SHNDX for the dynamic symbol table if there is one.
+  Output_symtab_xindex* dynsym_xindex_;
   // The SHT_DYNAMIC output section if there is one.
   Output_section* dynamic_section_;
+  // The _DYNAMIC symbol if there is one.
+  Symbol* dynamic_symbol_;
   // The dynamic data which goes into dynamic_section_.
   Output_data_dynamic* dynamic_data_;
   // The exception frame output section if there is one.
@@ -603,12 +1444,22 @@ class Layout
   bool added_eh_frame_data_;
   // The exception frame header output section if there is one.
   Output_section* eh_frame_hdr_section_;
+  // The data for the .gdb_index section.
+  Gdb_index* gdb_index_data_;
   // The space for the build ID checksum if there is one.
   Output_section_data* build_id_note_;
+  // The output section containing dwarf abbreviations
+  Output_reduced_debug_abbrev_section* debug_abbrev_;
+  // The output section containing the dwarf debug info tree
+  Output_reduced_debug_info_section* debug_info_;
   // A list of group sections and their signatures.
   Group_signatures group_signatures_;
   // The size of the output file.
   off_t output_file_size_;
+  // Whether we have added an input section to an output section.
+  bool have_added_input_section_;
+  // Whether we have attached the sections to the segments.
+  bool sections_are_attached_;
   // Whether we have seen an object file marked to require an
   // executable stack.
   bool input_requires_executable_stack_;
@@ -622,6 +1473,47 @@ class Layout
   bool has_static_tls_;
   // Whether any sections require postprocessing.
   bool any_postprocessing_sections_;
+  // Whether we have resized the signatures_ hash table.
+  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_;
+  // True if some input sections need to be mapped to a unique segment,
+  // after being mapped to a unique Output_section.
+  bool unique_segment_for_sections_specified_;
+  // In incremental build, holds information check the inputs and build the
+  // .gnu_incremental_inputs section.
+  Incremental_inputs* incremental_inputs_;
+  // Whether we record output section data created in script
+  bool record_output_section_data_from_script_;
+  // Set if this is a slim LTO object not loaded with a compiler plugin
+  bool lto_slim_object_;
+  // 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_;
+  // 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_;
+  // This maps an input section to a unique segment. This is done by first
+  // placing such input sections in unique output sections and then mapping
+  // the output section to a unique segment.  Unique_segment_info stores
+  // any additional flags and alignment of the new segment.
+  Section_segment_map section_segment_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.
+  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_;
+  // Program properties.
+  Gnu_properties gnu_properties_;
 };
 
 // This task handles writing out data in output sections which is not
@@ -634,9 +1526,11 @@ class Write_sections_task : public Task
  public:
   Write_sections_task(const Layout* layout, Output_file* of,
                      Task_token* output_sections_blocker,
+                     Task_token* input_sections_blocker,
                      Task_token* final_blocker)
     : layout_(layout), of_(of),
       output_sections_blocker_(output_sections_blocker),
+      input_sections_blocker_(input_sections_blocker),
       final_blocker_(final_blocker)
   { }
 
@@ -661,6 +1555,7 @@ class Write_sections_task : public Task
   const Layout* layout_;
   Output_file* of_;
   Task_token* output_sections_blocker_;
+  Task_token* input_sections_blocker_;
   Task_token* final_blocker_;
 };
 
@@ -702,12 +1597,13 @@ class Write_data_task : public Task
 class Write_symbols_task : public Task
 {
  public:
-  Write_symbols_task(const Symbol_table* symtab,
-                    const Input_objects* input_objects,
+  Write_symbols_task(const Layout* layout, const Symbol_table* symtab,
+                    const Input_objects* /*input_objects*/,
                     const Stringpool* sympool, const Stringpool* dynpool,
                     Output_file* of, Task_token* final_blocker)
-    : symtab_(symtab), input_objects_(input_objects), sympool_(sympool),
-      dynpool_(dynpool), of_(of), final_blocker_(final_blocker)
+    : layout_(layout), symtab_(symtab),
+      sympool_(sympool), dynpool_(dynpool), of_(of),
+      final_blocker_(final_blocker)
   { }
 
   // The standard Task methods.
@@ -726,8 +1622,8 @@ class Write_symbols_task : public Task
   { return "Write_symbols_task"; }
 
  private:
+  const Layout* layout_;
   const Symbol_table* symtab_;
-  const Input_objects* input_objects_;
   const Stringpool* sympool_;
   const Stringpool* dynpool_;
   Output_file* of_;
@@ -772,14 +1668,40 @@ class Write_after_input_sections_task : public Task
   Task_token* final_blocker_;
 };
 
+// This task function handles computation of the build id.
+// When using --build-id=tree, it schedules the tasks that
+// compute the hashes for each chunk of the file. This task
+// cannot run until we have finalized the size of the output
+// file, after the completion of Write_after_input_sections_task.
+
+class Build_id_task_runner : public Task_function_runner
+{
+ public:
+  Build_id_task_runner(const General_options* options, const Layout* layout,
+                      Output_file* of)
+    : options_(options), layout_(layout), of_(of)
+  { }
+
+  // Run the operation.
+  void
+  run(Workqueue*, const Task*);
+
+ private:
+  const General_options* options_;
+  const Layout* layout_;
+  Output_file* of_;
+};
+
 // This task function handles closing the file.
 
 class Close_task_runner : public Task_function_runner
 {
  public:
   Close_task_runner(const General_options* options, const Layout* layout,
-                   Output_file* of)
-    : options_(options), layout_(layout), of_(of)
+                   Output_file* of, unsigned char* array_of_hashes,
+                   size_t size_of_hashes)
+    : options_(options), layout_(layout), of_(of),
+      array_of_hashes_(array_of_hashes), size_of_hashes_(size_of_hashes)
   { }
 
   // Run the operation.
@@ -790,6 +1712,8 @@ class Close_task_runner : public Task_function_runner
   const General_options* options_;
   const Layout* layout_;
   Output_file* of_;
+  unsigned char* const array_of_hashes_;
+  const size_t size_of_hashes_;
 };
 
 // A small helper function to align an address.
This page took 0.036689 seconds and 4 git commands to generate.