include/elf/
[deliverable/binutils-gdb.git] / gold / layout.h
index 06060effda9bff149a1649e805bd6cbfe85711e9..ced07b5c606a8f60cf706e870a27be8d048a21f7 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 2006, 2007, 2008, 2009, 2010 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,81 @@ 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 Target;
+struct Timespec;
+
+// Return TRUE if SECNAME is the name of a compressed debug section.
+extern bool
+is_compressed_debug_section(const char* secname);
+
+// Maintain a list of free space within a section, segment, or file.
+// Used for incremental update links.
+
+class Free_list
+{
+ public:
+  Free_list()
+    : list_(), last_remove_(list_.begin()), extend_(false), length_(0)
+  { }
+
+  void
+  init(off_t len, bool extend);
+
+  void
+  remove(off_t start, off_t end);
+
+  off_t
+  allocate(off_t len, uint64_t align, off_t minoff);
+
+  void
+  dump();
+
+  static void
+  print_stats();
+
+ private:
+  struct Free_list_node
+  {
+    Free_list_node(off_t start, off_t end)
+      : start_(start), end_(end)
+    { }
+    off_t start_;
+    off_t end_;
+  };
+  typedef std::list<Free_list_node>::iterator Iterator;
+
+  // The free list.
+  std::list<Free_list_node> list_;
+
+  // The last node visited during a remove operation.
+  Iterator last_remove_;
+
+  // Whether we can extend past the original length.
+  bool extend_;
+
+  // The total length of the section, segment, or file.
+  off_t length_;
+
+  // Statistics:
+  // The total number of free lists used.
+  static unsigned int num_lists;
+  // The total number of free list nodes used.
+  static unsigned int num_nodes;
+  // The total number of calls to Free_list::remove.
+  static unsigned int num_removes;
+  // The total number of nodes visited during calls to Free_list::remove.
+  static unsigned int num_remove_visits;
+  // The total number of calls to Free_list::allocate.
+  static unsigned int num_allocates;
+  // The total number of nodes visited during calls to Free_list::allocate.
+  static unsigned int num_allocate_visits;
+};
 
 // This task function handles mapping the input sections to output
 // sections and laying them out in memory.
@@ -209,8 +279,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 +294,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 +351,107 @@ 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 regular text sections.
+  ORDER_TEXT,
+
+  // 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 +465,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,17 +488,29 @@ 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);
 
+  // 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&);
+
+  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.
   // DATA_SECTION is the reloc section to which it refers.  RR is the
   // 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 +520,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 +539,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,
@@ -357,21 +554,18 @@ class Layout
   // .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.  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
@@ -433,12 +627,18 @@ class Layout
   is_linkonce(const char* name)
   { return strncmp(name, ".gnu.linkonce", sizeof(".gnu.linkonce") - 1) == 0; }
 
+  // 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
@@ -485,6 +685,10 @@ class Layout
     return this->symtab_section_;
   }
 
+  // Return the file offset of the normal symbol table.
+  off_t
+  symtab_section_offset() const;
+
   // Return the dynamic symbol table.
   Output_section*
   dynsym_section() const
@@ -548,9 +752,17 @@ 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);
+
   // Compute and write out the build ID if needed.
   void
   write_build_id(Output_file*) const;
@@ -586,7 +798,8 @@ class Layout
 
   // 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*
@@ -655,7 +868,7 @@ 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 gold version.
@@ -677,7 +890,7 @@ 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.
@@ -745,7 +958,7 @@ 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
@@ -762,29 +975,29 @@ 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);
 
   // 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);
 
   // 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*);
 
+  // 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*);
@@ -990,6 +1203,8 @@ class Layout
   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
@@ -1014,12 +1229,20 @@ class Layout
   Incremental_inputs* incremental_inputs_;
   // Whether we record output section data created in script
   bool record_output_section_data_from_script_;
-  // List of output data that needs to be removed at relexation clean up.
+  // List of output data that needs to be removed at relaxation clean up.
   Output_section_data_list script_output_section_data_list_;
   // Structure to save segment states before entering the relaxation loop.
   Segment_states* segment_states_;
   // A relaxation debug checker.  We only create one when in debugging mode.
   Relaxation_debug_check* relaxation_debug_check_;
+  // 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_;
 };
 
 // This task handles writing out data in output sections which is not
This page took 0.033388 seconds and 4 git commands to generate.