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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [archive.h] - Blame information for rev 143

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

Line No. Rev Author Line
1 27 khays
// archive.h -- archive support for gold      -*- C++ -*-
2
 
3
// Copyright 2006, 2007, 2008, 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_ARCHIVE_H
24
#define GOLD_ARCHIVE_H
25
 
26
#include <string>
27
#include <vector>
28
 
29
#include "fileread.h"
30
#include "workqueue.h"
31
 
32
namespace gold
33
{
34
 
35
class Task;
36
class Input_argument;
37
class Input_file;
38
class Input_objects;
39
class Input_group;
40
class Layout;
41
class Symbol_table;
42
class Object;
43
class Read_symbols_data;
44
class Input_file_lib;
45
class Incremental_archive_entry;
46
 
47
// An entry in the archive map of offsets to members.
48
struct Archive_member
49
{
50
  Archive_member()
51
      : obj_(NULL), sd_(NULL), arg_serial_(0)
52
  { }
53
  Archive_member(Object* obj, Read_symbols_data* sd)
54
      : obj_(obj), sd_(sd), arg_serial_(0)
55
  { }
56
  // The object file.
57
  Object* obj_;
58
  // The data to pass from read_symbols() to add_symbols().
59
  Read_symbols_data* sd_;
60
  // The serial number of the file in the argument list.
61
  unsigned int arg_serial_;
62
};
63
 
64
// This class serves as a base class for Archive and Lib_group objects.
65
 
66
class Library_base
67
{
68
 public:
69
  Library_base(Task* task)
70
    : task_(task), incremental_info_(NULL)
71
  { }
72
 
73
  virtual
74
  ~Library_base()
75
  { }
76
 
77
  // The file name.
78
  const std::string&
79
  filename() const
80
  { return this->do_filename(); }
81
 
82
  // The modification time of the archive file.
83
  Timespec
84
  get_mtime()
85
  { return this->do_get_mtime(); }
86
 
87
  // When we see a symbol in an archive we might decide to include the member,
88
  // not include the member or be undecided. This enum represents these
89
  // possibilities.
90
 
91
  enum Should_include
92
  {
93
    SHOULD_INCLUDE_NO,
94
    SHOULD_INCLUDE_YES,
95
    SHOULD_INCLUDE_UNKNOWN
96
  };
97
 
98
  static Should_include
99
  should_include_member(Symbol_table* symtab, Layout*, const char* sym_name,
100
                        Symbol** symp, std::string* why, char** tmpbufp,
101
                        size_t* tmpbuflen);
102
 
103
  // Store a pointer to the incremental link info for the library.
104
  void
105
  set_incremental_info(Incremental_archive_entry* info)
106
  { this->incremental_info_ = info; }
107
 
108
  // Return the pointer to the incremental link info for the library.
109
  Incremental_archive_entry*
110
  incremental_info() const
111
  { return this->incremental_info_; }
112
 
113
  // Abstract base class for processing unused symbols.
114
  class Symbol_visitor_base
115
  {
116
   public:
117
    Symbol_visitor_base()
118
    { }
119
 
120
    virtual
121
    ~Symbol_visitor_base()
122
    { }
123
 
124
    // This function will be called for each unused global
125
    // symbol in a library, with a pointer to the symbol name.
126
    virtual void
127
    visit(const char* /* name */) = 0;
128
  };
129
 
130
  // Iterator for unused global symbols in the library.
131
  // Calls v->visit() for each global symbol defined
132
  // in each unused library member, passing a pointer to
133
  // the symbol name.
134
  void
135
  for_all_unused_symbols(Symbol_visitor_base* v) const
136
  { this->do_for_all_unused_symbols(v); }
137
 
138
 protected:
139
  // The task reading this archive.
140
  Task *task_;
141
 
142
 private:
143
  // The file name.
144
  virtual const std::string&
145
  do_filename() const = 0;
146
 
147
  // Return the modification time of the archive file.
148
  virtual Timespec
149
  do_get_mtime() = 0;
150
 
151
  // Iterator for unused global symbols in the library.
152
  virtual void
153
  do_for_all_unused_symbols(Symbol_visitor_base* v) const = 0;
154
 
155
  // The incremental link information for this archive.
156
  Incremental_archive_entry* incremental_info_;
157
};
158
 
159
// This class represents an archive--generally a libNAME.a file.
160
// Archives have a symbol table and a list of objects.
161
 
162
class Archive : public Library_base
163
{
164
 public:
165
  Archive(const std::string& name, Input_file* input_file,
166
          bool is_thin_archive, Dirsearch* dirpath, Task* task);
167
 
168
  // The length of the magic string at the start of an archive.
169
  static const int sarmag = 8;
170
 
171
  // The magic string at the start of an archive.
172
  static const char armag[sarmag];
173
  static const char armagt[sarmag];
174
 
175
  // The string expected at the end of an archive member header.
176
  static const char arfmag[2];
177
 
178
  // The name of the object.  This is the name used on the command
179
  // line; e.g., if "-lgcc" is on the command line, this will be
180
  // "gcc".
181
  const std::string&
182
  name() const
183
  { return this->name_; }
184
 
185
  // The input file.
186
  const Input_file*
187
  input_file() const
188
  { return this->input_file_; }
189
 
190
  // Set up the archive: read the symbol map.
191
  void
192
  setup();
193
 
194
  // Get a reference to the underlying file.
195
  File_read&
196
  file()
197
  { return this->input_file_->file(); }
198
 
199
  const File_read&
200
  file() const
201
  { return this->input_file_->file(); }
202
 
203
  // Lock the underlying file.
204
  void
205
  lock(const Task* t)
206
  { this->input_file_->file().lock(t); }
207
 
208
  // Unlock the underlying file.
209
  void
210
  unlock(const Task* t)
211
  { this->input_file_->file().unlock(t); }
212
 
213
  // Return whether the underlying file is locked.
214
  bool
215
  is_locked() const
216
  { return this->input_file_->file().is_locked(); }
217
 
218
  // Return the token, so that the task can be queued.
219
  Task_token*
220
  token()
221
  { return this->input_file_->file().token(); }
222
 
223
  // Release the underlying file.
224
  void
225
  release()
226
  { this->input_file_->file().release(); }
227
 
228
  // Clear uncached views in the underlying file.
229
  void
230
  clear_uncached_views()
231
  { this->input_file_->file().clear_uncached_views(); }
232
 
233
  // Whether this is a thin archive.
234
  bool
235
  is_thin_archive() const
236
  { return this->is_thin_archive_; }
237
 
238
  // Unlock any nested archives.
239
  void
240
  unlock_nested_archives();
241
 
242
  // Select members from the archive as needed and add them to the
243
  // link.
244
  bool
245
  add_symbols(Symbol_table*, Layout*, Input_objects*, Mapfile*);
246
 
247
  // Return whether the archive defines the symbol.
248
  bool
249
  defines_symbol(Symbol*) const;
250
 
251
  // Dump statistical information to stderr.
252
  static void
253
  print_stats();
254
 
255
  // Return the number of members in the archive.
256
  size_t
257
  count_members();
258
 
259
  // Return the no-export flag.
260
  bool
261
  no_export()
262
  { return this->no_export_; }
263
 
264
 private:
265
  Archive(const Archive&);
266
  Archive& operator=(const Archive&);
267
 
268
  // The file name.
269
  const std::string&
270
  do_filename() const
271
  { return this->input_file_->filename(); }
272
 
273
  // The modification time of the archive file.
274
  Timespec
275
  do_get_mtime()
276
  { return this->file().get_mtime(); }
277
 
278
  struct Archive_header;
279
 
280
  // Total number of archives seen.
281
  static unsigned int total_archives;
282
  // Total number of archive members seen.
283
  static unsigned int total_members;
284
  // Number of archive members loaded.
285
  static unsigned int total_members_loaded;
286
 
287
  // Get a view into the underlying file.
288
  const unsigned char*
289
  get_view(off_t start, section_size_type size, bool aligned, bool cache)
290
  { return this->input_file_->file().get_view(0, start, size, aligned, cache); }
291
 
292
  // Read the archive symbol map.
293
  void
294
  read_armap(off_t start, section_size_type size);
295
 
296
  // Read an archive member header at OFF.  CACHE is whether to cache
297
  // the file view.  Return the size of the member, and set *PNAME to
298
  // the name.
299
  off_t
300
  read_header(off_t off, bool cache, std::string* pname, off_t* nested_off);
301
 
302
  // Interpret an archive header HDR at OFF.  Return the size of the
303
  // member, and set *PNAME to the name.
304
  off_t
305
  interpret_header(const Archive_header* hdr, off_t off, std::string* pname,
306
                   off_t* nested_off) const;
307
 
308
  // Get the file and offset for an archive member, which may be an
309
  // external member of a thin archive.  Set *INPUT_FILE to the
310
  // file containing the actual member, *MEMOFF to the offset
311
  // within that file (0 if not a nested archive), and *MEMBER_NAME
312
  // to the name of the archive member.  Return TRUE on success.
313
  bool
314
  get_file_and_offset(off_t off, Input_file** input_file, off_t* memoff,
315
                      off_t* memsize, std::string* member_name);
316
 
317
  // Return an ELF object for the member at offset OFF.
318
  Object*
319
  get_elf_object_for_member(off_t off, bool*);
320
 
321
  // Read the symbols from all the archive members in the link.
322
  void
323
  read_all_symbols();
324
 
325
  // Read the symbols from an archive member in the link.  OFF is the file
326
  // offset of the member header.
327
  void
328
  read_symbols(off_t off);
329
 
330
  // Include all the archive members in the link.
331
  bool
332
  include_all_members(Symbol_table*, Layout*, Input_objects*, Mapfile*);
333
 
334
  // Include an archive member in the link.
335
  bool
336
  include_member(Symbol_table*, Layout*, Input_objects*, off_t off,
337
                 Mapfile*, Symbol*, const char* why);
338
 
339
  // Return whether we found this archive by searching a directory.
340
  bool
341
  searched_for() const
342
  { return this->input_file_->will_search_for(); }
343
 
344
  // Iterate over archive members.
345
  class const_iterator;
346
 
347
  const_iterator
348
  begin();
349
 
350
  const_iterator
351
  end();
352
 
353
  friend class const_iterator;
354
 
355
  // Iterator for unused global symbols in the library.
356
  void
357
  do_for_all_unused_symbols(Symbol_visitor_base* v) const;
358
 
359
  // An entry in the archive map of symbols to object files.
360
  struct Armap_entry
361
  {
362
    // The offset to the symbol name in armap_names_.
363
    off_t name_offset;
364
    // The file offset to the object in the archive.
365
    off_t file_offset;
366
  };
367
 
368
  // A simple hash code for off_t values.
369
  class Seen_hash
370
  {
371
   public:
372
    size_t operator()(off_t val) const
373
    { return static_cast<size_t>(val); }
374
  };
375
 
376
  // For keeping track of open nested archives in a thin archive file.
377
  typedef Unordered_map<std::string, Archive*> Nested_archive_table;
378
 
379
  // Name of object as printed to user.
380
  std::string name_;
381
  // For reading the file.
382
  Input_file* input_file_;
383
  // The archive map.
384
  std::vector<Armap_entry> armap_;
385
  // The names in the archive map.
386
  std::string armap_names_;
387
  // The extended name table.
388
  std::string extended_names_;
389
  // Track which symbols in the archive map are for elements which are
390
  // defined or which have already been included in the link.
391
  std::vector<bool> armap_checked_;
392
  // Track which elements have been included by offset.
393
  Unordered_set<off_t, Seen_hash> seen_offsets_;
394
  // Table of objects whose symbols have been pre-read.
395
  std::map<off_t, Archive_member> members_;
396
  // True if this is a thin archive.
397
  const bool is_thin_archive_;
398
  // True if we have included at least one object from this archive.
399
  bool included_member_;
400
  // Table of nested archives, indexed by filename.
401
  Nested_archive_table nested_archives_;
402
  // The directory search path.
403
  Dirsearch* dirpath_;
404
  // Number of members in this archive;
405
  unsigned int num_members_;
406
  // True if we exclude this library archive from automatic export.
407
  bool no_export_;
408
  // True if this library has been included as a --whole-archive.
409
  bool included_all_members_;
410
};
411
 
412
// This class is used to read an archive and pick out the desired
413
// elements and add them to the link.
414
 
415
class Add_archive_symbols : public Task
416
{
417
 public:
418
  Add_archive_symbols(Symbol_table* symtab, Layout* layout,
419
                      Input_objects* input_objects, Dirsearch* dirpath,
420
                      int dirindex, Mapfile* mapfile,
421
                      const Input_argument* input_argument,
422
                      Archive* archive, Input_group* input_group,
423
                      Task_token* this_blocker,
424
                      Task_token* next_blocker)
425
    : symtab_(symtab), layout_(layout), input_objects_(input_objects),
426
      dirpath_(dirpath), dirindex_(dirindex), mapfile_(mapfile),
427
      input_argument_(input_argument), archive_(archive),
428
      input_group_(input_group), this_blocker_(this_blocker),
429
      next_blocker_(next_blocker)
430
  { }
431
 
432
  ~Add_archive_symbols();
433
 
434
  // The standard Task methods.
435
 
436
  Task_token*
437
  is_runnable();
438
 
439
  void
440
  locks(Task_locker*);
441
 
442
  void
443
  run(Workqueue*);
444
 
445
  std::string
446
  get_name() const
447
  {
448
    if (this->archive_ == NULL)
449
      return "Add_archive_symbols";
450
    return "Add_archive_symbols " + this->archive_->file().filename();
451
  }
452
 
453
 private:
454
  Symbol_table* symtab_;
455
  Layout* layout_;
456
  Input_objects* input_objects_;
457
  Dirsearch* dirpath_;
458
  int dirindex_;
459
  Mapfile* mapfile_;
460
  const Input_argument* input_argument_;
461
  Archive* archive_;
462
  Input_group* input_group_;
463
  Task_token* this_blocker_;
464
  Task_token* next_blocker_;
465
};
466
 
467
// This class represents the files surrounded by a --start-lib ... --end-lib.
468
 
469
class Lib_group : public Library_base
470
{
471
 public:
472
  Lib_group(const Input_file_lib* lib, Task* task);
473
 
474
  // Select members from the lib group as needed and add them to the link.
475
  void
476
  add_symbols(Symbol_table*, Layout*, Input_objects*);
477
 
478
  // Include a member of the lib group in the link.
479
  void
480
  include_member(Symbol_table*, Layout*, Input_objects*, const Archive_member&);
481
 
482
  Archive_member*
483
  get_member(int i)
484
  {
485
    return &this->members_[i];
486
  }
487
 
488
  // Total number of archives seen.
489
  static unsigned int total_lib_groups;
490
  // Total number of archive members seen.
491
  static unsigned int total_members;
492
  // Number of archive members loaded.
493
  static unsigned int total_members_loaded;
494
 
495
  // Dump statistical information to stderr.
496
  static void
497
  print_stats();
498
 
499
 private:
500
  // The file name.
501
  const std::string&
502
  do_filename() const;
503
 
504
  // A Lib_group does not have a modification time, since there is no
505
  // real library file.
506
  Timespec
507
  do_get_mtime()
508
  { return Timespec(0, 0); }
509
 
510
  // Iterator for unused global symbols in the library.
511
  void
512
  do_for_all_unused_symbols(Symbol_visitor_base*) const;
513
 
514
  // For reading the files.
515
  const Input_file_lib* lib_;
516
  // Table of the objects in the group.
517
  std::vector<Archive_member> members_;
518
};
519
 
520
// This class is used to pick out the desired elements and add them to the link.
521
 
522
class Add_lib_group_symbols : public Task
523
{
524
 public:
525
  Add_lib_group_symbols(Symbol_table* symtab, Layout* layout,
526
                        Input_objects* input_objects,
527
                        Lib_group* lib, Task_token* next_blocker)
528
      : symtab_(symtab), layout_(layout), input_objects_(input_objects),
529
        lib_(lib), readsyms_blocker_(NULL), this_blocker_(NULL),
530
        next_blocker_(next_blocker)
531
  { }
532
 
533
  ~Add_lib_group_symbols();
534
 
535
  // The standard Task methods.
536
 
537
  Task_token*
538
  is_runnable();
539
 
540
  void
541
  locks(Task_locker*);
542
 
543
  void
544
  run(Workqueue*);
545
 
546
  // Set the blocker to use for this task.
547
  void
548
  set_blocker(Task_token* readsyms_blocker, Task_token* this_blocker)
549
  {
550
    gold_assert(this->readsyms_blocker_ == NULL && this->this_blocker_ == NULL);
551
    this->readsyms_blocker_ = readsyms_blocker;
552
    this->this_blocker_ = this_blocker;
553
  }
554
 
555
  std::string
556
  get_name() const
557
  {
558
    return "Add_lib_group_symbols";
559
  }
560
 
561
 private:
562
  Symbol_table* symtab_;
563
  Layout* layout_;
564
  Input_objects* input_objects_;
565
  Lib_group* lib_;
566
  Task_token* readsyms_blocker_;
567
  Task_token* this_blocker_;
568
  Task_token* next_blocker_;
569
};
570
 
571
} // End namespace gold.
572
 
573
#endif // !defined(GOLD_ARCHIVE_H)

powered by: WebSVN 2.1.0

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