gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gold / layout.h
index 604f19b1fdff21923516f2867f7c4feba6bcddd0..fd5878da18bc7d97e2c763f7263bac209d66e83a 100644 (file)
@@ -1,6 +1,6 @@
 // layout.h -- lay out output file sections for gold  -*- C++ -*-
 
-// Copyright 2006, 2007, 2008, 2009 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.
@@ -41,6 +41,7 @@ namespace gold
 
 class General_options;
 class Incremental_inputs;
+class Incremental_binary;
 class Input_objects;
 class Mapfile;
 class Symbol_table;
@@ -51,12 +52,116 @@ 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.
@@ -70,7 +175,7 @@ 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,
+                    Target* target,
                     Layout* layout,
                     Mapfile* mapfile)
     : options_(options), input_objects_(input_objects), symtab_(symtab),
@@ -209,8 +314,8 @@ class Kept_section
   // 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 intpshndx,
+                     uint64_tpsize) const
   {
     gold_assert(this->is_comdat_);
     Comdat_group::const_iterator p = this->u_.group_sections->find(name);
@@ -224,7 +329,7 @@ class Kept_section
   // 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)
@@ -281,6 +386,119 @@ class Kept_section
   } 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.
 
 class Layout
@@ -294,6 +512,20 @@ class Layout
     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
@@ -303,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.
@@ -313,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,
@@ -323,7 +631,7 @@ 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,
@@ -342,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,
@@ -352,26 +660,73 @@ 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*);
+
+  // 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.  IS_DYNAMIC_LINKER_SECTION
-  // is true for sections which are used by the dynamic linker, such
-  // as dynamic reloc sections.  IS_RELRO is true for relro sections.
-  // IS_LAST_RELRO is true for the last relro section.
-  // IS_FIRST_NON_RELRO is true for the first section after the relro
-  // sections.
+  // 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*, bool is_dynamic_linker_section,
-                         bool is_relro, bool is_last_relro,
-                         bool is_first_non_relro);
+                         Output_section_data*, Output_section_order order,
+                         bool is_relro);
 
   // Increase the size of the relro segment by this much.
   void
@@ -415,6 +770,12 @@ 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*
@@ -444,12 +805,26 @@ class Layout
   {
     // Debugging sections can only be recognized by name.
     return (strncmp(name, ".debug", sizeof(".debug") - 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, ".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
@@ -458,7 +833,7 @@ class Layout
   // *KEPT_SECTION is set to the internal copy and the function return
   // false.
   bool
-  find_or_add_kept_section(const std::string& name, Relobj* object, 
+  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);
 
@@ -490,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
@@ -553,12 +936,24 @@ class Layout
   // Return the object managing inputs in incremental build. NULL in
   // non-incremental builds.
   Incremental_inputs*
-  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
@@ -589,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*
@@ -608,7 +1008,7 @@ 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.
@@ -624,6 +1024,21 @@ class Layout
   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&);
@@ -638,6 +1053,14 @@ class Layout
   };
   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.
@@ -660,16 +1083,20 @@ class Layout
 
   // 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 charsection_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 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();
+  create_stack_segment();
 
   // Create a build ID note if needed.
   void
@@ -682,12 +1109,12 @@ class Layout
   // 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();
+  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.
@@ -697,7 +1124,7 @@ class Layout
   // Create the output sections for the symbol table.
   void
   create_symtab_sections(const Input_objects*, Symbol_table*,
-                        unsigned int, off_t*);
+                        unsigned int, off_t*, unsigned int);
 
   // Create the .shstrtab section.
   Output_section*
@@ -712,6 +1139,7 @@ class Layout
   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);
 
@@ -750,14 +1178,14 @@ 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 number of allocated output sections.
   size_t
@@ -767,32 +1195,41 @@ class Layout
   Output_section*
   get_output_section(const char* name, Stringpool::Key name_key,
                     elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
-                    bool is_interp, bool is_dynamic_linker_section,
-                    bool is_relro, bool is_last_relro,
-                    bool is_first_non_relro);
+                    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_interp,
-                       bool is_dynamic_linker_section, bool is_relro,
-                       bool is_last_relro, bool is_first_non_relro);
+                       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, bool is_interp,
-                     bool is_dynamic_linker_section, bool is_relro,
-                     bool is_last_relro, bool is_first_non_relro);
+                     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
@@ -832,10 +1269,10 @@ class Layout
   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);
 
-  // Use to save and restore segments during relaxation. 
+  // Use to save and restore segments during relaxation.
   typedef Unordered_map<const Output_segment*, const Output_segment*>
     Segment_states;
 
@@ -882,11 +1319,19 @@ 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_;
   };
 
   typedef std::vector<Output_section_data*> Output_section_data_list;
@@ -898,12 +1343,13 @@ class Layout
     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&);
-  
+                                      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&);
@@ -911,7 +1357,7 @@ class Layout
     // Verify a section list with recorded information.
     void
     verify_sections(const Layout::Section_list&);
+
    private:
     // Information we care about a section.
     struct Section_info
@@ -930,6 +1376,14 @@ class Layout
     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.
@@ -954,12 +1408,17 @@ class Layout
   // 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_;
@@ -985,6 +1444,8 @@ 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
@@ -1016,17 +1477,43 @@ class Layout
   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_;
-  // List of output data that needs to be removed at relexation clean up.
+  // 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
@@ -1039,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)
   { }
 
@@ -1066,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_;
 };
 
@@ -1108,10 +1598,10 @@ class Write_symbols_task : public Task
 {
  public:
   Write_symbols_task(const Layout* layout, const Symbol_table* symtab,
-                    const Input_objects* input_objects,
+                    const Input_objects* /*input_objects*/,
                     const Stringpool* sympool, const Stringpool* dynpool,
                     Output_file* of, Task_token* final_blocker)
-    : layout_(layout), symtab_(symtab), input_objects_(input_objects),
+    : layout_(layout), symtab_(symtab),
       sympool_(sympool), dynpool_(dynpool), of_(of),
       final_blocker_(final_blocker)
   { }
@@ -1134,7 +1624,6 @@ class Write_symbols_task : public Task
  private:
   const Layout* layout_;
   const Symbol_table* symtab_;
-  const Input_objects* input_objects_;
   const Stringpool* sympool_;
   const Stringpool* dynpool_;
   Output_file* of_;
@@ -1179,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.
@@ -1197,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.035592 seconds and 4 git commands to generate.