* object.cc (Sized_relobj::do_layout): Change to call layout_gnu_stack
[external/binutils.git] / gold / object.cc
index e09a71f..7d50514 100644 (file)
@@ -1,6 +1,6 @@
 // object.cc -- support for an object file for linking in gold
 
-// 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.
@@ -315,8 +315,8 @@ Relobj::is_section_name_included(const char* name)
           && strstr(name, "personality")) 
       || (is_prefix_of(".data", name) 
           &&  strstr(name, "personality")) 
-      || (is_prefix_of(".gnu.linkonce.d", name) && 
-            strstr(name, "personality")))
+      || (is_prefix_of(".gnu.linkonce.d", name)
+         && strstr(name, "personality")))
     {
       return true; 
     }
@@ -934,16 +934,16 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
   const unsigned int shnum = this->shnum();
   bool is_gc_pass_one = ((parameters->options().gc_sections() 
                           && !symtab->gc()->is_worklist_ready())
-                         || (parameters->options().icf()
+                         || (parameters->options().icf_enabled()
                              && !symtab->icf()->is_icf_ready()));
  
   bool is_gc_pass_two = ((parameters->options().gc_sections() 
                           && symtab->gc()->is_worklist_ready())
-                         || (parameters->options().icf()
+                         || (parameters->options().icf_enabled()
                              && symtab->icf()->is_icf_ready()));
 
   bool is_gc_or_icf = (parameters->options().gc_sections()
-                       || parameters->options().icf()); 
+                       || parameters->options().icf_enabled()); 
 
   // Both is_gc_pass_one and is_gc_pass_two should not be true.
   gold_assert(!(is_gc_pass_one  && is_gc_pass_two));
@@ -1138,6 +1138,12 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
                omit[i] = true;
            }
 
+         // Skip attributes section.
+         if (parameters->target().is_attributes_section(name))
+           {
+             omit[i] = true;
+           }
+
           bool discard = omit[i];
           if (!discard)
             {
@@ -1174,6 +1180,14 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
             {
               symtab->gc()->worklist().push(Section_id(this, i)); 
             }
+          // If the section name XXX can be represented as a C identifier
+          // it cannot be discarded if there are references to
+          // __start_XXX and __stop_XXX symbols.  These need to be
+          // specially handled.
+          if (is_cident(name))
+            {
+              symtab->gc()->add_cident_section(name, Section_id(this, i));
+            }
         }
 
       // When doing a relocatable link we are going to copy input
@@ -1238,7 +1252,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
               }
         }
 
-      if (is_gc_pass_two && parameters->options().icf())
+      if (is_gc_pass_two && parameters->options().icf_enabled())
         {
           if (out_sections[i] == NULL)
             {
@@ -1307,7 +1321,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
         }
     }
 
-  if (!is_gc_pass_one)
+  if (!is_gc_pass_two)
     layout->layout_gnu_stack(seen_gnu_stack, gnu_stack_flags);
 
   // When doing a relocatable link handle the reloc sections at the
@@ -1376,7 +1390,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
                                                   reloc_type[i],
                                                   &offset);
       out_sections[i] = os;
-      if (offset == -1)
+      if (os == NULL || offset == -1)
        {
          // An object can contain at most one section holding exception
          // frame information.
@@ -1390,7 +1404,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
       // If this section requires special handling, and if there are
       // relocs that apply to it, then we must do the special handling
       // before we apply the relocs.
-      if (offset == -1 && reloc_shndx[i] != 0)
+      if (os != NULL && offset == -1 && reloc_shndx[i] != 0)
        this->set_relocs_must_follow_section_writes();
     }
 
@@ -1521,6 +1535,7 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
   unsigned int dyncount = 0;
   // Skip the first, dummy, symbol.
   psyms += sym_size;
+  bool discard_all = parameters->options().discard_all();
   bool discard_locals = parameters->options().discard_locals();
   for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
     {
@@ -1544,7 +1559,7 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
       // Decide whether this symbol should go into the output file.
 
       if ((shndx < shnum && out_sections[shndx] == NULL)
-         || (shndx == this->discarded_eh_frame_shndx_))
+         || shndx == this->discarded_eh_frame_shndx_)
         {
          lv.set_no_output_symtab_entry();
           gold_assert(!lv.needs_output_dynsym_entry());
@@ -1567,6 +1582,21 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
          continue;
        }
 
