PR 10880
authorIan Lance Taylor <ian@airs.com>
Thu, 5 Nov 2009 06:24:39 +0000 (06:24 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 5 Nov 2009 06:24:39 +0000 (06:24 +0000)
* object.h (class Object): Add is_needed and set_is_needed
methods.  Add is_needed_ field.  Make bool fields into bitfields.
* symtab.cc (Symbol_table::set_dynsym_indexes): If a symbol is
defined in a dynamic object and referenced by a regular object,
set is_needed for the dynamic object.
* layout.cc (Layout::finish_dynamic_section): Don't add DT_NEEDED
if the file is marked with as_needed and it is not needed.

gold/ChangeLog
gold/layout.cc
gold/object.h
gold/symtab.cc

index bd91f6754fe89d823cb6e61d7a7199440ac31110..e31ffe735ba03d05a927134bcd25208cad3728f9 100644 (file)
@@ -1,3 +1,14 @@
+2009-11-04  Ian Lance Taylor  <iant@google.com>
+
+       PR 10880
+       * object.h (class Object): Add is_needed and set_is_needed
+       methods.  Add is_needed_ field.  Make bool fields into bitfields.
+       * symtab.cc (Symbol_table::set_dynsym_indexes): If a symbol is
+       defined in a dynamic object and referenced by a regular object,
+       set is_needed for the dynamic object.
+       * layout.cc (Layout::finish_dynamic_section): Don't add DT_NEEDED
+       if the file is marked with as_needed and it is not needed.
+
 2009-11-04  Ian Lance Taylor  <iant@google.com>
 
        PR 10887
index f0a51b43e1354a2ff5c4ba31c6bb023d41a85f80..b44dba65796af2de568426b890002e111f9d30b5 100644 (file)
@@ -3130,7 +3130,14 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
        p != input_objects->dynobj_end();
        ++p)
     {
-      // FIXME: Handle --as-needed.
+      if (!(*p)->is_needed()
+         && (*p)->input_file()->options().as_needed())
+       {
+         // This dynamic object was linked with --as-needed, but it
+         // is not needed.
+         continue;
+       }
+
       odyn->add_string(elfcpp::DT_NEEDED, (*p)->soname());
     }
 
index 558e456d6344c0510ccea656d79fda161448164c..187a10179b558c41a925af22d6be127228b0e4db 100644 (file)
@@ -195,8 +195,8 @@ class Object
   Object(const std::string& name, Input_file* input_file, bool is_dynamic,
         off_t offset = 0)
     : name_(name), input_file_(input_file), offset_(offset), shnum_(-1U),
-      is_dynamic_(is_dynamic), uses_split_stack_(false),
-      has_no_split_stack_(false), xindex_(NULL), no_export_(false)
+      is_dynamic_(is_dynamic), is_needed_(false), uses_split_stack_(false),
+      has_no_split_stack_(false), no_export_(false), xindex_(NULL)
   { input_file->file().add_object(); }
 
   virtual ~Object()
@@ -217,6 +217,19 @@ class Object
   is_dynamic() const
   { return this->is_dynamic_; }
 
+  // Return whether this object is needed--true if it is a dynamic
+  // object which defines some symbol referenced by a regular object.
+  // We keep the flag here rather than in Dynobj for convenience when
+  // setting it.
+  bool
+  is_needed() const
+  { return this->is_needed_; }
+
+  // Record that this object is needed.
+  void
+  set_is_needed()
+  { this->is_needed_ = true; }
+
   // Return whether this object was compiled with -fsplit-stack.
   bool
   uses_split_stack() const
@@ -589,17 +602,21 @@ class Object
   // Number of input sections.
   unsigned int shnum_;
   // Whether this is a dynamic object.
-  bool is_dynamic_;
+  bool is_dynamic_ : 1;
+  // Whether this object is needed.  This is only set for dynamic
+  // objects, and means that the object defined a symbol which was
+  // used by a reference from a regular object.
+  bool is_needed_ : 1;
   // Whether this object was compiled with -fsplit-stack.
-  bool uses_split_stack_;
+  bool uses_split_stack_ : 1;
   // Whether this object contains any functions compiled with the
   // no_split_stack attribute.
-  bool has_no_split_stack_;
-  // Many sections for objects with more than SHN_LORESERVE sections.
-  Xindex* xindex_;
+  bool has_no_split_stack_ : 1;
   // True if exclude this object from automatic symbol export.
   // This is used only for archive objects.
-  bool no_export_;
+  bool no_export_ : 1;
+  // Many sections for objects with more than SHN_LORESERVE sections.
+  Xindex* xindex_;
 };
 
 // A regular object (ET_REL).  This is an abstract base class itself.
index af272100b947166e6177ea4de3daffc3f7561422..dd521456077b6e3508b61c482a5ba7f83204be29 100644 (file)
@@ -2243,6 +2243,12 @@ Symbol_table::set_dynsym_indexes(unsigned int index,
          // Record any version information.
           if (sym->version() != NULL)
             versions->record_version(this, dynpool, sym);
+
+         // If the symbol is defined in a dynamic object and is
+         // referenced in a regular object, then mark the dynamic
+         // object as needed.  This is used to implement --as-needed.
+         if (sym->is_from_dynobj() && sym->in_reg())
+           sym->object()->set_is_needed();
        }
     }