aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/ChangeLog46
-rw-r--r--gold/archive.cc9
-rw-r--r--gold/incremental-dump.cc43
-rw-r--r--gold/incremental.cc52
-rw-r--r--gold/incremental.h45
-rw-r--r--gold/options.cc12
-rw-r--r--gold/options.h33
-rw-r--r--gold/readsyms.cc3
-rw-r--r--gold/script.cc46
-rw-r--r--gold/script.h20
10 files changed, 233 insertions, 76 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 5319a63..9c57a1b 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,49 @@
+2011-03-30 Cary Coutant <ccoutant@google.com>
+
+ * 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 <ccoutant@google.com>
* archive.cc (Library_base::should_include_member): Move
diff --git a/gold/archive.cc b/gold/archive.cc
index 4aafb71..a689722 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 348e795..e59b1c5 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 f7edf04..e5f71f5 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<size, big_endian>::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<size, big_endian>::write_info_blocks(
switch ((*p)->type())
{
case INCREMENTAL_INPUT_SCRIPT:
- // No supplemental info for a script.
+ {
+ gold_assert(static_cast<unsigned int>(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 b55aa71..b799f7b 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<Incremental_input_entry*> 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 6ab2fe9..7e86543 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 d0e42a1..042b8cf 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> 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 9f88b01..a6c0454 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 659a0d2..b56ec1c 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<Version_script_info::Language> 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 e1134ca..fc83905 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