diff options
author | Ian Lance Taylor <ian@airs.com> | 2009-03-14 05:56:46 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2009-03-14 05:56:46 +0000 |
commit | 15f8229bbf3f6fff866cbc04b07ddde9f6e41941 (patch) | |
tree | baff1a2307ed76fd05a8c579ada97c1605affcb4 /gold/readsyms.cc | |
parent | 2f563b5100820d5ca2d8ca0d3dd399e5ba6c798b (diff) | |
download | gdb-15f8229bbf3f6fff866cbc04b07ddde9f6e41941.zip gdb-15f8229bbf3f6fff866cbc04b07ddde9f6e41941.tar.gz gdb-15f8229bbf3f6fff866cbc04b07ddde9f6e41941.tar.bz2 |
* readsyms.cc (Read_symbols::incompatible_warning): New function.
(Read_symbols::requeue): New function.
(Read_symbols::do_read_symbols): If make_elf_object fails because
the target type is not configured, and the file was searched for,
issue a warning and retry with the next directory.
(Add_symbols::run): If the file has an incompatible format, and
it was searched for, requeue the Read_symbols task. On error,
release the object.
* readsyms.h (class Read_symbols): Add dirindex_ field. Add
dirindex parameter to constructor. Change all callers. Declare
incompatible_warning and requeue.
(class Add_symbols): Add dirpath_, dirindex_, mapfile_,
input_argument_ and input_group_ fields. Add them to
constructor. Change all callers.
(class Read_script): Add dirindex_ field. Add it to constructor.
Change all callers.
* archive.cc (Archive::setup): Remove input_objects parameter.
Change all callers.
(Archive::get_file_and_offset): Likewise.
(Archive::read_all_symbols): Likewise.
(Archive::read_symbols): Likewise.
(Archive::get_elf_object_for_member): Remove input_objects
parameter. Add punconfigured parameter. Change all callers.
(Archive::add_symbols): Change return type to bool. Check return
value of include_member.
(Archive::include_all_members): Likewise.
(Archive::include_member): Change return type to bool. Return
false if first included object has incompatible target. Set
included_member_ field.
(Add_archive_symbols::run): If add_symbols returns false, requeue
Read_symbols task.
* archive.h (class Archive): Add included_member_ field.
Initialize it in constructor. Add input_file and searched_for
methods. Update declarations.
(class Add_archive_symbols): Add dirpath_, dirindex_, and
input_argument_ fields. Add them to constructor. Change all
callers.
* script.cc: Include "target-select.h".
(class Parser_closure): Add skip_on_incompatible_target_ and
found_incompatible_target_ fields. Add
skip_on_incompatible_target parameter to constructor. Change all
callers. Add methods skip_on_incompatible_target,
clear_skip_on_incompatible_target, found_incompatible_target, and
set_found_incompatible_target.
(read_input_script): Add dirindex parameter. Change all callers.
If parser finds an incompatible target, requeue Read_symbols
task.
(script_set_symbol): Clear skip_on_incompatible_target in
closure.
(script_add_assertion, script_parse_option): Likewise.
(script_start_sections, script_add_phdr): Likewise.
(script_check_output_format): New function.
* script.h (read_input_script): Update declaration.
* script-c.h (script_check_output_format): Declare.
* yyscript.y (file_cmd): Handle OUTPUT_FORMAT.
(ignore_cmd): Remove OUTPUT_FORMAT.
* fileread.cc (Input_file::Input_file): Add explicit this.
(Input_file::will_search_for): New function.
(Input_file::open): Add pindex parameter. Change all callers.
* fileread.h (class Input_file): Add input_file_argument method.
Declare will_search_for. Update declarations.
* object.cc (make_elf_object): Add punconfigured parameter.
Change all callers.
* object.h (class Object): Make input_file public. Add
searched_for method.
(make_elf_object): Update declaration.
* dirsearch.cc (Dirsearch::find): Add pindex parameter. Use it to
restart search.
* dirsearch.h (class Dirsearch): Update declaration.
* options.h (class General_options): Add --warn-search-mismatch.
* parameters.cc (Parameters::is_compatible_target): New function.
* parameters.h (class Parameters): Declare is_compatible_target.
* workqueue.cc (Workqueue::add_blocker): New function.
* workqueue.h (class Workqueue): Declare add_blocker.
Diffstat (limited to 'gold/readsyms.cc')
-rw-r--r-- | gold/readsyms.cc | 106 |
1 files changed, 94 insertions, 12 deletions
diff --git a/gold/readsyms.cc b/gold/readsyms.cc index 4e126e7..dc85898 100644 --- a/gold/readsyms.cc +++ b/gold/readsyms.cc @@ -90,6 +90,44 @@ Read_symbols::~Read_symbols() // Add_symbols task. } +// If appropriate, issue a warning about skipping an incompatible +// file. + +void +Read_symbols::incompatible_warning(const Input_argument* input_argument, + const Input_file* input_file) +{ + if (parameters->options().warn_search_mismatch()) + gold_warning("skipping incompatible %s while searching for %s", + input_file->filename().c_str(), + input_argument->file().name()); +} + +// Requeue a Read_symbols task to search for the next object with the +// same name. + +void +Read_symbols::requeue(Workqueue* workqueue, Input_objects* input_objects, + Symbol_table* symtab, Layout* layout, Dirsearch* dirpath, + int dirindex, Mapfile* mapfile, + const Input_argument* input_argument, + Input_group* input_group, Task_token* next_blocker) +{ + // Bump the directory search index. + ++dirindex; + + // We don't need to worry about this_blocker, since we already + // reached it. However, we are removing the blocker on next_blocker + // because the calling task is completing. So we need to add a new + // blocker. Since next_blocker may be shared by several tasks, we + // need to increment the count with the workqueue lock held. + workqueue->add_blocker(next_blocker); + + workqueue->queue(new Read_symbols(input_objects, symtab, layout, dirpath, + dirindex, mapfile, input_argument, + input_group, NULL, next_blocker)); +} + // Return whether a Read_symbols task is runnable. We can read an // ordinary input file immediately. For an archive specified using // -l, we have to wait until the search path is complete. @@ -139,7 +177,7 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) } Input_file* input_file = new Input_file(&this->input_argument_->file()); - if (!input_file->open(*this->dirpath_, this)) + if (!input_file->open(*this->dirpath_, this, &this->dirindex_)) return false; // Read enough of the file to pick up the entire ELF header. @@ -171,7 +209,7 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) Archive* arch = new Archive(this->input_argument_->file().name(), input_file, is_thin_archive, this->dirpath_, this); - arch->setup(this->input_objects_); + arch->setup(); // Unlock the archive so it can be used in the next task. arch->unlock(this); @@ -179,7 +217,10 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) workqueue->queue_next(new Add_archive_symbols(this->symtab_, this->layout_, this->input_objects_, + this->dirpath_, + this->dirindex_, this->mapfile_, + this->input_argument_, arch, this->input_group_, this->this_blocker_, @@ -203,7 +244,13 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) workqueue->queue_next(new Add_symbols(this->input_objects_, this->symtab_, this->layout_, - obj, NULL, + this->dirpath_, + this->dirindex_, + this->mapfile_, + this->input_argument_, + this->input_group_, + obj, + NULL, this->this_blocker_, this->next_blocker_)); return true; @@ -221,10 +268,24 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) { // This is an ELF object. + bool unconfigured; Object* obj = make_elf_object(input_file->filename(), - input_file, 0, ehdr, read_size); + input_file, 0, ehdr, read_size, + &unconfigured); if (obj == NULL) - return false; + { + if (unconfigured && input_file->will_search_for()) + { + Read_symbols::incompatible_warning(this->input_argument_, + input_file); + input_file->file().release(); + input_file->file().unlock(this); + delete input_file; + ++this->dirindex_; + return this->do_read_symbols(workqueue); + } + return false; + } Read_symbols_data* sd = new Read_symbols_data; obj->read_symbols(sd); @@ -244,7 +305,13 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) workqueue->queue_next(new Add_symbols(this->input_objects_, this->symtab_, this->layout_, - obj, sd, + this->dirpath_, + this->dirindex_, + this->mapfile_, + this->input_argument_, + this->input_group_, + obj, + sd, this->this_blocker_, this->next_blocker_)); @@ -261,6 +328,7 @@ Read_symbols::do_read_symbols(Workqueue* workqueue) workqueue->queue_soon(new Read_script(this->symtab_, this->layout_, this->dirpath_, + this->dirindex_, this->input_objects_, this->mapfile_, this->input_group_, @@ -297,8 +365,8 @@ Read_symbols::do_group(Workqueue* workqueue) next_blocker->add_blocker(); workqueue->queue_soon(new Read_symbols(this->input_objects_, this->symtab_, this->layout_, - this->dirpath_, this->mapfile_, - arg, input_group, + this->dirpath_, this->dirindex_, + this->mapfile_, arg, input_group, this_blocker, next_blocker)); this_blocker = next_blocker; } @@ -376,7 +444,7 @@ Add_symbols::locks(Task_locker* tl) // Add the symbols in the object to the symbol table. void -Add_symbols::run(Workqueue*) +Add_symbols::run(Workqueue* workqueue) { Pluginobj* pluginobj = this->object_->pluginobj(); if (pluginobj != NULL) @@ -385,9 +453,23 @@ Add_symbols::run(Workqueue*) return; } - if (!this->input_objects_->add_object(this->object_)) + // If this file has an incompatible format, try for another file + // with the same name. + if (this->object_->searched_for() + && !parameters->is_compatible_target(this->object_->target())) { - // FIXME: We need to close the descriptor here. + Read_symbols::incompatible_warning(this->input_argument_, + this->object_->input_file()); + Read_symbols::requeue(workqueue, this->input_objects_, this->symtab_, + this->layout_, this->dirpath_, this->dirindex_, + this->mapfile_, this->input_argument_, + this->input_group_, this->next_blocker_); + this->object_->release(); + delete this->object_; + } + else if (!this->input_objects_->add_object(this->object_)) + { + this->object_->release(); delete this->object_; } else @@ -490,7 +572,7 @@ Read_script::run(Workqueue* workqueue) { bool used_next_blocker; if (!read_input_script(workqueue, this->symtab_, this->layout_, - this->dirpath_, this->input_objects_, + this->dirpath_, this->dirindex_, this->input_objects_, this->mapfile_, this->input_group_, this->input_argument_, this->input_file_, this->next_blocker_, &used_next_blocker)) |