123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- // readsyms.h -- read input file symbols for gold -*- C++ -*-
- // Copyright (C) 2006-2015 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"
- #include "incremental.h"
- namespace gold
- {
- class Input_objects;
- class Symbol_table;
- class Input_group;
- class Archive;
- class Finish_group;
- // 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, Archive_member* member,
- 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),
- member_(member), 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*);
- // Handle --start-lib ... --end-lib
- bool
- do_lib_group(Workqueue*);
- // Handle --whole-archive --start-lib ... --end-lib --no-whole-archive
- bool
- do_whole_lib_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_;
- Archive_member* member_;
- 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,
- Object* object, Incremental_library* library,
- Read_symbols_data* sd, Task_token* this_blocker,
- Task_token* next_blocker)
- : input_objects_(input_objects), symtab_(symtab), layout_(layout),
- input_argument_(input_argument), object_(object), library_(library),
- 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_;
- const Input_argument* input_argument_;
- Object* object_;
- Incremental_library* library_;
- Read_symbols_data* sd_;
- Task_token* this_blocker_;
- Task_token* next_blocker_;
- };
- // This Task is responsible for reading the symbols from an archive
- // member that has changed since the last incremental link.
- class Read_member : public Task
- {
- public:
- // 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_member(Input_objects* /*input_objects*/, Symbol_table* /*symtab*/,
- Layout* /*layout*/, Mapfile* /*mapfile*/,
- const Incremental_binary::Input_reader* input_reader,
- Task_token* this_blocker, Task_token* next_blocker)
- : input_reader_(input_reader),
- this_blocker_(this_blocker), next_blocker_(next_blocker)
- { }
- ~Read_member();
- // The standard Task methods.
- Task_token*
- is_runnable();
- void
- locks(Task_locker*);
- void
- run(Workqueue*);
- std::string
- get_name() const
- {
- return (std::string("Read_member ") + this->input_reader_->filename());
- }
- private:
- const Incremental_binary::Input_reader* input_reader_;
- Task_token* this_blocker_;
- Task_token* next_blocker_;
- };
- // This Task is responsible for processing an input script file that has
- // not changed since the last incremental link.
- class Check_script : public Task
- {
- public:
- Check_script(Layout* layout, Incremental_binary* ibase,
- unsigned int input_file_index,
- const Incremental_binary::Input_reader* input_reader,
- Task_token* this_blocker, Task_token* next_blocker)
- : layout_(layout), ibase_(ibase), input_file_index_(input_file_index),
- input_reader_(input_reader), this_blocker_(this_blocker),
- next_blocker_(next_blocker)
- {
- this->filename_ = std::string(this->input_reader_->filename());
- }
- ~Check_script();
- // The standard Task methods.
- Task_token*
- is_runnable();
- void
- locks(Task_locker*);
- void
- run(Workqueue*);
- std::string
- get_name() const
- {
- return (std::string("Check_script ") + this->input_reader_->filename());
- }
- private:
- std::string filename_;
- Layout* layout_;
- Incremental_binary* ibase_;
- unsigned int input_file_index_;
- const Incremental_binary::Input_reader* input_reader_;
- Task_token* this_blocker_;
- Task_token* next_blocker_;
- };
- // This Task is responsible for processing an archive library that has
- // not changed since the last incremental link.
- class Check_library : public Task
- {
- public:
- Check_library(Symbol_table* /*symtab*/, Layout* layout,
- Incremental_binary* ibase,
- unsigned int input_file_index,
- const Incremental_binary::Input_reader* input_reader,
- Task_token* this_blocker, Task_token* next_blocker)
- : layout_(layout), ibase_(ibase),
- input_file_index_(input_file_index), input_reader_(input_reader),
- this_blocker_(this_blocker), next_blocker_(next_blocker)
- { }
- ~Check_library();
- // The standard Task methods.
- Task_token*
- is_runnable();
- void
- locks(Task_locker*);
- void
- run(Workqueue*);
- std::string
- get_name() const
- {
- return (std::string("Check_library ") + this->input_reader_->filename());
- }
- private:
- Layout* layout_;
- Incremental_binary* ibase_;
- unsigned int input_file_index_;
- const Incremental_binary::Input_reader* input_reader_;
- 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_()
- { }
- ~Input_group();
- // 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 starts the handling of a group. It exists only to pick
- // up the number of undefined symbols at that point, so that we only
- // run back through the group if we saw a new undefined symbol.
- class Start_group : public Task
- {
- public:
- Start_group(Symbol_table* symtab, Finish_group* finish_group,
- Task_token* this_blocker, Task_token* next_blocker)
- : symtab_(symtab), finish_group_(finish_group),
- this_blocker_(this_blocker), next_blocker_(next_blocker)
- { }
- ~Start_group();
- // The standard Task methods.
- Task_token*
- is_runnable();
- void
- locks(Task_locker*);
- void
- run(Workqueue*);
- std::string
- get_name() const
- { return "Start_group"; }
- private:
- Symbol_table* symtab_;
- Finish_group* finish_group_;
- Task_token* this_blocker_;
- Task_token* next_blocker_;
- };
- // 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,
- Task_token* next_blocker)
- : input_objects_(input_objects), symtab_(symtab),
- layout_(layout), mapfile_(mapfile), input_group_(input_group),
- saw_undefined_(0), this_blocker_(NULL), next_blocker_(next_blocker)
- { }
- ~Finish_group();
- // Set the number of undefined symbols when we start processing the
- // group. This is called by the Start_group task.
- void
- set_saw_undefined(size_t saw_undefined)
- { this->saw_undefined_ = saw_undefined; }
- // Set the blocker to use for this task.
- void
- set_blocker(Task_token* this_blocker)
- {
- gold_assert(this->this_blocker_ == NULL);
- this->this_blocker_ = this_blocker;
- }
- // 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_;
- size_t 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)
|