2007-09-08 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / gold / layout.cc
index c150707819bf8f0283035af85c6e4cbaba7405a7..d533722687569d7c71a3d4c4d642af0fdf78b134 100644 (file)
@@ -133,7 +133,9 @@ Layout::get_output_section(const char* name, Stringpool::Key name_key,
   // We should ignore some flags.
   flags &= ~ (elfcpp::SHF_INFO_LINK
              | elfcpp::SHF_LINK_ORDER
-             | elfcpp::SHF_GROUP);
+             | elfcpp::SHF_GROUP
+             | elfcpp::SHF_MERGE
+             | elfcpp::SHF_STRINGS);
 
   const Key key(name_key, std::make_pair(type, flags));
   const std::pair<Key, Output_section*> v(key, NULL);
@@ -224,7 +226,7 @@ Output_section*
 Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
                            elfcpp::Elf_Xword flags)
 {
-  Output_section* os = new Output_section(name, type, flags, true);
+  Output_section* os = new Output_section(name, type, flags);
   this->section_list_.push_back(os);
 
   if ((flags & elfcpp::SHF_ALLOC) == 0)
@@ -466,7 +468,6 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
   off_t off = this->set_segment_offsets(target, load_seg, &shndx);
 
   // Create the symbol table sections.
-  // FIXME: We don't need to do this if we are stripping symbols.
   this->create_symtab_sections(size, input_objects, symtab, &off);
 
   // Create the .shstrtab section.
@@ -609,6 +610,10 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
 
          uint64_t aligned_addr = addr;
          uint64_t abi_pagesize = target->abi_pagesize();
+
+          // FIXME: This should depend on the -n and -N options.
+          (*p)->set_minimum_addralign(target->common_pagesize());
+
          if (was_readonly && ((*p)->flags() & elfcpp::PF_W) != 0)
            {
              uint64_t align = (*p)->addralign();
@@ -690,7 +695,9 @@ Layout::set_section_offsets(off_t off, unsigned int* pshndx)
   return off;
 }
 
-// Create the symbol table sections.
+// Create the symbol table sections.  Here we also set the final
+// values of the symbols.  At this point all the loadable sections are
+// fully laid out.
 
 void
 Layout::create_symtab_sections(int size, const Input_objects* input_objects,
@@ -979,24 +986,52 @@ Layout::create_version_sections(const Target* target, const Versions* versions,
   if (target->get_size() == 32)
     {
       if (target->is_big_endian())
-       this->sized_create_version_sections SELECT_SIZE_ENDIAN_NAME(32, true)(
-            versions, local_symcount, dynamic_symbols, dynstr
-            SELECT_SIZE_ENDIAN(32, true));
+        {
+#ifdef HAVE_TARGET_32_BIG
+          this->sized_create_version_sections
+              SELECT_SIZE_ENDIAN_NAME(32, true)(
+                  versions, local_symcount, dynamic_symbols, dynstr
+                  SELECT_SIZE_ENDIAN(32, true));
+#else
+          gold_unreachable();
+#endif
+        }
       else
-       this->sized_create_version_sections SELECT_SIZE_ENDIAN_NAME(32, false)(
-            versions, local_symcount, dynamic_symbols, dynstr
-            SELECT_SIZE_ENDIAN(32, false));
+        {
+#ifdef HAVE_TARGET_32_LITTLE
+          this->sized_create_version_sections
+              SELECT_SIZE_ENDIAN_NAME(32, false)(
+                  versions, local_symcount, dynamic_symbols, dynstr
+                  SELECT_SIZE_ENDIAN(32, false));
+#else
+          gold_unreachable();
+#endif
+        }
     }
   else if (target->get_size() == 64)
     {
       if (target->is_big_endian())
-       this->sized_create_version_sections SELECT_SIZE_ENDIAN_NAME(64, true)(
-            versions, local_symcount, dynamic_symbols, dynstr
-            SELECT_SIZE_ENDIAN(64, true));
+        {
+#ifdef HAVE_TARGET_64_BIG
+          this->sized_create_version_sections
+              SELECT_SIZE_ENDIAN_NAME(64, true)(
+                  versions, local_symcount, dynamic_symbols, dynstr
+                  SELECT_SIZE_ENDIAN(64, true));
+#else
+          gold_unreachable();
+#endif
+        }
       else
-       this->sized_create_version_sections SELECT_SIZE_ENDIAN_NAME(64, false)(
-            versions, local_symcount, dynamic_symbols, dynstr
-            SELECT_SIZE_ENDIAN(64, false));
+        {
+#ifdef HAVE_TARGET_64_LITTLE
+          this->sized_create_version_sections
+              SELECT_SIZE_ENDIAN_NAME(64, false)(
+                  versions, local_symcount, dynamic_symbols, dynstr
+                  SELECT_SIZE_ENDIAN(64, false));
+#else
+          gold_unreachable();
+#endif
+        }
     }
   else
     gold_unreachable();
@@ -1145,6 +1180,35 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
     odyn->add_symbol(elfcpp::DT_FINI, sym);
 
   // FIXME: Support DT_INIT_ARRAY and DT_FINI_ARRAY.
+
+  // Add a DT_RPATH entry if needed.
+  const General_options::Dir_list& rpath(this->options_.rpath());
+  if (!rpath.empty())
+    {
+      std::string rpath_val;
+      for (General_options::Dir_list::const_iterator p = rpath.begin();
+           p != rpath.end();
+           ++p)
+        {
+          if (rpath_val.empty())
+            rpath_val = *p;
+          else
+            {
+              // Eliminate duplicates.
+              General_options::Dir_list::const_iterator q;
+              for (q = rpath.begin(); q != p; ++q)
+                if (strcmp(*q, *p) == 0)
+                  break;
+              if (q == p)
+                {
+                  rpath_val += ':';
+                  rpath_val += *p;
+                }
+            }
+        }
+
+      odyn->add_string(elfcpp::DT_RPATH, rpath_val);
+    }
 }
 
 // The mapping of .gnu.linkonce section names to real section names.
@@ -1413,25 +1477,33 @@ Close_task_runner::run(Workqueue*)
 // Instantiate the templates we need.  We could use the configure
 // script to restrict this to only the ones for implemented targets.
 
+#ifdef HAVE_TARGET_32_LITTLE
 template
 Output_section*
 Layout::layout<32, false>(Relobj* object, unsigned int shndx, const char* name,
                          const elfcpp::Shdr<32, false>& shdr, off_t*);
+#endif
 
+#ifdef HAVE_TARGET_32_BIG
 template
 Output_section*
 Layout::layout<32, true>(Relobj* object, unsigned int shndx, const char* name,
                         const elfcpp::Shdr<32, true>& shdr, off_t*);
+#endif
 
+#ifdef HAVE_TARGET_64_LITTLE
 template
 Output_section*
 Layout::layout<64, false>(Relobj* object, unsigned int shndx, const char* name,
                          const elfcpp::Shdr<64, false>& shdr, off_t*);
+#endif
 
+#ifdef HAVE_TARGET_64_BIG
 template
 Output_section*
 Layout::layout<64, true>(Relobj* object, unsigned int shndx, const char* name,
                         const elfcpp::Shdr<64, true>& shdr, off_t*);
+#endif
 
 
 } // End namespace gold.
This page took 0.027918 seconds and 4 git commands to generate.