* 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.
This commit is contained in:
Cary Coutant 2011-03-30 21:07:13 +00:00
parent ef23e70580
commit c7975edd9e
10 changed files with 233 additions and 76 deletions

View File

@ -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

View File

@ -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_);

View File

@ -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",

View File

@ -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:

View File

@ -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

View File

@ -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.

View File

@ -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).

View File

@ -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_;

View File

@ -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

View File

@ -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