OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [readsyms.h] - Blame information for rev 165

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.