daily update
[deliverable/binutils-gdb.git] / gold / layout.cc
index 8c7cd9968bb0f471eb991c669333978da70ba70a..01b7c870fd6b85c3ff4a7e071ebedb6bb58a6c74 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.
@@ -45,7 +45,9 @@
 #include "compressed_output.h"
 #include "reduced_debug_output.h"
 #include "reloc.h"
+#include "descriptors.h"
 #include "layout.h"
+#include "plugin.h"
 
 namespace gold
 {
@@ -138,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.
@@ -205,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:
@@ -255,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:
@@ -421,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;
@@ -920,8 +927,7 @@ Layout::attach_allocated_section_to_segment(Output_section* os)
   if ((flags & elfcpp::SHF_TLS) != 0)
     {
       if (this->tls_segment_ == NULL)
-        this->tls_segment_ = this->make_output_segment(elfcpp::PT_TLS,
-                                                       seg_flags);
+       this->make_output_segment(elfcpp::PT_TLS, seg_flags);
       this->tls_segment_->add_output_section(os, seg_flags);
     }
 
@@ -931,8 +937,7 @@ Layout::attach_allocated_section_to_segment(Output_section* os)
     {
       gold_assert(seg_flags == (elfcpp::PF_R | elfcpp::PF_W));
       if (this->relro_segment_ == NULL)
-       this->relro_segment_ = this->make_output_segment(elfcpp::PT_GNU_RELRO,
-                                                        seg_flags);
+       this->make_output_segment(elfcpp::PT_GNU_RELRO, seg_flags);
       this->relro_segment_->add_output_section(os, seg_flags);
     }
 }
@@ -1507,14 +1512,14 @@ Layout::create_build_id()
       char buffer[uuidsz];
       memset(buffer, 0, uuidsz);
 
-      int descriptor = ::open("/dev/urandom", O_RDONLY);
+      int descriptor = open_descriptor(-1, "/dev/urandom", O_RDONLY);
       if (descriptor < 0)
        gold_error(_("--build-id=uuid failed: could not open /dev/urandom: %s"),
                   strerror(errno));
       else
        {
          ssize_t got = ::read(descriptor, buffer, uuidsz);
-         ::close(descriptor);
+         release_descriptor(descriptor, true);
          if (got < 0)
            gold_error(_("/dev/urandom: read failed: %s"), strerror(errno));
          else if (static_cast<size_t>(got) != uuidsz)
@@ -1732,6 +1737,9 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
        }
     }
 
+  const bool check_sections = parameters->options().check_sections();
+  Output_segment* last_load_segment = NULL;
+
   bool was_readonly = false;
   for (Segment_list::iterator p = this->segment_list_.begin();
        p != this->segment_list_.end();
@@ -1848,6 +1856,25 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
 
          if (((*p)->flags() & elfcpp::PF_W) == 0)
            was_readonly = true;
+
+         // Implement --check-sections.  We know that the segments
+         // are sorted by LMA.
+         if (check_sections && last_load_segment != NULL)
+           {
+             gold_assert(last_load_segment->paddr() <= (*p)->paddr());
+             if (last_load_segment->paddr() + last_load_segment->memsz()
+                 > (*p)->paddr())
+               {
+                 unsigned long long lb1 = last_load_segment->paddr();
+                 unsigned long long le1 = lb1 + last_load_segment->memsz();
+                 unsigned long long lb2 = (*p)->paddr();
+                 unsigned long long le2 = lb2 + (*p)->memsz();
+                 gold_error(_("load segment overlap [0x%llx -> 0x%llx] and "
+                              "[0x%llx -> 0x%llx]"),
+                            lb1, le1, lb2, le2);
+               }
+           }
+         last_load_segment = *p;
        }
     }
 
@@ -2732,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;
@@ -2753,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);
 }
@@ -2923,6 +2954,14 @@ Layout::add_comdat(Relobj* object, unsigned int shndx,
   if (ins.first->second.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 = kept;
+          return true;
+        }
       return false;
     }
   else if (group)
@@ -2976,6 +3015,12 @@ Layout::make_output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
   gold_assert(!parameters->options().relocatable());
   Output_segment* oseg = new Output_segment(type, flags);
   this->segment_list_.push_back(oseg);
+
+  if (type == elfcpp::PT_TLS)
+    this->tls_segment_ = oseg;
+  else if (type == elfcpp::PT_GNU_RELRO)
+    this->relro_segment_ = oseg;
+
   return oseg;
 }
 
@@ -3272,8 +3317,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.026406 seconds and 4 git commands to generate.