xref: /dflybsd-src/contrib/binutils-2.27/gold/readsyms.h (revision e656dc90e3d65d744d534af2f5ea88cf8101ebcf)
1*a9fa9459Szrj // readsyms.h -- read input file symbols for gold   -*- C++ -*-
2*a9fa9459Szrj 
3*a9fa9459Szrj // Copyright (C) 2006-2016 Free Software Foundation, Inc.
4*a9fa9459Szrj // Written by Ian Lance Taylor <iant@google.com>.
5*a9fa9459Szrj 
6*a9fa9459Szrj // This file is part of gold.
7*a9fa9459Szrj 
8*a9fa9459Szrj // This program is free software; you can redistribute it and/or modify
9*a9fa9459Szrj // it under the terms of the GNU General Public License as published by
10*a9fa9459Szrj // the Free Software Foundation; either version 3 of the License, or
11*a9fa9459Szrj // (at your option) any later version.
12*a9fa9459Szrj 
13*a9fa9459Szrj // This program is distributed in the hope that it will be useful,
14*a9fa9459Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
15*a9fa9459Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*a9fa9459Szrj // GNU General Public License for more details.
17*a9fa9459Szrj 
18*a9fa9459Szrj // You should have received a copy of the GNU General Public License
19*a9fa9459Szrj // along with this program; if not, write to the Free Software
20*a9fa9459Szrj // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21*a9fa9459Szrj // MA 02110-1301, USA.
22*a9fa9459Szrj 
23*a9fa9459Szrj #ifndef GOLD_READSYMS_H
24*a9fa9459Szrj #define GOLD_READSYMS_H
25*a9fa9459Szrj 
26*a9fa9459Szrj #include <vector>
27*a9fa9459Szrj 
28*a9fa9459Szrj #include "workqueue.h"
29*a9fa9459Szrj #include "object.h"
30*a9fa9459Szrj #include "incremental.h"
31*a9fa9459Szrj 
32*a9fa9459Szrj namespace gold
33*a9fa9459Szrj {
34*a9fa9459Szrj 
35*a9fa9459Szrj class Input_objects;
36*a9fa9459Szrj class Symbol_table;
37*a9fa9459Szrj class Input_group;
38*a9fa9459Szrj class Archive;
39*a9fa9459Szrj class Finish_group;
40*a9fa9459Szrj 
41*a9fa9459Szrj // This Task is responsible for reading the symbols from an input
42*a9fa9459Szrj // file.  This also includes reading the relocations so that we can
43*a9fa9459Szrj // check for any that require a PLT and/or a GOT.  After the data has
44*a9fa9459Szrj // been read, this queues up another task to actually add the symbols
45*a9fa9459Szrj // to the symbol table.  The tasks are separated because the file
46*a9fa9459Szrj // reading can occur in parallel but adding the symbols must be done
47*a9fa9459Szrj // in the order of the input files.
48*a9fa9459Szrj 
49*a9fa9459Szrj class Read_symbols : public Task
50*a9fa9459Szrj {
51*a9fa9459Szrj  public:
52*a9fa9459Szrj   // DIRPATH is the list of directories to search for libraries.
53*a9fa9459Szrj   // INPUT is the file to read.  INPUT_GROUP is not NULL if we are in
54*a9fa9459Szrj   // the middle of an input group.  THIS_BLOCKER is used to prevent
55*a9fa9459Szrj   // the associated Add_symbols task from running before the previous
56*a9fa9459Szrj   // one has completed; it will be NULL for the first task.
57*a9fa9459Szrj   // NEXT_BLOCKER is used to block the next input file from adding
58*a9fa9459Szrj   // 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)59*a9fa9459Szrj   Read_symbols(Input_objects* input_objects, Symbol_table* symtab,
60*a9fa9459Szrj 	       Layout* layout, Dirsearch* dirpath, int dirindex,
61*a9fa9459Szrj 	       Mapfile* mapfile, const Input_argument* input_argument,
62*a9fa9459Szrj 	       Input_group* input_group, Archive_member* member,
63*a9fa9459Szrj                Task_token* this_blocker, Task_token* next_blocker)
64*a9fa9459Szrj     : input_objects_(input_objects), symtab_(symtab), layout_(layout),
65*a9fa9459Szrj       dirpath_(dirpath), dirindex_(dirindex), mapfile_(mapfile),
66*a9fa9459Szrj       input_argument_(input_argument), input_group_(input_group),
67*a9fa9459Szrj       member_(member), this_blocker_(this_blocker),
68*a9fa9459Szrj       next_blocker_(next_blocker)
69*a9fa9459Szrj   { }
70*a9fa9459Szrj 
71*a9fa9459Szrj   ~Read_symbols();
72*a9fa9459Szrj 
73*a9fa9459Szrj   // If appropriate, issue a warning about skipping an incompatible
74*a9fa9459Szrj   // object.
75*a9fa9459Szrj   static void
76*a9fa9459Szrj   incompatible_warning(const Input_argument*, const Input_file*);
77*a9fa9459Szrj 
78*a9fa9459Szrj   // Requeue a Read_symbols task to search for the next object with
79*a9fa9459Szrj   // the same name.
80*a9fa9459Szrj   static void
81*a9fa9459Szrj   requeue(Workqueue*, Input_objects*, Symbol_table*, Layout*, Dirsearch*,
82*a9fa9459Szrj 	  int dirindex, Mapfile*, const Input_argument*, Input_group*,
83*a9fa9459Szrj 	  Task_token* next_blocker);
84*a9fa9459Szrj 
85*a9fa9459Szrj   // The standard Task methods.
86*a9fa9459Szrj 
87*a9fa9459Szrj   Task_token*
88*a9fa9459Szrj   is_runnable();
89*a9fa9459Szrj 
90*a9fa9459Szrj   void
91*a9fa9459Szrj   locks(Task_locker*);
92*a9fa9459Szrj 
93*a9fa9459Szrj   void
94*a9fa9459Szrj   run(Workqueue*);
95*a9fa9459Szrj 
96*a9fa9459Szrj   std::string
97*a9fa9459Szrj   get_name() const;
98*a9fa9459Szrj 
99*a9fa9459Szrj  private:
100*a9fa9459Szrj   // Handle an archive group.
101*a9fa9459Szrj   void
102*a9fa9459Szrj   do_group(Workqueue*);
103*a9fa9459Szrj 
104*a9fa9459Szrj   // Handle --start-lib ... --end-lib
105*a9fa9459Szrj   bool
106*a9fa9459Szrj   do_lib_group(Workqueue*);
107*a9fa9459Szrj 
108*a9fa9459Szrj   // Handle --whole-archive --start-lib ... --end-lib --no-whole-archive
109*a9fa9459Szrj   bool
110*a9fa9459Szrj   do_whole_lib_group(Workqueue*);
111*a9fa9459Szrj 
112*a9fa9459Szrj   // Open and identify the file.
113*a9fa9459Szrj   bool
114*a9fa9459Szrj   do_read_symbols(Workqueue*);
115*a9fa9459Szrj 
116*a9fa9459Szrj   Input_objects* input_objects_;
117*a9fa9459Szrj   Symbol_table* symtab_;
118*a9fa9459Szrj   Layout* layout_;
119*a9fa9459Szrj   Dirsearch* dirpath_;
120*a9fa9459Szrj   int dirindex_;
121*a9fa9459Szrj   Mapfile* mapfile_;
122*a9fa9459Szrj   const Input_argument* input_argument_;
123*a9fa9459Szrj   Input_group* input_group_;
124*a9fa9459Szrj   Archive_member* member_;
125*a9fa9459Szrj   Task_token* this_blocker_;
126*a9fa9459Szrj   Task_token* next_blocker_;
127*a9fa9459Szrj };
128*a9fa9459Szrj 
129*a9fa9459Szrj // This Task handles adding the symbols to the symbol table.  These
130*a9fa9459Szrj // tasks must be run in the same order as the arguments appear on the
131*a9fa9459Szrj // command line.
132*a9fa9459Szrj 
133*a9fa9459Szrj class Add_symbols : public Task
134*a9fa9459Szrj {
135*a9fa9459Szrj  public:
136*a9fa9459Szrj   // THIS_BLOCKER is used to prevent this task from running before the
137*a9fa9459Szrj   // one for the previous input file.  NEXT_BLOCKER is used to prevent
138*a9fa9459Szrj   // the next task from running.
Add_symbols(Input_objects * input_objects,Symbol_table * symtab,Layout * layout,Dirsearch *,int,Mapfile *,const Input_argument * input_argument,Object * object,Incremental_library * library,Read_symbols_data * sd,Task_token * this_blocker,Task_token * next_blocker)139*a9fa9459Szrj   Add_symbols(Input_objects* input_objects, Symbol_table* symtab,
140*a9fa9459Szrj 	      Layout* layout, Dirsearch* /*dirpath*/, int /*dirindex*/,
141*a9fa9459Szrj 	      Mapfile* /*mapfile*/, const Input_argument* input_argument,
142*a9fa9459Szrj 	      Object* object, Incremental_library* library,
143*a9fa9459Szrj 	      Read_symbols_data* sd, Task_token* this_blocker,
144*a9fa9459Szrj 	      Task_token* next_blocker)
145*a9fa9459Szrj     : input_objects_(input_objects), symtab_(symtab), layout_(layout),
146*a9fa9459Szrj       input_argument_(input_argument), object_(object), library_(library),
147*a9fa9459Szrj       sd_(sd), this_blocker_(this_blocker), next_blocker_(next_blocker)
148*a9fa9459Szrj   { }
149*a9fa9459Szrj 
150*a9fa9459Szrj   ~Add_symbols();
151*a9fa9459Szrj 
152*a9fa9459Szrj   // The standard Task methods.
153*a9fa9459Szrj 
154*a9fa9459Szrj   Task_token*
155*a9fa9459Szrj   is_runnable();
156*a9fa9459Szrj 
157*a9fa9459Szrj   void
158*a9fa9459Szrj   locks(Task_locker*);
159*a9fa9459Szrj 
160*a9fa9459Szrj   void
161*a9fa9459Szrj   run(Workqueue*);
162*a9fa9459Szrj 
163*a9fa9459Szrj   std::string
get_name()164*a9fa9459Szrj   get_name() const
165*a9fa9459Szrj   { return "Add_symbols " + this->object_->name(); }
166*a9fa9459Szrj 
167*a9fa9459Szrj private:
168*a9fa9459Szrj   Input_objects* input_objects_;
169*a9fa9459Szrj   Symbol_table* symtab_;
170*a9fa9459Szrj   Layout* layout_;
171*a9fa9459Szrj   const Input_argument* input_argument_;
172*a9fa9459Szrj   Object* object_;
173*a9fa9459Szrj   Incremental_library* library_;
174*a9fa9459Szrj   Read_symbols_data* sd_;
175*a9fa9459Szrj   Task_token* this_blocker_;
176*a9fa9459Szrj   Task_token* next_blocker_;
177*a9fa9459Szrj };
178*a9fa9459Szrj 
179*a9fa9459Szrj // This Task is responsible for reading the symbols from an archive
180*a9fa9459Szrj // member that has changed since the last incremental link.
181*a9fa9459Szrj 
182*a9fa9459Szrj class Read_member : public Task
183*a9fa9459Szrj {
184*a9fa9459Szrj  public:
185*a9fa9459Szrj   // INPUT is the file to read.  INPUT_GROUP is not NULL if we are in
186*a9fa9459Szrj   // the middle of an input group.  THIS_BLOCKER is used to prevent
187*a9fa9459Szrj   // the associated Add_symbols task from running before the previous
188*a9fa9459Szrj   // one has completed; it will be NULL for the first task.
189*a9fa9459Szrj   // NEXT_BLOCKER is used to block the next input file from adding
190*a9fa9459Szrj   // symbols.
Read_member(Input_objects *,Symbol_table *,Layout *,Mapfile *,const Incremental_binary::Input_reader * input_reader,Task_token * this_blocker,Task_token * next_blocker)191*a9fa9459Szrj   Read_member(Input_objects* /*input_objects*/, Symbol_table* /*symtab*/,
192*a9fa9459Szrj 	      Layout* /*layout*/, Mapfile* /*mapfile*/,
193*a9fa9459Szrj 	      const Incremental_binary::Input_reader* input_reader,
194*a9fa9459Szrj               Task_token* this_blocker, Task_token* next_blocker)
195*a9fa9459Szrj     : input_reader_(input_reader),
196*a9fa9459Szrj       this_blocker_(this_blocker), next_blocker_(next_blocker)
197*a9fa9459Szrj   { }
198*a9fa9459Szrj 
199*a9fa9459Szrj   ~Read_member();
200*a9fa9459Szrj 
201*a9fa9459Szrj   // The standard Task methods.
202*a9fa9459Szrj 
203*a9fa9459Szrj   Task_token*
204*a9fa9459Szrj   is_runnable();
205*a9fa9459Szrj 
206*a9fa9459Szrj   void
207*a9fa9459Szrj   locks(Task_locker*);
208*a9fa9459Szrj 
209*a9fa9459Szrj   void
210*a9fa9459Szrj   run(Workqueue*);
211*a9fa9459Szrj 
212*a9fa9459Szrj   std::string
get_name()213*a9fa9459Szrj   get_name() const
214*a9fa9459Szrj   {
215*a9fa9459Szrj     return (std::string("Read_member ") + this->input_reader_->filename());
216*a9fa9459Szrj   }
217*a9fa9459Szrj 
218*a9fa9459Szrj  private:
219*a9fa9459Szrj   const Incremental_binary::Input_reader* input_reader_;
220*a9fa9459Szrj   Task_token* this_blocker_;
221*a9fa9459Szrj   Task_token* next_blocker_;
222*a9fa9459Szrj };
223*a9fa9459Szrj 
224*a9fa9459Szrj // This Task is responsible for processing an input script file that has
225*a9fa9459Szrj // not changed since the last incremental link.
226*a9fa9459Szrj 
227*a9fa9459Szrj class Check_script : public Task
228*a9fa9459Szrj {
229*a9fa9459Szrj  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)230*a9fa9459Szrj   Check_script(Layout* layout, Incremental_binary* ibase,
231*a9fa9459Szrj 	       unsigned int input_file_index,
232*a9fa9459Szrj 	       const Incremental_binary::Input_reader* input_reader,
233*a9fa9459Szrj 	       Task_token* this_blocker, Task_token* next_blocker)
234*a9fa9459Szrj     : layout_(layout), ibase_(ibase), input_file_index_(input_file_index),
235*a9fa9459Szrj       input_reader_(input_reader), this_blocker_(this_blocker),
236*a9fa9459Szrj       next_blocker_(next_blocker)
237*a9fa9459Szrj   {
238*a9fa9459Szrj     this->filename_ = std::string(this->input_reader_->filename());
239*a9fa9459Szrj   }
240*a9fa9459Szrj 
241*a9fa9459Szrj   ~Check_script();
242*a9fa9459Szrj 
243*a9fa9459Szrj   // The standard Task methods.
244*a9fa9459Szrj 
245*a9fa9459Szrj   Task_token*
246*a9fa9459Szrj   is_runnable();
247*a9fa9459Szrj 
248*a9fa9459Szrj   void
249*a9fa9459Szrj   locks(Task_locker*);
250*a9fa9459Szrj 
251*a9fa9459Szrj   void
252*a9fa9459Szrj   run(Workqueue*);
253*a9fa9459Szrj 
254*a9fa9459Szrj   std::string
get_name()255*a9fa9459Szrj   get_name() const
256*a9fa9459Szrj   {
257*a9fa9459Szrj     return (std::string("Check_script ") + this->input_reader_->filename());
258*a9fa9459Szrj   }
259*a9fa9459Szrj 
260*a9fa9459Szrj  private:
261*a9fa9459Szrj   std::string filename_;
262*a9fa9459Szrj   Layout* layout_;
263*a9fa9459Szrj   Incremental_binary* ibase_;
264*a9fa9459Szrj   unsigned int input_file_index_;
265*a9fa9459Szrj   const Incremental_binary::Input_reader* input_reader_;
266*a9fa9459Szrj   Task_token* this_blocker_;
267*a9fa9459Szrj   Task_token* next_blocker_;
268*a9fa9459Szrj };
269*a9fa9459Szrj 
270*a9fa9459Szrj // This Task is responsible for processing an archive library that has
271*a9fa9459Szrj // not changed since the last incremental link.
272*a9fa9459Szrj 
273*a9fa9459Szrj class Check_library : public Task
274*a9fa9459Szrj {
275*a9fa9459Szrj  public:
Check_library(Symbol_table *,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)276*a9fa9459Szrj   Check_library(Symbol_table* /*symtab*/, Layout* layout,
277*a9fa9459Szrj 		Incremental_binary* ibase,
278*a9fa9459Szrj 		unsigned int input_file_index,
279*a9fa9459Szrj 		const Incremental_binary::Input_reader* input_reader,
280*a9fa9459Szrj 		Task_token* this_blocker, Task_token* next_blocker)
281*a9fa9459Szrj     : layout_(layout), ibase_(ibase),
282*a9fa9459Szrj       input_file_index_(input_file_index), input_reader_(input_reader),
283*a9fa9459Szrj       this_blocker_(this_blocker), next_blocker_(next_blocker)
284*a9fa9459Szrj   { }
285*a9fa9459Szrj 
286*a9fa9459Szrj   ~Check_library();
287*a9fa9459Szrj 
288*a9fa9459Szrj   // The standard Task methods.
289*a9fa9459Szrj 
290*a9fa9459Szrj   Task_token*
291*a9fa9459Szrj   is_runnable();
292*a9fa9459Szrj 
293*a9fa9459Szrj   void
294*a9fa9459Szrj   locks(Task_locker*);
295*a9fa9459Szrj 
296*a9fa9459Szrj   void
297*a9fa9459Szrj   run(Workqueue*);
298*a9fa9459Szrj 
299*a9fa9459Szrj   std::string
get_name()300*a9fa9459Szrj   get_name() const
301*a9fa9459Szrj   {
302*a9fa9459Szrj     return (std::string("Check_library ") + this->input_reader_->filename());
303*a9fa9459Szrj   }
304*a9fa9459Szrj 
305*a9fa9459Szrj  private:
306*a9fa9459Szrj   Layout* layout_;
307*a9fa9459Szrj   Incremental_binary* ibase_;
308*a9fa9459Szrj   unsigned int input_file_index_;
309*a9fa9459Szrj   const Incremental_binary::Input_reader* input_reader_;
310*a9fa9459Szrj   Task_token* this_blocker_;
311*a9fa9459Szrj   Task_token* next_blocker_;
312*a9fa9459Szrj };
313*a9fa9459Szrj 
314*a9fa9459Szrj // This class is used to track the archives in a group.
315*a9fa9459Szrj 
316*a9fa9459Szrj class Input_group
317*a9fa9459Szrj {
318*a9fa9459Szrj  public:
319*a9fa9459Szrj   typedef std::vector<Archive*> Archives;
320*a9fa9459Szrj   typedef Archives::const_iterator const_iterator;
321*a9fa9459Szrj 
Input_group()322*a9fa9459Szrj   Input_group()
323*a9fa9459Szrj     : archives_()
324*a9fa9459Szrj   { }
325*a9fa9459Szrj 
326*a9fa9459Szrj   ~Input_group();
327*a9fa9459Szrj 
328*a9fa9459Szrj   // Add an archive to the group.
329*a9fa9459Szrj   void
add_archive(Archive * arch)330*a9fa9459Szrj   add_archive(Archive* arch)
331*a9fa9459Szrj   { this->archives_.push_back(arch); }
332*a9fa9459Szrj 
333*a9fa9459Szrj   // Loop over the archives in the group.
334*a9fa9459Szrj 
335*a9fa9459Szrj   const_iterator
begin()336*a9fa9459Szrj   begin() const
337*a9fa9459Szrj   { return this->archives_.begin(); }
338*a9fa9459Szrj 
339*a9fa9459Szrj   const_iterator
end()340*a9fa9459Szrj   end() const
341*a9fa9459Szrj   { return this->archives_.end(); }
342*a9fa9459Szrj 
343*a9fa9459Szrj  private:
344*a9fa9459Szrj   Archives archives_;
345*a9fa9459Szrj };
346*a9fa9459Szrj 
347*a9fa9459Szrj // This class starts the handling of a group.  It exists only to pick
348*a9fa9459Szrj // up the number of undefined symbols at that point, so that we only
349*a9fa9459Szrj // run back through the group if we saw a new undefined symbol.
350*a9fa9459Szrj 
351*a9fa9459Szrj class Start_group : public Task
352*a9fa9459Szrj {
353*a9fa9459Szrj  public:
Start_group(Symbol_table * symtab,Finish_group * finish_group,Task_token * this_blocker,Task_token * next_blocker)354*a9fa9459Szrj   Start_group(Symbol_table* symtab, Finish_group* finish_group,
355*a9fa9459Szrj 	      Task_token* this_blocker, Task_token* next_blocker)
356*a9fa9459Szrj     : symtab_(symtab), finish_group_(finish_group),
357*a9fa9459Szrj       this_blocker_(this_blocker), next_blocker_(next_blocker)
358*a9fa9459Szrj   { }
359*a9fa9459Szrj 
360*a9fa9459Szrj   ~Start_group();
361*a9fa9459Szrj 
362*a9fa9459Szrj   // The standard Task methods.
363*a9fa9459Szrj 
364*a9fa9459Szrj   Task_token*
365*a9fa9459Szrj   is_runnable();
366*a9fa9459Szrj 
367*a9fa9459Szrj   void
368*a9fa9459Szrj   locks(Task_locker*);
369*a9fa9459Szrj 
370*a9fa9459Szrj   void
371*a9fa9459Szrj   run(Workqueue*);
372*a9fa9459Szrj 
373*a9fa9459Szrj   std::string
get_name()374*a9fa9459Szrj   get_name() const
375*a9fa9459Szrj   { return "Start_group"; }
376*a9fa9459Szrj 
377*a9fa9459Szrj  private:
378*a9fa9459Szrj   Symbol_table* symtab_;
379*a9fa9459Szrj   Finish_group* finish_group_;
380*a9fa9459Szrj   Task_token* this_blocker_;
381*a9fa9459Szrj   Task_token* next_blocker_;
382*a9fa9459Szrj };
383*a9fa9459Szrj 
384*a9fa9459Szrj // This class is used to finish up handling a group.  It is just a
385*a9fa9459Szrj // closure.
386*a9fa9459Szrj 
387*a9fa9459Szrj class Finish_group : public Task
388*a9fa9459Szrj {
389*a9fa9459Szrj  public:
Finish_group(Input_objects * input_objects,Symbol_table * symtab,Layout * layout,Mapfile * mapfile,Input_group * input_group,Task_token * next_blocker)390*a9fa9459Szrj   Finish_group(Input_objects* input_objects, Symbol_table* symtab,
391*a9fa9459Szrj 	       Layout* layout, Mapfile* mapfile, Input_group* input_group,
392*a9fa9459Szrj 	       Task_token* next_blocker)
393*a9fa9459Szrj     : input_objects_(input_objects), symtab_(symtab),
394*a9fa9459Szrj       layout_(layout), mapfile_(mapfile), input_group_(input_group),
395*a9fa9459Szrj       saw_undefined_(0), this_blocker_(NULL), next_blocker_(next_blocker)
396*a9fa9459Szrj   { }
397*a9fa9459Szrj 
398*a9fa9459Szrj   ~Finish_group();
399*a9fa9459Szrj 
400*a9fa9459Szrj   // Set the number of undefined symbols when we start processing the
401*a9fa9459Szrj   // group.  This is called by the Start_group task.
402*a9fa9459Szrj   void
set_saw_undefined(size_t saw_undefined)403*a9fa9459Szrj   set_saw_undefined(size_t saw_undefined)
404*a9fa9459Szrj   { this->saw_undefined_ = saw_undefined; }
405*a9fa9459Szrj 
406*a9fa9459Szrj   // Set the blocker to use for this task.
407*a9fa9459Szrj   void
set_blocker(Task_token * this_blocker)408*a9fa9459Szrj   set_blocker(Task_token* this_blocker)
409*a9fa9459Szrj   {
410*a9fa9459Szrj     gold_assert(this->this_blocker_ == NULL);
411*a9fa9459Szrj     this->this_blocker_ = this_blocker;
412*a9fa9459Szrj   }
413*a9fa9459Szrj 
414*a9fa9459Szrj   // The standard Task methods.
415*a9fa9459Szrj 
416*a9fa9459Szrj   Task_token*
417*a9fa9459Szrj   is_runnable();
418*a9fa9459Szrj 
419*a9fa9459Szrj   void
420*a9fa9459Szrj   locks(Task_locker*);
421*a9fa9459Szrj 
422*a9fa9459Szrj   void
423*a9fa9459Szrj   run(Workqueue*);
424*a9fa9459Szrj 
425*a9fa9459Szrj   std::string
get_name()426*a9fa9459Szrj   get_name() const
427*a9fa9459Szrj   { return "Finish_group"; }
428*a9fa9459Szrj 
429*a9fa9459Szrj  private:
430*a9fa9459Szrj   Input_objects* input_objects_;
431*a9fa9459Szrj   Symbol_table* symtab_;
432*a9fa9459Szrj   Layout* layout_;
433*a9fa9459Szrj   Mapfile* mapfile_;
434*a9fa9459Szrj   Input_group* input_group_;
435*a9fa9459Szrj   size_t saw_undefined_;
436*a9fa9459Szrj   Task_token* this_blocker_;
437*a9fa9459Szrj   Task_token* next_blocker_;
438*a9fa9459Szrj };
439*a9fa9459Szrj 
440*a9fa9459Szrj // This class is used to read a file which was not recognized as an
441*a9fa9459Szrj // object or archive.  It tries to read it as a linker script, using
442*a9fa9459Szrj // the tokens to serialize with the calls to Add_symbols.
443*a9fa9459Szrj 
444*a9fa9459Szrj class Read_script : public Task
445*a9fa9459Szrj {
446*a9fa9459Szrj  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)447*a9fa9459Szrj   Read_script(Symbol_table* symtab, Layout* layout, Dirsearch* dirpath,
448*a9fa9459Szrj 	      int dirindex, Input_objects* input_objects, Mapfile* mapfile,
449*a9fa9459Szrj 	      Input_group* input_group, const Input_argument* input_argument,
450*a9fa9459Szrj 	      Input_file* input_file, Task_token* this_blocker,
451*a9fa9459Szrj 	      Task_token* next_blocker)
452*a9fa9459Szrj     : symtab_(symtab), layout_(layout), dirpath_(dirpath), dirindex_(dirindex),
453*a9fa9459Szrj       input_objects_(input_objects), mapfile_(mapfile),
454*a9fa9459Szrj       input_group_(input_group), input_argument_(input_argument),
455*a9fa9459Szrj       input_file_(input_file), this_blocker_(this_blocker),
456*a9fa9459Szrj       next_blocker_(next_blocker)
457*a9fa9459Szrj   { }
458*a9fa9459Szrj 
459*a9fa9459Szrj   ~Read_script();
460*a9fa9459Szrj 
461*a9fa9459Szrj   // The standard Task methods.
462*a9fa9459Szrj 
463*a9fa9459Szrj   Task_token*
464*a9fa9459Szrj   is_runnable();
465*a9fa9459Szrj 
466*a9fa9459Szrj   void
467*a9fa9459Szrj   locks(Task_locker*);
468*a9fa9459Szrj 
469*a9fa9459Szrj   void
470*a9fa9459Szrj   run(Workqueue*);
471*a9fa9459Szrj 
472*a9fa9459Szrj   std::string
473*a9fa9459Szrj   get_name() const;
474*a9fa9459Szrj 
475*a9fa9459Szrj  private:
476*a9fa9459Szrj   Symbol_table* symtab_;
477*a9fa9459Szrj   Layout* layout_;
478*a9fa9459Szrj   Dirsearch* dirpath_;
479*a9fa9459Szrj   int dirindex_;
480*a9fa9459Szrj   Input_objects* input_objects_;
481*a9fa9459Szrj   Mapfile* mapfile_;
482*a9fa9459Szrj   Input_group* input_group_;
483*a9fa9459Szrj   const Input_argument* input_argument_;
484*a9fa9459Szrj   Input_file* input_file_;
485*a9fa9459Szrj   Task_token* this_blocker_;
486*a9fa9459Szrj   Task_token* next_blocker_;
487*a9fa9459Szrj };
488*a9fa9459Szrj 
489*a9fa9459Szrj } // end namespace gold
490*a9fa9459Szrj 
491*a9fa9459Szrj #endif // !defined(GOLD_READSYMS_H)
492