binutils-gdb/gold/readsyms.h
Ian Lance Taylor 15f8229bbf * 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.
2009-03-14 05:56:46 +00:00

299 lines
7.9 KiB
C++

// readsyms.h -- read input file symbols for gold -*- C++ -*-
// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
#ifndef GOLD_READSYMS_H
#define GOLD_READSYMS_H
#include <vector>
#include "workqueue.h"
#include "object.h"
namespace gold
{
class Input_objects;
class Symbol_table;
class Input_group;
class Archive;
// This Task is responsible for reading the symbols from an input
// file. This also includes reading the relocations so that we can
// check for any that require a PLT and/or a GOT. After the data has
// been read, this queues up another task to actually add the symbols
// to the symbol table. The tasks are separated because the file
// reading can occur in parallel but adding the symbols must be done
// in the order of the input files.
class Read_symbols : public Task
{
public:
// DIRPATH is the list of directories to search for libraries.
// INPUT is the file to read. INPUT_GROUP is not NULL if we are in
// the middle of an input group. THIS_BLOCKER is used to prevent
// the associated Add_symbols task from running before the previous
// one has completed; it will be NULL for the first task.
// NEXT_BLOCKER is used to block the next input file from adding
// symbols.
Read_symbols(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* this_blocker,
Task_token* next_blocker)
: input_objects_(input_objects), symtab_(symtab), layout_(layout),
dirpath_(dirpath), dirindex_(dirindex), mapfile_(mapfile),
input_argument_(input_argument), input_group_(input_group),
this_blocker_(this_blocker), next_blocker_(next_blocker)
{ }
~Read_symbols();
// If appropriate, issue a warning about skipping an incompatible
// object.
static void
incompatible_warning(const Input_argument*, const Input_file*);
// Requeue a Read_symbols task to search for the next object with
// the same name.
static void
requeue(Workqueue*, Input_objects*, Symbol_table*, Layout*, Dirsearch*,
int dirindex, Mapfile*, const Input_argument*, Input_group*,
Task_token* next_blocker);
// The standard Task methods.
Task_token*
is_runnable();
void
locks(Task_locker*);
void
run(Workqueue*);
std::string
get_name() const;
private:
// Handle an archive group.
void
do_group(Workqueue*);
// Open and identify the file.
bool
do_read_symbols(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* this_blocker_;
Task_token* next_blocker_;
};
// This Task handles adding the symbols to the symbol table. These
// tasks must be run in the same order as the arguments appear on the
// command line.
class Add_symbols : public Task
{
public:
// THIS_BLOCKER is used to prevent this task from running before the
// one for the previous input file. NEXT_BLOCKER is used to prevent
// the next task from running.
Add_symbols(Input_objects* input_objects, Symbol_table* symtab,
Layout* layout, Dirsearch* dirpath, int dirindex,
Mapfile* mapfile, const Input_argument* input_argument,
Input_group* input_group, Object* object,
Read_symbols_data* sd, Task_token* this_blocker,
Task_token* next_blocker)
: input_objects_(input_objects), symtab_(symtab), layout_(layout),
dirpath_(dirpath), dirindex_(dirindex), mapfile_(mapfile),
input_argument_(input_argument), input_group_(input_group),
object_(object), sd_(sd), this_blocker_(this_blocker),
next_blocker_(next_blocker)
{ }
~Add_symbols();
// The standard Task methods.
Task_token*
is_runnable();
void
locks(Task_locker*);
void
run(Workqueue*);
std::string
get_name() const
{ return "Add_symbols " + this->object_->name(); }
private:
Input_objects* input_objects_;
Symbol_table* symtab_;
Layout* layout_;
Dirsearch* dirpath_;
int dirindex_;
Mapfile* mapfile_;
const Input_argument* input_argument_;
Input_group* input_group_;
Object* object_;
Read_symbols_data* sd_;
Task_token* this_blocker_;
Task_token* next_blocker_;
};
// This class is used to track the archives in a group.
class Input_group
{
public:
typedef std::vector<Archive*> Archives;
typedef Archives::const_iterator const_iterator;
Input_group()
: archives_()
{ }
// Add an archive to the group.
void
add_archive(Archive* arch)
{ this->archives_.push_back(arch); }
// Loop over the archives in the group.
const_iterator
begin() const
{ return this->archives_.begin(); }
const_iterator
end() const
{ return this->archives_.end(); }
private:
Archives archives_;
};
// This class is used to finish up handling a group. It is just a
// closure.
class Finish_group : public Task
{
public:
Finish_group(Input_objects* input_objects, Symbol_table* symtab,
Layout* layout, Mapfile* mapfile, Input_group* input_group,
int saw_undefined, Task_token* this_blocker,
Task_token* next_blocker)
: input_objects_(input_objects), symtab_(symtab),
layout_(layout), mapfile_(mapfile), input_group_(input_group),
saw_undefined_(saw_undefined), this_blocker_(this_blocker),
next_blocker_(next_blocker)
{ }
~Finish_group();
// The standard Task methods.
Task_token*
is_runnable();
void
locks(Task_locker*);
void
run(Workqueue*);
std::string
get_name() const
{ return "Finish_group"; }
private:
Input_objects* input_objects_;
Symbol_table* symtab_;
Layout* layout_;
Mapfile* mapfile_;
Input_group* input_group_;
int saw_undefined_;
Task_token* this_blocker_;
Task_token* next_blocker_;
};
// This class is used to read a file which was not recognized as an
// object or archive. It tries to read it as a linker script, using
// the tokens to serialize with the calls to Add_symbols.
class Read_script : public Task
{
public:
Read_script(Symbol_table* symtab, Layout* layout, Dirsearch* dirpath,
int dirindex, Input_objects* input_objects, Mapfile* mapfile,
Input_group* input_group, const Input_argument* input_argument,
Input_file* input_file, Task_token* this_blocker,
Task_token* next_blocker)
: symtab_(symtab), layout_(layout), dirpath_(dirpath), dirindex_(dirindex),
input_objects_(input_objects), mapfile_(mapfile),
input_group_(input_group), input_argument_(input_argument),
input_file_(input_file), this_blocker_(this_blocker),
next_blocker_(next_blocker)
{ }
~Read_script();
// The standard Task methods.
Task_token*
is_runnable();
void
locks(Task_locker*);
void
run(Workqueue*);
std::string
get_name() const;
private:
Symbol_table* symtab_;
Layout* layout_;
Dirsearch* dirpath_;
int dirindex_;
Input_objects* input_objects_;
Mapfile* mapfile_;
Input_group* input_group_;
const Input_argument* input_argument_;
Input_file* input_file_;
Task_token* this_blocker_;
Task_token* next_blocker_;
};
} // end namespace gold
#endif // !defined(GOLD_READSYMS_H)