* options.cc (parse_short_option): Keep dash_z from registering itself.
[deliverable/binutils-gdb.git] / gold / layout.cc
index 99819d6cfcdd69c4c0585e85b5f8157c8b0591e9..df74df36c5039deb05bf327b11bf2678ea231edc 100644 (file)
@@ -1,6 +1,6 @@
 // layout.cc -- lay out output file sections for gold
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -47,6 +47,7 @@
 #include "reloc.h"
 #include "descriptors.h"
 #include "layout.h"
+#include "plugin.h"
 
 namespace gold
 {
@@ -139,14 +140,6 @@ Layout::Hash_key::operator()(const Layout::Key& k) const
  return k.first + k.second.first + k.second.second;
 }
 
-// Return whether PREFIX is a prefix of STR.
-
-static inline bool
-is_prefix_of(const char* prefix, const char* str)
-{
-  return strncmp(prefix, str, strlen(prefix)) == 0;
-}
-
 // Returns whether the given section is in the list of
 // debug-sections-used-by-some-version-of-gdb.  Currently,
 // we've checked versions of gdb up to and including 6.7.1.
@@ -206,6 +199,9 @@ bool
 Layout::include_section(Sized_relobj<size, big_endian>*, const char* name,
                        const elfcpp::Shdr<size, big_endian>& shdr)
 {
+  if (shdr.get_sh_flags() & elfcpp::SHF_EXCLUDE)
+    return false;
+
   switch (shdr.get_sh_type())
     {
     case elfcpp::SHT_NULL:
@@ -256,6 +252,14 @@ Layout::include_section(Sized_relobj<size, big_endian>*, const char* name,
               && !is_gdb_debug_section(name))
            return false;
        }
+      if (parameters->options().strip_lto_sections()
+          && !parameters->options().relocatable()
+          && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
+        {
+          // Ignore LTO sections containing intermediate code.
+          if (is_prefix_of(".gnu.lto_", name))
+            return false;
+        }
       return true;
 
     default:
@@ -422,7 +426,9 @@ Layout::choose_output_section(const Relobj* relobj, const char* name,
   // output section.
 
   size_t len = strlen(name);
-  if (is_input_section && !parameters->options().relocatable())
+  if (is_input_section
+      && !this->script_options_->saw_sections_clause()
+      && !parameters->options().relocatable())
     name = Layout::output_section_name(name, &len);
 
   Stringpool::Key name_key;
@@ -2753,6 +2759,8 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
     }
   if (parameters->options().shared() && this->has_static_tls())
     flags |= elfcpp::DF_STATIC_TLS;
+  if (parameters->options().origin())
+    flags |= elfcpp::DF_ORIGIN;
   odyn->add_constant(elfcpp::DT_FLAGS, flags);
 
   flags = 0;
@@ -2774,6 +2782,8 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
     flags &= ~(elfcpp::DF_1_INITFIRST
               | elfcpp::DF_1_NODELETE
               | elfcpp::DF_1_NOOPEN);
+  if (parameters->options().origin())
+    flags |= elfcpp::DF_1_ORIGIN;
   if (flags)
     odyn->add_constant(elfcpp::DT_FLAGS_1, flags);
 }
@@ -2920,38 +2930,50 @@ Layout::output_section_name(const char* name, size_t* plen)
   return name;
 }
 
-// Record the signature of a comdat section, and return whether to
-// include it in the link.  If GROUP is true, this is a regular
-// section group.  If GROUP is false, this is a group signature
-// derived from the name of a linkonce section.  We want linkonce
-// signatures and group signatures to block each other, but we don't
-// want a linkonce signature to block another linkonce signature.
+// 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, the CANDIDATE signature is recorded for
+// this NAME in the layout object, *KEPT_SECTION is set to the
+// internal copy and the function return false.  In some cases, with
+// CANDIDATE->GROUP_ being false, KEPT_SECTION can point back to
+// CANDIDATE.
 
 bool
-Layout::add_comdat(Relobj* object, unsigned int shndx,
-                   const std::string& signature, bool group)
+Layout::find_or_add_kept_section(const std::string name,
+                                 Kept_section* candidate,
+                                 Kept_section** kept_section)
 {
-  Kept_section kept(object, shndx, group);
   std::pair<Signatures::iterator, bool> ins(
-    this->signatures_.insert(std::make_pair(signature, kept)));
+    this->signatures_.insert(std::make_pair(name, *candidate)));
 
+  if (kept_section)
+    *kept_section = &ins.first->second;
   if (ins.second)
     {
       // This is the first time we've seen this signature.
       return true;
     }
 
-  if (ins.first->second.group_)
+  if (ins.first->second.is_group)
     {
       // We've already seen a real section group with this signature.
+      // If the kept group is from a plugin object, and we're in
+      // the replacement phase, accept the new one as a replacement.
+      if (ins.first->second.object == NULL
+          && parameters->options().plugins()->in_replacement_phase())
+        {
+          ins.first->second = *candidate;
+          return true;
+        }
       return false;
     }
-  else if (group)
+  else if (candidate->is_group)
     {
       // This is a real section group, and we've already seen a
       // linkonce section with this signature.  Record that we've seen
       // a section group, and don't include this section group.
-      ins.first->second.group_ = true;
+      ins.first->second.is_group = true;
       return false;
     }
   else
@@ -2959,6 +2981,7 @@ Layout::add_comdat(Relobj* object, unsigned int shndx,
       // We've already seen a linkonce section and this is a linkonce
       // section.  These don't block each other--this may be the same
       // symbol name with different section types.
+      *kept_section = candidate;
       return true;
     }
 }
@@ -2973,8 +2996,8 @@ Layout::find_kept_object(const std::string& signature,
   if (p == this->signatures_.end())
     return NULL;
   if (pshndx != NULL)
-    *pshndx = p->second.shndx_;
-  return p->second.object_;
+    *pshndx = p->second.shndx;
+  return p->second.object;
 }
 
 // Store the allocated sections into the section list.
@@ -3083,7 +3106,7 @@ Layout::write_sections_after_input_sections(Output_file* of)
     {
       off_t off = this->output_file_size_;
       off = this->set_section_offsets(off, POSTPROCESSING_SECTIONS_PASS);
-      
+
       // Now that we've finalized the names, we can finalize the shstrab.
       off =
        this->set_section_offsets(off,
@@ -3299,8 +3322,8 @@ Write_symbols_task::locks(Task_locker* tl)
 void
 Write_symbols_task::run(Workqueue*)
 {
-  this->symtab_->write_globals(this->input_objects_, this->sympool_,
-                              this->dynpool_, this->layout_->symtab_xindex(),
+  this->symtab_->write_globals(this->sympool_, this->dynpool_,
+                              this->layout_->symtab_xindex(),
                               this->layout_->dynsym_xindex(), this->of_);
 }
 
This page took 0.026519 seconds and 4 git commands to generate.