From 594c8e5ede2a93362f335a97389eaadac17ec204 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 5 Nov 2009 06:24:39 +0000 Subject: [PATCH] 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. --- gold/ChangeLog | 11 +++++++++++ gold/layout.cc | 9 ++++++++- gold/object.h | 33 +++++++++++++++++++++++++-------- gold/symtab.cc | 6 ++++++ 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index bd91f6754fe..e31ffe735ba 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,14 @@ +2009-11-04 Ian Lance Taylor + + 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 PR 10887 diff --git a/gold/layout.cc b/gold/layout.cc index f0a51b43e13..b44dba65796 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -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()); } diff --git a/gold/object.h b/gold/object.h index 558e456d634..187a10179b5 100644 --- a/gold/object.h +++ b/gold/object.h @@ -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. diff --git a/gold/symtab.cc b/gold/symtab.cc index af272100b94..dd521456077 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -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(); } } -- 2.30.2