+      const char* name = pnames + sym.get_st_name();
+
+      // If needed, add the symbol to the dynamic symbol table string pool.
+      if (lv.needs_output_dynsym_entry())
+        {
+          dynpool->add(name, true, NULL);
+          ++dyncount;
+        }
+
+      if (discard_all)
+       {
+         lv.set_no_output_symtab_entry();
+         continue;
+       }
+
       // If --discard-locals option is used, discard all temporary local
       // symbols.  These symbols start with system-specific local label
       // prefixes, typically .L for ELF system.  We want to be compatible
@@ -1579,7 +1609,6 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
       //   - the symbol has a name.
       //
       // We do not discard a symbol if it needs a dynamic symbol entry.
-      const char* name = pnames + sym.get_st_name();
       if (discard_locals
          && sym.get_st_type() != elfcpp::STT_FILE
          && !lv.needs_output_dynsym_entry()
@@ -1600,13 +1629,6 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
       // Add the symbol to the symbol table string pool.
       pool->add(name, true, NULL);
       ++count;
-
-      // If needed, add the symbol to the dynamic symbol table string pool.
-      if (lv.needs_output_dynsym_entry())
-        {
-          dynpool->add(name, true, NULL);
-          ++dyncount;
-        }
     }
 
   this->output_local_symbol_count_ = count;
@@ -1677,7 +1699,15 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
               os = folded_obj->output_section(folded.second);
               gold_assert(os != NULL);
               secoffset = folded_obj->get_output_section_offset(folded.second);
-              gold_assert(secoffset != invalid_address);
+
+             // This could be a relaxed input section.
+              if (secoffset == invalid_address)
+               {
+                 const Output_relaxed_input_section* relaxed_section =
+                   os->find_relaxed_input_section(folded_obj, folded.second);
+                 gold_assert(relaxed_section != NULL);
+                 secoffset = relaxed_section->address() - os->address();
+               }
             }
 
          if (os == NULL)
@@ -1711,12 +1741,18 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
                }
              else if (!os->find_starting_output_address(this, shndx, &start))
                {
-                 // This is a section symbol, but apparently not one
-                 // in a merged section.  Just use the start of the
-                 // output section.  This happens with relocatable
-                 // links when the input object has section symbols
-                 // for arbitrary non-merge sections.
-                 lv.set_output_value(os->address());
+                 // This is a section symbol, but apparently not one in a
+                 // merged section.  First check to see if this is a relaxed
+                 // input section.  If so, use its address.  Otherwise just
+                 // use the start of the output section.  This happens with
+                 // relocatable links when the input object has section
+                 // symbols for arbitrary non-merge sections.
+                 const Output_section_data* posd =
+                   os->find_relaxed_input_section(this, shndx);
+                 if (posd != NULL)
+                   lv.set_output_value(posd->address());
+                 else
+                   lv.set_output_value(os->address());
                }
              else
                {
@@ -2118,7 +2154,8 @@ Input_objects::add_object(Object* obj)
     }
 
   // Add this object to the cross-referencer if requested.
