diff options
author | Rafael Ávila de Espíndola <respindola@mozilla.com> | 2010-03-22 14:18:24 +0000 |
---|---|---|
committer | Rafael Ávila de Espíndola <respindola@mozilla.com> | 2010-03-22 14:18:24 +0000 |
commit | b0193076dad64abdb42ed0057ad668eaf3c17c7a (patch) | |
tree | 52ff18d9073b353700e411c07b9cf8ad4f7c50f5 /gold/readsyms.cc | |
parent | cff8d58ab4a99c8fdcc1572227f9957064b1aaa0 (diff) | |
download | binutils-gdb-b0193076dad64abdb42ed0057ad668eaf3c17c7a.tar.gz |
2010-03-22 Rafael Espindola <espindola@google.com>
* 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.
Diffstat (limited to 'gold/readsyms.cc')
-rw-r--r-- | gold/readsyms.cc | 162 |
1 files changed, 143 insertions, 19 deletions
diff --git a/gold/readsyms.cc b/gold/readsyms.cc index 980e0af5705..d8af99bd39b 100644 --- a/gold/readsyms.cc +++ b/gold/readsyms.cc @@ -127,7 +127,7 @@ Read_symbols::requeue(Workqueue* workqueue, Input_objects* input_objects, workqueue->queue(new Read_symbols(input_objects, symtab, layout, dirpath, dirindex, mapfile, input_argument, - input_group, NULL, next_blocker)); + input_group, NULL, NULL, next_blocker)); } // Return whether a Read_symbols task is runnable. We can read an @@ -149,8 +149,10 @@ Read_symbols::is_runnable() // locks here. void -Read_symbols::locks(Task_locker*) +Read_symbols::locks(Task_locker* tl) { + if (this->member_ != NULL) + tl->add(this, this->next_blocker_); } // Run a Read_symbols task. @@ -165,6 +167,93 @@ Read_symbols::run(Workqueue* workqueue) this->next_blocker_)); } +// Handle a whole lib group. Other then collecting statisticts, this just +// mimics what we do for regular object files in the command line. + +bool +Read_symbols::do_whole_lib_group(Workqueue* workqueue) +{ + const Input_file_lib* lib_group = this->input_argument_->lib(); + + ++Lib_group::total_lib_groups; + + Task_token* this_blocker = this->this_blocker_; + for (Input_file_lib::const_iterator i = lib_group->begin(); + i != lib_group->end(); + ++i) + { + ++Lib_group::total_members; + ++Lib_group::total_members_loaded; + + const Input_argument* arg = &*i; + + Task_token* next_blocker; + if (i != lib_group->end() - 1) + { + next_blocker = new Task_token(true); + next_blocker->add_blocker(); + } + else + next_blocker = this->next_blocker_; + + workqueue->queue_soon(new Read_symbols(this->input_objects_, + this->symtab_, this->layout_, + this->dirpath_, this->dirindex_, + this->mapfile_, arg, NULL, + NULL, this_blocker, next_blocker)); + this_blocker = next_blocker; + } + + return true; +} + +// Handle a lib group. We set Read_symbols Tasks as usual, but have them +// just record the symbol data instead of adding the objects. We also start +// a Add_lib_group_symbols Task which runs after we've read all the symbols. +// In that task we process the members in a loop until we are done. + +bool +Read_symbols::do_lib_group(Workqueue* workqueue) +{ + const Input_file_lib* lib_group = this->input_argument_->lib(); + + if (lib_group->options().whole_archive()) + return this->do_whole_lib_group(workqueue); + + Lib_group* lib = new Lib_group(lib_group, this); + + Add_lib_group_symbols* add_lib_group_symbols = + new Add_lib_group_symbols(this->symtab_, this->layout_, + this->input_objects_, + lib, this->next_blocker_); + + + Task_token* next_blocker = new Task_token(true); + int j = 0; + for (Input_file_lib::const_iterator i = lib_group->begin(); + i != lib_group->end(); + ++i, ++j) + { + const Input_argument* arg = &*i; + Archive_member* m = lib->get_member(j); + + next_blocker->add_blocker(); + + // Since this Read_symbols will not create an Add_symbols, + // just pass NULL as this_blocker. + workqueue->queue_soon(new Read_symbols(this->input_objects_, + this->symtab_, this->layout_, + this->dirpath_, this->dirindex_, + this->mapfile_, arg, NULL, + m, NULL, next_blocker)); + } + + add_lib_group_symbols->set_blocker(next_blocker); + workqueue->queue_soon(add_lib_group_symbols); + + return true; +} + // Open the file and read the symbols. Return true if a new task was // queued, false if that could not happen due to some error. @@ -178,6 +267,9 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) return true; } + if (this->input_argument_->is_lib()) + return this->do_lib_group(workqueue); + Input_file* input_file = new Input_file(&this->input_argument_->file()); if (!input_file->open(*this->dirpath_, this, &this->dirindex_)) return false; @@ -212,7 +304,7 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) if (this->layout_->incremental_inputs()) { - const Input_argument* ia = this->input_argument_; + const Input_argument* ia = this->input_argument_; this->layout_->incremental_inputs()->report_archive(ia, arch); } @@ -246,6 +338,13 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) // We are done with the file at this point, so unlock it. obj->unlock(this); + if (this->member_ != NULL) + { + this->member_->sd_ = NULL; + this->member_->obj_ = obj; + return true; + } + workqueue->queue_next(new Add_symbols(this->input_objects_, this->symtab_, this->layout_, @@ -306,6 +405,13 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) input_file->file().unlock(this); + if (this->member_ != NULL) + { + this->member_->sd_ = sd; + this->member_->obj_ = obj; + return true; + } + // We use queue_next because everything is cached for this // task to run right away if possible. @@ -384,7 +490,7 @@ Read_symbols::do_group(Workqueue* workqueue) this->symtab_, this->layout_, this->dirpath_, this->dirindex_, this->mapfile_, arg, input_group, - this_blocker, next_blocker)); + NULL, this_blocker, next_blocker)); this_blocker = next_blocker; } @@ -398,7 +504,39 @@ Read_symbols::do_group(Workqueue* workqueue) std::string Read_symbols::get_name() const { - if (!this->input_argument_->is_group()) + if (this->input_argument_->is_group()) + { + std::string ret("Read_symbols group ("); + bool add_space = false; + const Input_file_group* group = this->input_argument_->group(); + for (Input_file_group::const_iterator p = group->begin(); + p != group->end(); + ++p) + { + if (add_space) + ret += ' '; + ret += p->file().name(); + add_space = true; + } + return ret + ')'; + } + else if (this->input_argument_->is_lib()) + { + std::string ret("Read_symbols lib ("); + bool add_space = false; + const Input_file_lib* lib = this->input_argument_->lib(); + for (Input_file_lib::const_iterator p = lib->begin(); + p != lib->end(); + ++p) + { + if (add_space) + ret += ' '; + ret += p->file().name(); + add_space = true; + } + return ret + ')'; + } + else { std::string ret("Read_symbols "); if (this->input_argument_->file().is_lib()) @@ -408,20 +546,6 @@ Read_symbols::get_name() const ret += this->input_argument_->file().name(); return ret; } - - std::string ret("Read_symbols group ("); - bool add_space = false; - const Input_file_group* group = this->input_argument_->group(); - for (Input_file_group::const_iterator p = group->begin(); - p != group->end(); - ++p) - { - if (add_space) - ret += ' '; - ret += p->file().name(); - add_space = true; - } - return ret + ')'; } // Class Add_symbols. |