~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/gold/archive.h

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 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)