From b0193076dad64abdb42ed0057ad668eaf3c17c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Mon, 22 Mar 2010 14:18:24 +0000 Subject: 2010-03-22 Rafael Espindola * archive.cc (Should_include): Move to archive.h. (should_include_member): Make it a member of Archive. (Lib_group): New. (Add_lib_group_symbols): New. * archive.h: Include options.h. (Archive_member): Moved from Archive. (Should_include): Moved from archive.cc. (Lib_group): New. (Add_lib_group_symbols): New. * dynobj.cc (do_should_include_member): New. * dynobj.h (do_should_include_member): New. * gold.cc (queue_initial_tasks): Update call to queue. * main.cc (main): Print lib group stats. * object.cc (do_should_include_member): New. * object.h: Include archive.h. (Object::should_include_member): New. (Object::do_should_include_member): New. (Sized_relobj::do_should_include_member): New. * options.cc (General_options::parse_start_lib): New. (General_options::parse_end_lib): New. (Input_arguments::add_file): Handle lib groups. (Input_arguments::start_group): Check we are not in a lib. (Input_arguments::start_lib): New. (Input_arguments::end_lib): New. * options.h (General_options): Add start_lib and end_lib. (Input_argument::lib_): New. (Input_argument::lib): New. (Input_argument::is_lib): New. (Input_file_lib): New. (Input_arguments::in_lib_): New. (Input_arguments::in_lib): New. (Input_arguments::start_lib): New. (Input_arguments::end_lib_): New. * plugin.cc (Pluginobj::get_symbol_resolution_info): Mark symbols in unused members as preempted. (Sized_pluginobj::do_should_include_member): New. * plugin.h (Sized_pluginobj::do_should_include_member): New. * readsyms.cc (Read_symbols::locks): If we are just reading a member, return the blocker. (Read_symbols::do_whole_lib_group): New. (Read_symbols::do_lib_group): New. (Read_symbols::do_read_symbols): Handle lib groups. (Read_symbols::get_name): Handle lib groups. * readsyms.h (Read_symbols): Add an archive member pointer. (Read_symbols::do_whole_lib_group): New. (Read_symbols::do_lib_group): New. (Read_symbols::member_): New. * script.cc (read_input_script): Update call to queue_soon. --- gold/archive.cc | 178 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 155 insertions(+), 23 deletions(-) (limited to 'gold/archive.cc') diff --git a/gold/archive.cc b/gold/archive.cc index 4411033..c62fb24 100644 --- a/gold/archive.cc +++ b/gold/archive.cc @@ -602,20 +602,10 @@ Archive::read_symbols(off_t off) this->members_[off] = member; } -// When we see a symbol in an archive we might decide to include the member, -// not include the member or be undecided. This enum represents these -// possibilities. - -enum Should_include -{ - SHOULD_INCLUDE_NO, - SHOULD_INCLUDE_YES, - SHOULD_INCLUDE_UNKNOWN -}; - -static Should_include -should_include_member(Symbol_table* symtab, const char* sym_name, Symbol** symp, - std::string* why, char** tmpbufp, size_t* tmpbuflen) +Archive::Should_include +Archive::should_include_member(Symbol_table* symtab, const char* sym_name, + Symbol** symp, std::string* why, char** tmpbufp, + size_t* tmpbuflen) { // In an object file, and therefore in an archive map, an // '@' in the name separates the symbol name from the @@ -659,7 +649,7 @@ should_include_member(Symbol_table* symtab, const char* sym_name, Symbol** symp, { // Check whether the symbol was named in a -u option. if (!parameters->options().is_undefined(sym_name)) - return SHOULD_INCLUDE_UNKNOWN; + return Archive::SHOULD_INCLUDE_UNKNOWN; else { *why = "-u "; @@ -667,11 +657,11 @@ should_include_member(Symbol_table* symtab, const char* sym_name, Symbol** symp, } } else if (!sym->is_undefined()) - return SHOULD_INCLUDE_NO; + return Archive::SHOULD_INCLUDE_NO; else if (sym->binding() == elfcpp::STB_WEAK) - return SHOULD_INCLUDE_UNKNOWN; + return Archive::SHOULD_INCLUDE_UNKNOWN; - return SHOULD_INCLUDE_YES; + return Archive::SHOULD_INCLUDE_YES; } // Select members from the archive and add them to the link. We walk @@ -735,14 +725,15 @@ Archive::add_symbols(Symbol_table* symtab, Layout* layout, Symbol* sym; std::string why; - Should_include t = should_include_member(symtab, sym_name, - &sym, &why, &tmpbuf, - &tmpbuflen); + Archive::Should_include t = + Archive::should_include_member(symtab, sym_name, &sym, &why, + &tmpbuf, &tmpbuflen); - if (t == SHOULD_INCLUDE_NO || t == SHOULD_INCLUDE_YES) + if (t == Archive::SHOULD_INCLUDE_NO + || t == Archive::SHOULD_INCLUDE_YES) this->armap_checked_[i] = true; - if (t != SHOULD_INCLUDE_YES) + if (t != Archive::SHOULD_INCLUDE_YES) continue; // We want to include this object in the link. @@ -978,4 +969,145 @@ Add_archive_symbols::run(Workqueue* workqueue) } } +// Class Lib_group static variables. +unsigned int Lib_group::total_lib_groups; +unsigned int Lib_group::total_members; +unsigned int Lib_group::total_members_loaded; + +Lib_group::Lib_group(const Input_file_lib* lib, Task* task) + : lib_(lib), task_(task), members_() +{ + this->members_.resize(lib->size()); +} + +// Select members from the lib group and add them to the link. We walk +// through the the members, and check if each one up should be included. +// If the object says it should be included, we do so. We have to do +// this in a loop, since including one member may create new undefined +// symbols which may be satisfied by other members. + +void +Lib_group::add_symbols(Symbol_table* symtab, Layout* layout, + Input_objects* input_objects) +{ + ++Lib_group::total_lib_groups; + + Lib_group::total_members += this->members_.size(); + + bool added_new_object; + do + { + added_new_object = false; + unsigned int i = 0; + while (i < this->members_.size()) + { + const Archive_member& member = this->members_[i]; + Object *obj = member.obj_; + std::string why; + + // Skip files with no symbols. Plugin objects have + // member.sd_ == NULL. + if (obj != NULL + && (member.sd_ == NULL || member.sd_->symbol_names != NULL)) + { + Archive::Should_include t = obj->should_include_member(symtab, + member.sd_, + &why); + + if (t != Archive::SHOULD_INCLUDE_YES) + { + ++i; + continue; + } + + this->include_member(symtab, layout, input_objects, member); + + added_new_object = true; + } + else + { + if (member.sd_ != NULL) + delete member.sd_; + } + + this->members_[i] = this->members_.back(); + this->members_.pop_back(); + } + } + while (added_new_object); +} + +// Include a lib group member in the link. + +void +Lib_group::include_member(Symbol_table* symtab, Layout* layout, + Input_objects* input_objects, + const Archive_member& member) +{ + ++Lib_group::total_members_loaded; + + Object* obj = member.obj_; + gold_assert(obj != NULL); + + Pluginobj* pluginobj = obj->pluginobj(); + if (pluginobj != NULL) + { + pluginobj->add_symbols(symtab, NULL, layout); + return; + } + + Read_symbols_data* sd = member.sd_; + gold_assert(sd != NULL); + obj->lock(this->task_); + if (input_objects->add_object(obj)) + { + obj->layout(symtab, layout, sd); + obj->add_symbols(symtab, sd, layout); + // Unlock the file for the next task. + obj->unlock(this->task_); + } + delete sd; +} + +// Print statistical information to stderr. This is used for --stats. + +void +Lib_group::print_stats() +{ + fprintf(stderr, _("%s: lib groups: %u\n"), + program_name, Lib_group::total_lib_groups); + fprintf(stderr, _("%s: total lib groups members: %u\n"), + program_name, Lib_group::total_members); + fprintf(stderr, _("%s: loaded lib groups members: %u\n"), + program_name, Lib_group::total_members_loaded); +} + +Task_token* +Add_lib_group_symbols::is_runnable() +{ + if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked()) + return this->this_blocker_; + return NULL; +} + +void +Add_lib_group_symbols::locks(Task_locker* tl) +{ + tl->add(this, this->next_blocker_); +} + +void +Add_lib_group_symbols::run(Workqueue*) +{ + this->lib_->add_symbols(this->symtab_, this->layout_, this->input_objects_); +} + +Add_lib_group_symbols::~Add_lib_group_symbols() +{ + if (this->this_blocker_ != NULL) + delete this->this_blocker_; + // next_blocker_ is deleted by the task associated with the next + // input file. +} + } // End namespace gold. -- cgit v1.1