-  if (parameters->options().user_set_print_symbol_counts())
+  if (parameters->options().user_set_print_symbol_counts()
+      || parameters->options().cref())
     {
       if (this->cref_ == NULL)
        this->cref_ = new Cref();
@@ -2134,15 +2171,15 @@ Input_objects::add_object(Object* obj)
 void
 Input_objects::check_dynamic_dependencies() const
 {
+  bool issued_copy_dt_needed_error = false;
   for (Dynobj_list::const_iterator p = this->dynobj_list_.begin();
        p != this->dynobj_list_.end();
        ++p)
     {
       const Dynobj::Needed& needed((*p)->needed());
       bool found_all = true;
-      for (Dynobj::Needed::const_iterator pneeded = needed.begin();
-          pneeded != needed.end();
-          ++pneeded)
+      Dynobj::Needed::const_iterator pneeded;
+      for (pneeded = needed.begin(); pneeded != needed.end(); ++pneeded)
        {
          if (this->sonames_.find(*pneeded) == this->sonames_.end())
            {
@@ -2151,6 +2188,25 @@ Input_objects::check_dynamic_dependencies() const
            }
        }
       (*p)->set_has_unknown_needed_entries(!found_all);
+
+      // --copy-dt-needed-entries aka --add-needed is a GNU ld option
+      // --that gold does not support.  However, they cause no trouble
+      // --unless there is a DT_NEEDED entry that we don't know about;
+      // --warn only in that case.
+      if (!found_all
+         && !issued_copy_dt_needed_error
+         && (parameters->options().copy_dt_needed_entries()
+             || parameters->options().add_needed()))
+       {
+         const char* optname;
+         if (parameters->options().copy_dt_needed_entries())
+           optname = "--copy-dt-needed-entries";
+         else
+           optname = "--add-needed";
+         gold_error(_("%s is not supported but is required for %s in %s"),
+                    optname, (*pneeded).c_str(), (*p)->name().c_str());
+         issued_copy_dt_needed_error = true;
+       }
     }
 }
 
@@ -2159,7 +2215,8 @@ Input_objects::check_dynamic_dependencies() const
 void
 Input_objects::archive_start(Archive* archive)
 {
-  if (parameters->options().user_set_print_symbol_counts())
+  if (parameters->options().user_set_print_symbol_counts()
+      || parameters->options().cref())
     {
       if (this->cref_ == NULL)
        this->cref_ = new Cref();
@@ -2172,7 +2229,8 @@ Input_objects::archive_start(Archive* archive)
 void
 Input_objects::archive_stop(Archive* archive)
 {
-  if (parameters->options().user_set_print_symbol_counts())
+  if (parameters->options().user_set_print_symbol_counts()
+      || parameters->options().cref())
     this->cref_->add_archive_stop(archive);
 }
 
@@ -2186,6 +2244,15 @@ Input_objects::print_symbol_counts(const Symbol_table* symtab) const
     this->cref_->print_symbol_counts(symtab);
 }
 
+// Print a cross reference table.
+
+void
+Input_objects::print_cref(const Symbol_table* symtab, FILE* f) const
+{
+  if (parameters->options().cref() && this->cref_ != NULL)
+    this->cref_->print_cref(symtab, f);
+}
+
 // Relocate_info methods.
 
 // Return a string describing the location of a relocation.  This is
@@ -2304,8 +2371,8 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset,
     *punconfigured = false;
 
   std::string error;
-  bool big_endian;
-  int size;
+  bool big_endian = false;
+  int size = 0;
   if (!elfcpp::Elf_recognizer::is_valid_header(p, bytes, &size,
                                                &big_endian, &error))
     {
@@ -2457,4 +2524,48 @@ template
 struct Relocate_info<64, true>;
 #endif
 
+#ifdef HAVE_TARGET_32_LITTLE
+template
+void
+Xindex::initialize_symtab_xindex<32, false>(Object*, unsigned int);
+
+template
+void
+Xindex::read_symtab_xindex<32, false>(Object*, unsigned int,
+                                     const unsigned char*);
+#endif
+
+#ifdef HAVE_TARGET_32_BIG
+template
+void
+Xindex::initialize_symtab_xindex<32, true>(Object*, unsigned int);
+
+template
+void
+Xindex::read_symtab_xindex<32, true>(Object*, unsigned int,
+                                    const unsigned char*);
+#endif
+
+#ifdef HAVE_TARGET_64_LITTLE
+template
+void
+Xindex::initialize_symtab_xindex<64, false>(Object*, unsigned int);
+
+template
+void
+Xindex::read_symtab_xindex<64, false>(Object*, unsigned int,
+                                     const unsigned char*);
+#endif
+
+#ifdef HAVE_TARGET_64_BIG
+template
+void
+Xindex::initialize_symtab_xindex<64, true>(Object*, unsigned int);
+
+template
+void
+Xindex::read_symtab_xindex<64, true>(Object*, unsigned int,
+                                    const unsigned char*);
+#endif
+
 } // End namespace gold.