* 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.
This commit is contained in:
Ian Lance Taylor 2009-11-05 06:24:39 +00:00
parent 946ef19679
commit 594c8e5ede
4 changed files with 50 additions and 9 deletions

View 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

View 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());
}

View 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.

View 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();
}
}