From c7975edd9eba42c2bd59948060d8d5c715456517 Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Wed, 30 Mar 2011 21:07:13 +0000 Subject: [PATCH] * archive.cc (Archive::include_member): Adjust call to report_object. (Add_archive_symbols::run): Add script_info to call to report_archive_begin. (Lib_group::include_member): Adjust call to report_object. (Add_lib_group_symbols::run): Adjust call to report_object. * incremental-dump.cc (dump_incremental_inputs): Remove unnecessary blocks. Add object count for script input files. * incremental.cc (Incremental_inputs::report_archive_begin): Add script_info parameter; change all callers. (Incremental_inputs::report_object): Add script_info parameter; change all callers. (Incremental_inputs::report_script): Store backpointer to incremental info entry. (Output_section_incremental_inputs::set_final_data_size): Record additional information for scripts. (Output_section_incremental_inputs::write_info_blocks): Likewise. * incremental.h (Incremental_script_entry::add_object): New function. (Incremental_script_entry::get_object_count): New function. (Incremental_script_entry::get_object): New function. (Incremental_script_entry::objects_): New data member; adjust constructor. (Incremental_inputs::report_archive_begin): Add script_info parameter. (Incremental_inputs::report_object): Add script_info parameter. (Incremental_inputs_reader::get_object_count): New function. (Incremental_inputs_reader::get_object_offset): New function. * options.cc (Input_arguments::add_file): Return reference to new input argument. * options.h (Input_argument::set_script_info): New function. (Input_argument::script_info): New function. (Input_argument::script_info_): New data member; adjust all constructors. (Input_file_group::add_file): Return reference to new input argument. (Input_file_lib::add_file): Likewise. (Input_arguments::add_file): Likewise. * readsyms.cc (Add_symbols::run): Adjust call to report_object. * script.cc (Parser_closure::Parser_closure): Add script_info parameter; adjust all callers. (Parser_closure::script_info): New function. (Parser_closure::script_info_): New data member. (read_input_script): Report scripts earlier to incremental info. (script_add_file): Set script_info in Input_argument. (script_add_library): Likewise. * script.h (Script_options::Script_info): Rewrite class. --- gold/ChangeLog | 46 +++++++++++++++++++++++++++++++++++ gold/archive.cc | 9 +++---- gold/incremental-dump.cc | 43 ++++++++++++++------------------- gold/incremental.cc | 52 ++++++++++++++++++++++++++++++++++++---- gold/incremental.h | 45 +++++++++++++++++++++++++++++++--- gold/options.cc | 12 +++++----- gold/options.h | 33 ++++++++++++++++++------- gold/readsyms.cc | 3 ++- gold/script.cc | 46 ++++++++++++++++++++++------------- gold/script.h | 20 ++++++++++------ 10 files changed, 233 insertions(+), 76 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 5319a639440..9c57a1baa16 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,49 @@ +2011-03-30 Cary Coutant + + * archive.cc (Archive::include_member): Adjust call to report_object. + (Add_archive_symbols::run): Add script_info to call to + report_archive_begin. + (Lib_group::include_member): Adjust call to report_object. + (Add_lib_group_symbols::run): Adjust call to report_object. + * incremental-dump.cc (dump_incremental_inputs): Remove unnecessary + blocks. Add object count for script input files. + * incremental.cc (Incremental_inputs::report_archive_begin): Add + script_info parameter; change all callers. + (Incremental_inputs::report_object): Add script_info parameter; + change all callers. + (Incremental_inputs::report_script): Store backpointer to + incremental info entry. + (Output_section_incremental_inputs::set_final_data_size): Record + additional information for scripts. + (Output_section_incremental_inputs::write_info_blocks): Likewise. + * incremental.h (Incremental_script_entry::add_object): New function. + (Incremental_script_entry::get_object_count): New function. + (Incremental_script_entry::get_object): New function. + (Incremental_script_entry::objects_): New data member; adjust + constructor. + (Incremental_inputs::report_archive_begin): Add script_info parameter. + (Incremental_inputs::report_object): Add script_info parameter. + (Incremental_inputs_reader::get_object_count): New function. + (Incremental_inputs_reader::get_object_offset): New function. + * options.cc (Input_arguments::add_file): Return reference to + new input argument. + * options.h (Input_argument::set_script_info): New function. + (Input_argument::script_info): New function. + (Input_argument::script_info_): New data member; adjust all + constructors. + (Input_file_group::add_file): Return reference to new input argument. + (Input_file_lib::add_file): Likewise. + (Input_arguments::add_file): Likewise. + * readsyms.cc (Add_symbols::run): Adjust call to report_object. + * script.cc (Parser_closure::Parser_closure): Add script_info + parameter; adjust all callers. + (Parser_closure::script_info): New function. + (Parser_closure::script_info_): New data member. + (read_input_script): Report scripts earlier to incremental info. + (script_add_file): Set script_info in Input_argument. + (script_add_library): Likewise. + * script.h (Script_options::Script_info): Rewrite class. + 2011-03-29 Cary Coutant * archive.cc (Library_base::should_include_member): Move diff --git a/gold/archive.cc b/gold/archive.cc index 4aafb71664d..a689722ba38 100644 --- a/gold/archive.cc +++ b/gold/archive.cc @@ -960,7 +960,7 @@ Archive::include_member(Symbol_table* symtab, Layout* layout, { { if (layout->incremental_inputs() != NULL) - layout->incremental_inputs()->report_object(obj, this); + layout->incremental_inputs()->report_object(obj, this, NULL); Read_symbols_data sd; obj->read_symbols(&sd); obj->layout(symtab, layout, &sd); @@ -1040,7 +1040,8 @@ Add_archive_symbols::run(Workqueue* workqueue) // For an incremental link, begin recording layout information. Incremental_inputs* incremental_inputs = this->layout_->incremental_inputs(); if (incremental_inputs != NULL) - incremental_inputs->report_archive_begin(this->archive_); + incremental_inputs->report_archive_begin(this->archive_, + this->input_argument_->script_info()); bool added = this->archive_->add_symbols(this->symtab_, this->layout_, this->input_objects_, @@ -1196,7 +1197,7 @@ Lib_group::include_member(Symbol_table* symtab, Layout* layout, if (input_objects->add_object(obj)) { if (layout->incremental_inputs() != NULL) - layout->incremental_inputs()->report_object(obj, this); + layout->incremental_inputs()->report_object(obj, this, NULL); obj->layout(symtab, layout, sd); obj->add_symbols(symtab, sd, layout); } @@ -1256,7 +1257,7 @@ Add_lib_group_symbols::run(Workqueue*) // For an incremental link, begin recording layout information. Incremental_inputs* incremental_inputs = this->layout_->incremental_inputs(); if (incremental_inputs != NULL) - incremental_inputs->report_archive_begin(this->lib_); + incremental_inputs->report_archive_begin(this->lib_, NULL); this->lib_->add_symbols(this->symtab_, this->layout_, this->input_objects_); diff --git a/gold/incremental-dump.cc b/gold/incremental-dump.cc index 348e795fc66..e59b1c5f5b1 100644 --- a/gold/incremental-dump.cc +++ b/gold/incremental-dump.cc @@ -158,40 +158,33 @@ dump_incremental_inputs(const char* argv0, const char* filename, switch (input_type) { case INCREMENTAL_INPUT_OBJECT: - { - printf("Object\n"); - printf(" Input section count: %d\n", - input_file.get_input_section_count()); - printf(" Symbol count: %d\n", - input_file.get_global_symbol_count()); - } + printf("Object\n"); + printf(" Input section count: %d\n", + input_file.get_input_section_count()); + printf(" Symbol count: %d\n", + input_file.get_global_symbol_count()); break; case INCREMENTAL_INPUT_ARCHIVE_MEMBER: - { - printf("Archive member\n"); - printf(" Input section count: %d\n", - input_file.get_input_section_count()); - printf(" Symbol count: %d\n", - input_file.get_global_symbol_count()); - } + printf("Archive member\n"); + printf(" Input section count: %d\n", + input_file.get_input_section_count()); + printf(" Symbol count: %d\n", + input_file.get_global_symbol_count()); break; case INCREMENTAL_INPUT_ARCHIVE: - { - printf("Archive\n"); - printf(" Member count: %d\n", input_file.get_member_count()); - printf(" Unused symbol count: %d\n", - input_file.get_unused_symbol_count()); - } + printf("Archive\n"); + printf(" Member count: %d\n", input_file.get_member_count()); + printf(" Unused symbol count: %d\n", + input_file.get_unused_symbol_count()); break; case INCREMENTAL_INPUT_SHARED_LIBRARY: - { - printf("Shared library\n"); - printf(" Symbol count: %d\n", - input_file.get_global_symbol_count()); - } + printf("Shared library\n"); + printf(" Symbol count: %d\n", + input_file.get_global_symbol_count()); break; case INCREMENTAL_INPUT_SCRIPT: printf("Linker script\n"); + printf(" Object count: %d\n", input_file.get_object_count()); break; default: fprintf(stderr, "%s: invalid file type for object %u: %d\n", diff --git a/gold/incremental.cc b/gold/incremental.cc index f7edf0427ad..e5f71f5ed66 100644 --- a/gold/incremental.cc +++ b/gold/incremental.cc @@ -436,7 +436,8 @@ Incremental_inputs::report_command_line(int argc, const char* const* argv) // input objects until report_archive_end is called. void -Incremental_inputs::report_archive_begin(Library_base* arch) +Incremental_inputs::report_archive_begin(Library_base* arch, + Script_info* script_info) { Stringpool::Key filename_key; Timespec mtime = arch->get_mtime(); @@ -446,6 +447,13 @@ Incremental_inputs::report_archive_begin(Library_base* arch) new Incremental_archive_entry(filename_key, mtime); arch->set_incremental_info(entry); this->inputs_.push_back(entry); + + if (script_info != NULL) + { + Incremental_script_entry* script_entry = script_info->incremental_info(); + gold_assert(script_entry != NULL); + script_entry->add_object(entry); + } } // Visitor class for processing the unused global symbols in a library. @@ -496,7 +504,8 @@ Incremental_inputs::report_archive_end(Library_base* arch) // Add_symbols task after finding out the type of the file. void -Incremental_inputs::report_object(Object* obj, Library_base* arch) +Incremental_inputs::report_object(Object* obj, Library_base* arch, + Script_info* script_info) { Stringpool::Key filename_key; Timespec mtime = obj->input_file()->file().get_mtime(); @@ -513,6 +522,13 @@ Incremental_inputs::report_object(Object* obj, Library_base* arch) arch_entry->add_object(obj_entry); } + if (script_info != NULL) + { + Incremental_script_entry* script_entry = script_info->incremental_info(); + gold_assert(script_entry != NULL); + script_entry->add_object(obj_entry); + } + this->current_object_ = obj; this->current_object_entry_ = obj_entry; } @@ -548,6 +564,7 @@ Incremental_inputs::report_script(const std::string& filename, Incremental_script_entry* entry = new Incremental_script_entry(filename_key, script, mtime); this->inputs_.push_back(entry); + script->set_incremental_info(entry); } // Finalize the incremental link information. Called from @@ -640,8 +657,15 @@ Output_section_incremental_inputs::set_final_data_size() switch ((*p)->type()) { case INCREMENTAL_INPUT_SCRIPT: - // No supplemental info for a script. - (*p)->set_info_offset(0); + { + Incremental_script_entry *entry = (*p)->script_entry(); + gold_assert(entry != NULL); + (*p)->set_info_offset(info_offset); + // Object count. + info_offset += 4; + // Each member. + info_offset += (entry->get_object_count() * 4); + } break; case INCREMENTAL_INPUT_OBJECT: case INCREMENTAL_INPUT_ARCHIVE_MEMBER: @@ -845,7 +869,25 @@ Output_section_incremental_inputs::write_info_blocks( switch ((*p)->type()) { case INCREMENTAL_INPUT_SCRIPT: - // No supplemental info for a script. + { + gold_assert(static_cast(pov - oview) + == (*p)->get_info_offset()); + Incremental_script_entry* entry = (*p)->script_entry(); + gold_assert(entry != NULL); + + // Write the object count. + unsigned int nobjects = entry->get_object_count(); + Swap32::writeval(pov, nobjects); + pov += 4; + + // For each object, write the offset to its input file entry. + for (unsigned int i = 0; i < nobjects; ++i) + { + Incremental_input_entry* obj = entry->get_object(i); + Swap32::writeval(pov, obj->get_offset()); + pov += 4; + } + } break; case INCREMENTAL_INPUT_OBJECT: diff --git a/gold/incremental.h b/gold/incremental.h index b55aa7135d0..b799f7bcffb 100644 --- a/gold/incremental.h +++ b/gold/incremental.h @@ -342,9 +342,29 @@ class Incremental_script_entry : public Incremental_input_entry public: Incremental_script_entry(Stringpool::Key filename_key, Script_info* script, Timespec mtime) - : Incremental_input_entry(filename_key, mtime), script_(script) + : Incremental_input_entry(filename_key, mtime), script_(script), objects_() { } + // Add a member object to the archive. + void + add_object(Incremental_input_entry* obj_entry) + { + this->objects_.push_back(obj_entry); + } + + // Return the number of objects included by this script. + unsigned int + get_object_count() + { return this->objects_.size(); } + + // Return the Nth object. + Incremental_input_entry* + get_object(unsigned int n) + { + gold_assert(n < this->objects_.size()); + return this->objects_[n]; + } + protected: virtual Incremental_input_type do_type() const @@ -358,6 +378,8 @@ class Incremental_script_entry : public Incremental_input_entry private: // Information about the script file. Script_info* script_; + // Objects that have been included by this script. + std::vector objects_; }; // Class for recording input object files. @@ -530,7 +552,7 @@ class Incremental_inputs // Record the initial info for archive file ARCHIVE. void - report_archive_begin(Library_base* arch); + report_archive_begin(Library_base* arch, Script_info* script_info); // Record the final info for archive file ARCHIVE. void @@ -539,7 +561,7 @@ class Incremental_inputs // Record the info for object file OBJ. If ARCH is not NULL, // attach the object file to the archive. void - report_object(Object* obj, Library_base* arch); + report_object(Object* obj, Library_base* arch, Script_info* script_info); // Record an input section belonging to object file OBJ. void @@ -765,6 +787,23 @@ class Incremental_inputs_reader } } + // Return the object count -- for scripts only. + unsigned int + get_object_count() const + { + gold_assert(this->type_ == INCREMENTAL_INPUT_SCRIPT); + return Swap32::readval(this->inputs_->p_ + this->info_offset_); + } + + // Return the input file offset for object N -- for scripts only. + unsigned int + get_object_offset(unsigned int n) const + { + gold_assert(this->type_ == INCREMENTAL_INPUT_SCRIPT); + return Swap32::readval(this->inputs_->p_ + this->info_offset_ + + 4 + n * 4); + } + // Return the member count -- for archives only. unsigned int get_member_count() const diff --git a/gold/options.cc b/gold/options.cc index 6ab2fe9dba4..7e86543ae2d 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -1214,23 +1214,23 @@ Search_directory::add_sysroot(const char* sysroot, // Add a file to the list. -void +Input_argument& Input_arguments::add_file(const Input_file_argument& file) { if (this->in_group_) { gold_assert(!this->input_argument_list_.empty()); gold_assert(this->input_argument_list_.back().is_group()); - this->input_argument_list_.back().group()->add_file(file); + return this->input_argument_list_.back().group()->add_file(file); } - else if (this->in_lib_) + if (this->in_lib_) { gold_assert(!this->input_argument_list_.empty()); gold_assert(this->input_argument_list_.back().is_lib()); - this->input_argument_list_.back().lib()->add_file(file); + return this->input_argument_list_.back().lib()->add_file(file); } - else - this->input_argument_list_.push_back(Input_argument(file)); + this->input_argument_list_.push_back(Input_argument(file)); + return this->input_argument_list_.back(); } // Start a group. diff --git a/gold/options.h b/gold/options.h index d0e42a18b20..042b8cf1940 100644 --- a/gold/options.h +++ b/gold/options.h @@ -1599,17 +1599,17 @@ class Input_argument public: // Create a file or library argument. explicit Input_argument(Input_file_argument file) - : is_file_(true), file_(file), group_(NULL), lib_(NULL) + : is_file_(true), file_(file), group_(NULL), lib_(NULL), script_info_(NULL) { } // Create a group argument. explicit Input_argument(Input_file_group* group) - : is_file_(false), group_(group), lib_(NULL) + : is_file_(false), group_(group), lib_(NULL), script_info_(NULL) { } // Create a lib argument. explicit Input_argument(Input_file_lib* lib) - : is_file_(false), group_(NULL), lib_(lib) + : is_file_(false), group_(NULL), lib_(lib), script_info_(NULL) { } // Return whether this is a file. @@ -1667,11 +1667,22 @@ class Input_argument return this->lib_; } + // If a script generated this argument, store a pointer to the script info. + // Currently used only for recording incremental link information. + void + set_script_info(Script_info* info) + { this->script_info_ = info; } + + Script_info* + script_info() const + { return this->script_info_; } + private: bool is_file_; Input_file_argument file_; Input_file_group* group_; Input_file_lib* lib_; + Script_info* script_info_; }; typedef std::vector Input_argument_list; @@ -1689,9 +1700,12 @@ class Input_file_group { } // Add a file to the end of the group. - void + Input_argument& add_file(const Input_file_argument& arg) - { this->files_.push_back(Input_argument(arg)); } + { + this->files_.push_back(Input_argument(arg)); + return this->files_.back(); + } // Iterators to iterate over the group contents. @@ -1720,9 +1734,12 @@ class Input_file_lib { } // Add a file to the end of the lib. - void + Input_argument& add_file(const Input_file_argument& arg) - { this->files_.push_back(Input_argument(arg)); } + { + this->files_.push_back(Input_argument(arg)); + return this->files_.back(); + } const Position_dependent_options& options() const @@ -1759,7 +1776,7 @@ class Input_arguments { } // Add a file. - void + Input_argument& add_file(const Input_file_argument& arg); // Start a group (the --start-group option). diff --git a/gold/readsyms.cc b/gold/readsyms.cc index 9f88b01d8b9..a6c04544e74 100644 --- a/gold/readsyms.cc +++ b/gold/readsyms.cc @@ -590,7 +590,8 @@ Add_symbols::run(Workqueue*) Incremental_inputs* incremental_inputs = this->layout_->incremental_inputs(); if (incremental_inputs != NULL) - incremental_inputs->report_object(this->object_, NULL); + incremental_inputs->report_object(this->object_, NULL, + this->input_argument_->script_info()); this->object_->layout(this->symtab_, this->layout_, this->sd_); this->object_->add_symbols(this->symtab_, this->sd_, this->layout_); delete this->sd_; diff --git a/gold/script.cc b/gold/script.cc index 659a0d2ee65..b56ec1cbb9d 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -1206,7 +1206,8 @@ class Parser_closure Command_line* command_line, Script_options* script_options, Lex* lex, - bool skip_on_incompatible_target) + bool skip_on_incompatible_target, + Script_info* script_info) : filename_(filename), posdep_options_(posdep_options), parsing_defsym_(parsing_defsym), in_group_(in_group), is_in_sysroot_(is_in_sysroot), @@ -1214,7 +1215,8 @@ class Parser_closure found_incompatible_target_(false), command_line_(command_line), script_options_(script_options), version_script_info_(script_options->version_script_info()), - lex_(lex), lineno_(0), charpos_(0), lex_mode_stack_(), inputs_(NULL) + lex_(lex), lineno_(0), charpos_(0), lex_mode_stack_(), inputs_(NULL), + script_info_(script_info) { // We start out processing C symbols in the default lex mode. this->language_stack_.push_back(Version_script_info::LANGUAGE_C); @@ -1365,6 +1367,11 @@ class Parser_closure this->language_stack_.pop_back(); } + // Return a pointer to the incremental info. + Script_info* + script_info() + { return this->script_info_; } + private: // The name of the file we are reading. const char* filename_; @@ -1401,6 +1408,8 @@ class Parser_closure std::vector language_stack_; // New input files found to add to the link. Input_arguments* inputs_; + // Pointer to incremental linking info. + Script_info* script_info_; }; // FILE was found as an argument on the command line. Try to read it @@ -1422,6 +1431,15 @@ read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout, Lex lex(input_string.c_str(), input_string.length(), PARSING_LINKER_SCRIPT); + Script_info* script_info = NULL; + if (layout->incremental_inputs() != NULL) + { + const std::string& filename = input_file->filename(); + Timespec mtime = input_file->file().get_mtime(); + script_info = new Script_info(); + layout->incremental_inputs()->report_script(filename, script_info, mtime); + } + Parser_closure closure(input_file->filename().c_str(), input_argument->file().options(), false, @@ -1430,7 +1448,8 @@ read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout, NULL, layout->script_options(), &lex, - input_file->will_search_for()); + input_file->will_search_for(), + script_info); bool old_saw_sections_clause = layout->script_options()->saw_sections_clause(); @@ -1476,16 +1495,6 @@ read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout, this_blocker = nb; } - if (layout->incremental_inputs() != NULL) - { - // Like new Read_symbols(...) above, we rely on closure.inputs() - // getting leaked by closure. - const std::string& filename = input_file->filename(); - Script_info* info = new Script_info(closure.inputs()); - Timespec mtime = input_file->file().get_mtime(); - layout->incremental_inputs()->report_script(filename, info, mtime); - } - *used_next_blocker = true; return true; @@ -1535,7 +1544,8 @@ read_script_file(const char* filename, Command_line* cmdline, cmdline, script_options, &lex, - false); + false, + NULL); if (yyparse(&closure) != 0) { input_file.file().unlock(task); @@ -1594,7 +1604,7 @@ Script_options::define_symbol(const char* definition) Position_dependent_options posdep_options; Parser_closure closure("command line", posdep_options, true, - false, false, NULL, this, &lex, false); + false, false, NULL, this, &lex, false, NULL); if (yyparse(&closure) != 0) return false; @@ -2620,7 +2630,8 @@ script_add_file(void* closurev, const char* name, size_t length) Input_file_argument::INPUT_FILE_TYPE_FILE, extra_search_path, false, closure->position_dependent_options()); - closure->inputs()->add_file(file); + Input_argument& arg = closure->inputs()->add_file(file); + arg.set_script_info(closure->script_info()); } // Called by the bison parser to add a library to the link. @@ -2638,7 +2649,8 @@ script_add_library(void* closurev, const char* name, size_t length) Input_file_argument::INPUT_FILE_TYPE_LIBRARY, "", false, closure->position_dependent_options()); - closure->inputs()->add_file(file); + Input_argument& arg = closure->inputs()->add_file(file); + arg.set_script_info(closure->script_info()); } // Called by the bison parser to start a group. If we are already in diff --git a/gold/script.h b/gold/script.h index e1134ca2861..fc83905f090 100644 --- a/gold/script.h +++ b/gold/script.h @@ -57,6 +57,7 @@ struct Version_expression_list; struct Version_tree; struct Version_expression; class Lazy_demangler; +class Incremental_script_entry; // This class represents an expression in a linker script. @@ -554,17 +555,22 @@ class Script_options class Script_info { public: - Script_info(Input_arguments* inputs) - : inputs_(inputs) + Script_info() + : incremental_script_entry_(NULL) { } - // Returns the input files included because of this script. - Input_arguments* - inputs() - { return this->inputs_; } + // Store a pointer to the incremental information for this script. + void + set_incremental_info(Incremental_script_entry* entry) + { this->incremental_script_entry_ = entry; } + + // Return the pointer to the incremental information for this script. + Incremental_script_entry* + incremental_info() const + { return this->incremental_script_entry_; } private: - Input_arguments* inputs_; + Incremental_script_entry* incremental_script_entry_; }; // FILE was found as an argument on the command line, but was not -- 2.30.2