diff options
Diffstat (limited to 'gold/readsyms.cc')
-rw-r--r-- | gold/readsyms.cc | 149 |
1 files changed, 111 insertions, 38 deletions
diff --git a/gold/readsyms.cc b/gold/readsyms.cc index 2ba8dbb..1658a58 100644 --- a/gold/readsyms.cc +++ b/gold/readsyms.cc @@ -120,8 +120,8 @@ Read_symbols::run(Workqueue* workqueue) // If we didn't queue a new task, then we need to explicitly unblock // the token. if (!this->do_read_symbols(workqueue)) - workqueue->queue_front(new Unblock_token(this->this_blocker_, - this->next_blocker_)); + workqueue->queue_soon(new Unblock_token(this->this_blocker_, + this->next_blocker_)); } // Open the file and read the symbols. Return true if a new task was @@ -189,11 +189,14 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) input_file->file().unlock(this); - workqueue->queue_front(new Add_symbols(this->input_objects_, - this->symtab_, this->layout_, - obj, sd, - this->this_blocker_, - this->next_blocker_)); + // We use queue_next because everything is cached for this + // task to run right away if possible. + + workqueue->queue_next(new Add_symbols(this->input_objects_, + this->symtab_, this->layout_, + obj, sd, + this->this_blocker_, + this->next_blocker_)); return true; } @@ -208,30 +211,34 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) input_file); arch->setup(this); - workqueue->queue_front(new Add_archive_symbols(this->symtab_, - this->layout_, - this->input_objects_, - arch, - this->input_group_, - this->this_blocker_, - this->next_blocker_)); + workqueue->queue_next(new Add_archive_symbols(this->symtab_, + this->layout_, + this->input_objects_, + arch, + this->input_group_, + this->this_blocker_, + this->next_blocker_)); return true; } } - // Try to parse this file as a script. - if (read_input_script(workqueue, this->options_, this->symtab_, - this->layout_, this->dirpath_, this->input_objects_, - this->input_group_, this->input_argument_, input_file, - ehdr_buf, read_size, this->this_blocker_, - this->next_blocker_)) - return true; - - // Here we have to handle any other input file types we need. - gold_error(_("%s: not an object or archive"), - input_file->file().filename().c_str()); - - return false; + // Queue up a task to try to parse this file as a script. We use a + // separate task so that the script will be read in order with other + // objects named on the command line. Also so that we don't try to + // read multiple scripts simultaneously, which could lead to + // unpredictable changes to the General_options structure. + + workqueue->queue_soon(new Read_script(this->options_, + this->symtab_, + this->layout_, + this->dirpath_, + this->input_objects_, + this->input_group_, + this->input_argument_, + input_file, + this->this_blocker_, + this->next_blocker_)); + return true; } // Handle a group. We need to walk through the arguments over and @@ -258,21 +265,22 @@ Read_symbols::do_group(Workqueue* workqueue) Task_token* next_blocker = new Task_token(true); next_blocker->add_blocker(); - workqueue->queue(new Read_symbols(this->options_, this->input_objects_, - this->symtab_, this->layout_, - this->dirpath_, arg, input_group, - this_blocker, next_blocker)); + workqueue->queue_soon(new Read_symbols(this->options_, + this->input_objects_, + this->symtab_, this->layout_, + this->dirpath_, arg, input_group, + this_blocker, next_blocker)); this_blocker = next_blocker; } const int saw_undefined = this->symtab_->saw_undefined(); - workqueue->queue(new Finish_group(this->input_objects_, - this->symtab_, - this->layout_, - input_group, - saw_undefined, - this_blocker, - this->next_blocker_)); + workqueue->queue_soon(new Finish_group(this->input_objects_, + this->symtab_, + this->layout_, + input_group, + saw_undefined, + this_blocker, + this->next_blocker_)); } // Return a debugging name for a Read_symbols task. @@ -409,4 +417,69 @@ Finish_group::run(Workqueue*) delete this->input_group_; } +// Class Read_script + +Read_script::~Read_script() +{ + if (this->this_blocker_ != NULL) + delete this->this_blocker_; + // next_blocker_ is deleted by the task associated with the next + // input file. +} + +// We are blocked by this_blocker_. + +Task_token* +Read_script::is_runnable() +{ + if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked()) + return this->this_blocker_; + return NULL; +} + +// We don't unlock next_blocker_ here. If the script names any input +// files, then the last file will be responsible for unlocking it. + +void +Read_script::locks(Task_locker*) +{ +} + +// Read the script, if it is a script. + +void +Read_script::run(Workqueue* workqueue) +{ + bool used_next_blocker; + if (!read_input_script(workqueue, this->options_, this->symtab_, + this->layout_, this->dirpath_, this->input_objects_, + this->input_group_, this->input_argument_, + this->input_file_, this->next_blocker_, + &used_next_blocker)) + { + // Here we have to handle any other input file types we need. + gold_error(_("%s: not an object or archive"), + this->input_file_->file().filename().c_str()); + } + + if (!used_next_blocker) + { + // Queue up a task to unlock next_blocker. We can't just unlock + // it here, as we don't hold the workqueue lock. + workqueue->queue_soon(new Unblock_token(NULL, this->next_blocker_)); + } +} + +// Return a debugging name for a Read_script task. + +std::string +Read_script::get_name() const +{ + std::string ret("Read_script "); + if (this->input_argument_->file().is_lib()) + ret += "-l"; + ret += this->input_argument_->file().name(); + return ret; +} + } // End namespace gold. |