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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [incremental.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
// inremental.h -- incremental linking support for gold   -*- C++ -*-
2
 
3
// Copyright 2009, 2010 Free Software Foundation, Inc.
4
// Written by Mikolaj Zalewski <mikolajz@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_INCREMENTAL_H
24
#define GOLD_INCREMENTAL_H
25
 
26
#include <map>
27
#include <vector>
28
 
29
#include "elfcpp_file.h"
30
#include "stringpool.h"
31
#include "workqueue.h"
32
#include "fileread.h"
33
#include "output.h"
34
#include "archive.h"
35
 
36
namespace gold
37
{
38
 
39
class Input_argument;
40
class Incremental_inputs_checker;
41
class Incremental_script_entry;
42
class Incremental_object_entry;
43
class Incremental_dynobj_entry;
44
class Incremental_archive_entry;
45
class Incremental_inputs;
46
class Incremental_binary;
47
class Incremental_library;
48
class Object;
49
class Script_info;
50
 
51
// Incremental input type as stored in .gnu_incremental_inputs.
52
 
53
enum Incremental_input_type
54
{
55
  INCREMENTAL_INPUT_OBJECT = 1,
56
  INCREMENTAL_INPUT_ARCHIVE_MEMBER = 2,
57
  INCREMENTAL_INPUT_ARCHIVE = 3,
58
  INCREMENTAL_INPUT_SHARED_LIBRARY = 4,
59
  INCREMENTAL_INPUT_SCRIPT = 5
60
};
61
 
62
// Incremental input file flags.
63
// The input file type is stored in the lower eight bits.
64
 
65
enum Incremental_input_flags
66
{
67
  INCREMENTAL_INPUT_IN_SYSTEM_DIR = 0x8000,
68
  INCREMENTAL_INPUT_AS_NEEDED = 0x4000
69
};
70
 
71
// Create an Incremental_binary object for FILE. Returns NULL is this is not
72
// possible, e.g. FILE is not an ELF file or has an unsupported target.
73
 
74
Incremental_binary*
75
open_incremental_binary(Output_file* file);
76
 
77
// Base class for recording each input file.
78
 
79
class Incremental_input_entry
80
{
81
 public:
82
  Incremental_input_entry(Stringpool::Key filename_key, unsigned int arg_serial,
83
                          Timespec mtime)
84
    : filename_key_(filename_key), file_index_(0), offset_(0), info_offset_(0),
85
      arg_serial_(arg_serial), mtime_(mtime), is_in_system_directory_(false),
86
      as_needed_(false)
87
  { }
88
 
89
  virtual
90
  ~Incremental_input_entry()
91
  { }
92
 
93
  // Return the type of input file.
94
  Incremental_input_type
95
  type() const
96
  { return this->do_type(); }
97
 
98
  // Set the index and section offset of this input file entry.
99
  void
100
  set_offset(unsigned int file_index, unsigned int offset)
101
  {
102
    this->file_index_ = file_index;
103
    this->offset_ = offset;
104
  }
105
 
106
  // Set the section offset of the supplemental information for this entry.
107
  void
108
  set_info_offset(unsigned int info_offset)
109
  { this->info_offset_ = info_offset; }
110
 
111
  // Get the index of this input file entry.
112
  unsigned int
113
  get_file_index() const
114
  { return this->file_index_; }
115
 
116
  // Get the section offset of this input file entry.
117
  unsigned int
118
  get_offset() const
119
  { return this->offset_; }
120
 
121
  // Get the section offset of the supplemental information for this entry.
122
  unsigned int
123
  get_info_offset() const
124
  { return this->info_offset_; }
125
 
126
  // Get the stringpool key for the input filename.
127
  Stringpool::Key
128
  get_filename_key() const
129
  { return this->filename_key_; }
130
 
131
  // Get the serial number of the input file.
132
  unsigned int
133
  arg_serial() const
134
  { return this->arg_serial_; }
135
 
136
  // Get the modification time of the input file.
137
  const Timespec&
138
  get_mtime() const
139
  { return this->mtime_; }
140
 
141
  // Record that the file was found in a system directory.
142
  void
143
  set_is_in_system_directory()
144
  { this->is_in_system_directory_ = true; }
145
 
146
  // Return TRUE if the file was found in a system directory.
147
  bool
148
  is_in_system_directory() const
149
  { return this->is_in_system_directory_; }
150
 
151
  // Record that the file was linked with --as-needed.
152
  void
153
  set_as_needed()
154
  { this->as_needed_ = true; }
155
 
156
  // Return TRUE if the file was linked with --as-needed.
157
  bool
158
  as_needed() const
159
  { return this->as_needed_; }
160
 
161
  // Return a pointer to the derived Incremental_script_entry object.
162
  // Return NULL for input entries that are not script files.
163
  Incremental_script_entry*
164
  script_entry()
165
  { return this->do_script_entry(); }
166
 
167
  // Return a pointer to the derived Incremental_object_entry object.
168
  // Return NULL for input entries that are not object files.
169
  Incremental_object_entry*
170
  object_entry()
171
  { return this->do_object_entry(); }
172
 
173
  // Return a pointer to the derived Incremental_dynobj_entry object.
174
  // Return NULL for input entries that are not shared object files.
175
  Incremental_dynobj_entry*
176
  dynobj_entry()
177
  { return this->do_dynobj_entry(); }
178
 
179
  // Return a pointer to the derived Incremental_archive_entry object.
180
  // Return NULL for input entries that are not archive files.
181
  Incremental_archive_entry*
182
  archive_entry()
183
  { return this->do_archive_entry(); }
184
 
185
 protected:
186
  // Return the type of input file.
187
  virtual Incremental_input_type
188
  do_type() const = 0;
189
 
190
  // Return a pointer to the derived Incremental_script_entry object.
191
  // Return NULL for input entries that are not script files.
192
  virtual Incremental_script_entry*
193
  do_script_entry()
194
  { return NULL; }
195
 
196
  // Return a pointer to the derived Incremental_object_entry object.
197
  // Return NULL for input entries that are not object files.
198
  virtual Incremental_object_entry*
199
  do_object_entry()
200
  { return NULL; }
201
 
202
  // Return a pointer to the derived Incremental_dynobj_entry object.
203
  // Return NULL for input entries that are not shared object files.
204
  virtual Incremental_dynobj_entry*
205
  do_dynobj_entry()
206
  { return NULL; }
207
 
208
  // Return a pointer to the derived Incremental_archive_entry object.
209
  // Return NULL for input entries that are not archive files.
210
  virtual Incremental_archive_entry*
211
  do_archive_entry()
212
  { return NULL; }
213
 
214
 private:
215
  // Key of the filename string in the section stringtable.
216
  Stringpool::Key filename_key_;
217
 
218
  // Index of the entry in the output section.
219
  unsigned int file_index_;
220
 
221
  // Offset of the entry in the output section.
222
  unsigned int offset_;
223
 
224
  // Offset of the extra information in the output section.
225
  unsigned int info_offset_;
226
 
227
  // Serial number of the file in the argument list.
228
  unsigned int arg_serial_;
229
 
230
  // Last modification time of the file.
231
  Timespec mtime_;
232
 
233
  // TRUE if the file was found in a system directory.
234
  bool is_in_system_directory_;
235
 
236
  // TRUE if the file was linked with --as-needed.
237
  bool as_needed_;
238
};
239
 
240
// Information about a script input that will persist during the whole linker
241
// run.  Needed only during an incremental build to retrieve the input files
242
// added by this script.
243
 
244
class Script_info
245
{
246
 public:
247
  Script_info(const std::string& filename)
248
    : filename_(filename), incremental_script_entry_(NULL)
249
  { }
250
 
251
  // Store a pointer to the incremental information for this script.
252
  void
253
  set_incremental_info(Incremental_script_entry* entry)
254
  { this->incremental_script_entry_ = entry; }
255
 
256
  // Return the filename.
257
  const std::string&
258
  filename() const
259
  { return this->filename_; }
260
 
261
  // Return the pointer to the incremental information for this script.
262
  Incremental_script_entry*
263
  incremental_info() const
264
  { return this->incremental_script_entry_; }
265
 
266
 private:
267
  const std::string filename_;
268
  Incremental_script_entry* incremental_script_entry_;
269
};
270
 
271
// Class for recording input scripts.
272
 
273
class Incremental_script_entry : public Incremental_input_entry
274
{
275
 public:
276
  Incremental_script_entry(Stringpool::Key filename_key,
277
                           unsigned int arg_serial, Script_info* script,
278
                           Timespec mtime)
279
    : Incremental_input_entry(filename_key, arg_serial, mtime),
280
      script_(script), objects_()
281
  { }
282
 
283
  // Add a member object to the archive.
284
  void
285
  add_object(Incremental_input_entry* obj_entry)
286
  {
287
    this->objects_.push_back(obj_entry);
288
  }
289
 
290
  // Return the number of objects included by this script.
291
  unsigned int
292
  get_object_count()
293
  { return this->objects_.size(); }
294
 
295
  // Return the Nth object.
296
  Incremental_input_entry*
297
  get_object(unsigned int n)
298
  {
299
    gold_assert(n < this->objects_.size());
300
    return this->objects_[n];
301
  }
302
 
303
 protected:
304
  virtual Incremental_input_type
305
  do_type() const
306
  { return INCREMENTAL_INPUT_SCRIPT; }
307
 
308
  // Return a pointer to the derived Incremental_script_entry object.
309
  virtual Incremental_script_entry*
310
  do_script_entry()
311
  { return this; }
312
 
313
 private:
314
  // Information about the script file.
315
  Script_info* script_;
316
  // Objects that have been included by this script.
317
  std::vector<Incremental_input_entry*> objects_;
318
};
319
 
320
// Class for recording input object files.
321
 
322
class Incremental_object_entry : public Incremental_input_entry
323
{
324
 public:
325
  Incremental_object_entry(Stringpool::Key filename_key, Object* obj,
326
                           unsigned int arg_serial, Timespec mtime)
327
    : Incremental_input_entry(filename_key, arg_serial, mtime), obj_(obj),
328
      is_member_(false), sections_(), groups_()
329
  { this->sections_.reserve(obj->shnum()); }
330
 
331
  // Get the object.
332
  Object*
333
  object() const
334
  { return this->obj_; }
335
 
336
  // Record that this object is an archive member.
337
  void
338
  set_is_member()
339
  { this->is_member_ = true; }
340
 
341
  // Return true if this object is an archive member.
342
  bool
343
  is_member() const
344
  { return this->is_member_; }
345
 
346
  // Add an input section.
347
  void
348
  add_input_section(unsigned int shndx, Stringpool::Key name_key, off_t sh_size)
349
  { this->sections_.push_back(Input_section(shndx, name_key, sh_size)); }
350
 
351
  // Return the number of input sections in this object.
352
  unsigned int
353
  get_input_section_count() const
354
  { return this->sections_.size(); }
355
 
356
  // Return the input section index for the Nth input section.
357
  Stringpool::Key
358
  get_input_section_index(unsigned int n) const
359
  { return this->sections_[n].shndx_; }
360
 
361
  // Return the stringpool key of the Nth input section.
362
  Stringpool::Key
363
  get_input_section_name_key(unsigned int n) const
364
  { return this->sections_[n].name_key_; }
365
 
366
  // Return the size of the Nth input section.
367
  off_t
368
  get_input_section_size(unsigned int n) const
369
  { return this->sections_[n].sh_size_; }
370
 
371
  // Add a kept COMDAT group.
372
  void
373
  add_comdat_group(Stringpool::Key signature_key)
374
  { this->groups_.push_back(signature_key); }
375
 
376
  // Return the number of COMDAT groups.
377
  unsigned int
378
  get_comdat_group_count() const
379
  { return this->groups_.size(); }
380
 
381
  // Return the stringpool key for the signature of the Nth comdat group.
382
  Stringpool::Key
383
  get_comdat_signature_key(unsigned int n) const
384
  { return this->groups_[n]; }
385
 
386
 protected:
387
  virtual Incremental_input_type
388
  do_type() const
389
  {
390
    return (this->is_member_
391
            ? INCREMENTAL_INPUT_ARCHIVE_MEMBER
392
            : INCREMENTAL_INPUT_OBJECT);
393
  }
394
 
395
  // Return a pointer to the derived Incremental_object_entry object.
396
  virtual Incremental_object_entry*
397
  do_object_entry()
398
  { return this; }
399
 
400
 private:
401
  // The object file itself.
402
  Object* obj_;
403
 
404
  // Whether this object is an archive member.
405
  bool is_member_;
406
 
407
  // Input sections.
408
  struct Input_section
409
  {
410
    Input_section(unsigned int shndx, Stringpool::Key name_key, off_t sh_size)
411
      : shndx_(shndx), name_key_(name_key), sh_size_(sh_size)
412
    { }
413
    unsigned int shndx_;
414
    Stringpool::Key name_key_;
415
    off_t sh_size_;
416
  };
417
  std::vector<Input_section> sections_;
418
 
419
  // COMDAT groups.
420
  std::vector<Stringpool::Key> groups_;
421
};
422
 
423
// Class for recording shared library input files.
424
 
425
class Incremental_dynobj_entry : public Incremental_input_entry
426
{
427
 public:
428
  Incremental_dynobj_entry(Stringpool::Key filename_key,
429
                           Stringpool::Key soname_key, Object* obj,
430
                           unsigned int arg_serial, Timespec mtime)
431
    : Incremental_input_entry(filename_key, arg_serial, mtime),
432
      soname_key_(soname_key), obj_(obj)
433
  { }
434
 
435
  // Get the object.
436
  Object*
437
  object() const
438
  { return this->obj_; }
439
 
440
  // Get the stringpool key for the soname.
441
  Stringpool::Key
442
  get_soname_key() const
443
  { return this->soname_key_; }
444
 
445
 protected:
446
  virtual Incremental_input_type
447
  do_type() const
448
  { return INCREMENTAL_INPUT_SHARED_LIBRARY; }
449
 
450
  // Return a pointer to the derived Incremental_dynobj_entry object.
451
  virtual Incremental_dynobj_entry*
452
  do_dynobj_entry()
453
  { return this; }
454
 
455
 private:
456
  // Key of the soname string in the section stringtable.
457
  Stringpool::Key soname_key_;
458
 
459
  // The object file itself.
460
  Object* obj_;
461
};
462
 
463
// Class for recording archive library input files.
464
 
465
class Incremental_archive_entry : public Incremental_input_entry
466
{
467
 public:
468
  Incremental_archive_entry(Stringpool::Key filename_key,
469
                            unsigned int arg_serial, Timespec mtime)
470
    : Incremental_input_entry(filename_key, arg_serial, mtime), members_(),
471
      unused_syms_()
472
  { }
473
 
474
  // Add a member object to the archive.
475
  void
476
  add_object(Incremental_object_entry* obj_entry)
477
  {
478
    this->members_.push_back(obj_entry);
479
    obj_entry->set_is_member();
480
  }
481
 
482
  // Add an unused global symbol to the archive.
483
  void
484
  add_unused_global_symbol(Stringpool::Key symbol_key)
485
  { this->unused_syms_.push_back(symbol_key); }
486
 
487
  // Return the number of member objects included in the link.
488
  unsigned int
489
  get_member_count()
490
  { return this->members_.size(); }
491
 
492
  // Return the Nth member object.
493
  Incremental_object_entry*
494
  get_member(unsigned int n)
495
  { return this->members_[n]; }
496
 
497
  // Return the number of unused global symbols in this archive.
498
  unsigned int
499
  get_unused_global_symbol_count()
500
  { return this->unused_syms_.size(); }
501
 
502
  // Return the Nth unused global symbol.
503
  Stringpool::Key
504
  get_unused_global_symbol(unsigned int n)
505
  { return this->unused_syms_[n]; }
506
 
507
 protected:
508
  virtual Incremental_input_type
509
  do_type() const
510
  { return INCREMENTAL_INPUT_ARCHIVE; }
511
 
512
  // Return a pointer to the derived Incremental_archive_entry object.
513
  virtual Incremental_archive_entry*
514
  do_archive_entry()
515
  { return this; }
516
 
517
 private:
518
  // Members of the archive that have been included in the link.
519
  std::vector<Incremental_object_entry*> members_;
520
 
521
  // Unused global symbols from this archive.
522
  std::vector<Stringpool::Key> unused_syms_;
523
};
524
 
525
// This class contains the information needed during an incremental
526
// build about the inputs necessary to build the .gnu_incremental_inputs.
527
 
528
class Incremental_inputs
529
{
530
 public:
531
  typedef std::vector<Incremental_input_entry*> Input_list;
532
 
533
  Incremental_inputs()
534
    : inputs_(), command_line_(), command_line_key_(0),
535
      strtab_(new Stringpool()), current_object_(NULL),
536
      current_object_entry_(NULL), inputs_section_(NULL),
537
      symtab_section_(NULL), relocs_section_(NULL),
538
      reloc_count_(0)
539
  { }
540
 
541
  ~Incremental_inputs() { delete this->strtab_; }
542
 
543
  // Record the command line.
544
  void
545
  report_command_line(int argc, const char* const* argv);
546
 
547
  // Record the initial info for archive file ARCHIVE.
548
  void
549
  report_archive_begin(Library_base* arch, unsigned int arg_serial,
550
                       Script_info* script_info);
551
 
552
  // Record the final info for archive file ARCHIVE.
553
  void
554
  report_archive_end(Library_base* arch);
555
 
556
  // Record the info for object file OBJ.  If ARCH is not NULL,
557
  // attach the object file to the archive.
558
  void
559
  report_object(Object* obj, unsigned int arg_serial, Library_base* arch,
560
                Script_info* script_info);
561
 
562
  // Record an input section belonging to object file OBJ.
563
  void
564
  report_input_section(Object* obj, unsigned int shndx, const char* name,
565
                       off_t sh_size);
566
 
567
  // Record a kept COMDAT group belonging to object file OBJ.
568
  void
569
  report_comdat_group(Object* obj, const char* name);
570
 
571
  // Record the info for input script SCRIPT.
572
  void
573
  report_script(Script_info* script, unsigned int arg_serial,
574
                Timespec mtime);
575
 
576
  // Return the running count of incremental relocations.
577
  unsigned int
578
  get_reloc_count() const
579
  { return this->reloc_count_; }
580
 
581
  // Update the running count of incremental relocations.
582
  void
583
  set_reloc_count(unsigned int count)
584
  { this->reloc_count_ = count; }
585
 
586
  // Prepare for layout.  Called from Layout::finalize.
587
  void
588
  finalize();
589
 
590
  // Create the .gnu_incremental_inputs and related sections.
591
  void
592
  create_data_sections(Symbol_table* symtab);
593
 
594
  // Return the .gnu_incremental_inputs section.
595
  Output_section_data*
596
  inputs_section() const
597
  { return this->inputs_section_; }
598
 
599
  // Return the .gnu_incremental_symtab section.
600
  Output_data_space*
601
  symtab_section() const
602
  { return this->symtab_section_; }
603
 
604
  // Return the .gnu_incremental_relocs section.
605
  Output_data_space*
606
  relocs_section() const
607
  { return this->relocs_section_; }
608
 
609
  // Return the .gnu_incremental_got_plt section.
610
  Output_data_space*
611
  got_plt_section() const
612
  { return this->got_plt_section_; }
613
 
614
  // Return the .gnu_incremental_strtab stringpool.
615
  Stringpool*
616
  get_stringpool() const
617
  { return this->strtab_; }
618
 
619
  // Return the canonical form of the command line, as will be stored in
620
  // .gnu_incremental_strtab.
621
  const std::string&
622
  command_line() const
623
  { return this->command_line_; }
624
 
625
  // Return the stringpool key of the command line.
626
  Stringpool::Key
627
  command_line_key() const
628
  { return this->command_line_key_; }
629
 
630
  // Return the number of input files.
631
  int
632
  input_file_count() const
633
  { return this->inputs_.size(); }
634
 
635
  // Return the input files.
636
  const Input_list&
637
  input_files() const
638
  { return this->inputs_; }
639
 
640
  // Return the sh_entsize value for the .gnu_incremental_relocs section.
641
  unsigned int
642
  relocs_entsize() const;
643
 
644
 private:
645
  // The list of input files.
646
  Input_list inputs_;
647
 
648
  // Canonical form of the command line, as will be stored in
649
  // .gnu_incremental_strtab.
650
  std::string command_line_;
651
 
652
  // The key of the command line string in the string pool.
653
  Stringpool::Key command_line_key_;
654
 
655
  // The .gnu_incremental_strtab string pool associated with the
656
  // .gnu_incremental_inputs.
657
  Stringpool* strtab_;
658
 
659
  // Keep track of the object currently being processed.
660
  Object* current_object_;
661
  Incremental_object_entry* current_object_entry_;
662
 
663
  // The .gnu_incremental_inputs section.
664
  Output_section_data* inputs_section_;
665
 
666
  // The .gnu_incremental_symtab section.
667
  Output_data_space* symtab_section_;
668
 
669
  // The .gnu_incremental_relocs section.
670
  Output_data_space* relocs_section_;
671
 
672
  // The .gnu_incremental_got_plt section.
673
  Output_data_space* got_plt_section_;
674
 
675
  // Total count of incremental relocations.  Updated during Scan_relocs
676
  // phase at the completion of each object file.
677
  unsigned int reloc_count_;
678
};
679
 
680
// Reader class for global symbol info from an object file entry in
681
// the .gnu_incremental_inputs section.
682
 
683
template<bool big_endian>
684
class Incremental_global_symbol_reader
685
{
686
 private:
687
  typedef elfcpp::Swap<32, big_endian> Swap32;
688
 
689
 public:
690
  Incremental_global_symbol_reader(const unsigned char* p)
691
    : p_(p)
692
  { }
693
 
694
  unsigned int
695
  output_symndx() const
696
  { return Swap32::readval(this->p_); }
697
 
698
  unsigned int
699
  shndx() const
700
  { return Swap32::readval(this->p_ + 4); }
701
 
702
  unsigned int
703
  next_offset() const
704
  { return Swap32::readval(this->p_ + 8); }
705
 
706
  unsigned int
707
  reloc_count() const
708
  { return Swap32::readval(this->p_ + 12); }
709
 
710
  unsigned int
711
  reloc_offset() const
712
  { return Swap32::readval(this->p_ + 16); }
713
 
714
 private:
715
  // Base address of the symbol entry.
716
  const unsigned char* p_;
717
};
718
 
719
// Reader class for .gnu_incremental_inputs section.
720
 
721
template<int size, bool big_endian>
722
class Incremental_inputs_reader
723
{
724
 private:
725
  typedef elfcpp::Swap<size, big_endian> Swap;
726
  typedef elfcpp::Swap<16, big_endian> Swap16;
727
  typedef elfcpp::Swap<32, big_endian> Swap32;
728
  typedef elfcpp::Swap<64, big_endian> Swap64;
729
 
730
 public:
731
  Incremental_inputs_reader()
732
    : p_(NULL), strtab_(NULL, 0), input_file_count_(0)
733
  { }
734
 
735
  Incremental_inputs_reader(const unsigned char* p,
736
                            const elfcpp::Elf_strtab& strtab)
737
    : p_(p), strtab_(strtab)
738
  { this->input_file_count_ = Swap32::readval(this->p_ + 4); }
739
 
740
  // Return the version number.
741
  unsigned int
742
  version() const
743
  { return Swap32::readval(this->p_); }
744
 
745
  // Return the count of input file entries.
746
  unsigned int
747
  input_file_count() const
748
  { return this->input_file_count_; }
749
 
750
  // Return the command line.
751
  const char*
752
  command_line() const
753
  {
754
    unsigned int offset = Swap32::readval(this->p_ + 8);
755
    return this->get_string(offset);
756
  }
757
 
758
  // Reader class for an input file entry and its supplemental info.
759
  class Incremental_input_entry_reader
760
  {
761
   public:
762
    Incremental_input_entry_reader(const Incremental_inputs_reader* inputs,
763
                                   unsigned int offset)
764
      : inputs_(inputs), offset_(offset)
765
    {
766
      this->info_offset_ = Swap32::readval(inputs->p_ + offset + 4);
767
      this->flags_ = Swap16::readval(this->inputs_->p_ + offset + 20);
768
    }
769
 
770
    // Return the filename.
771
    const char*
772
    filename() const
773
    {
774
      unsigned int offset = Swap32::readval(this->inputs_->p_ + this->offset_);
775
      return this->inputs_->get_string(offset);
776
    }
777
 
778
    // Return the argument serial number.
779
    unsigned int
780
    arg_serial() const
781
    {
782
      return Swap16::readval(this->inputs_->p_ + this->offset_ + 22);
783
    }
784
 
785
    // Return the timestamp.
786
    Timespec
787
    get_mtime() const
788
    {
789
      Timespec t;
790
      const unsigned char* p = this->inputs_->p_ + this->offset_ + 8;
791
      t.seconds = Swap64::readval(p);
792
      t.nanoseconds = Swap32::readval(p+8);
793
      return t;
794
    }
795
 
796
    // Return the type of input file.
797
    Incremental_input_type
798
    type() const
799
    { return static_cast<Incremental_input_type>(this->flags_ & 0xff); }
800
 
801
    // Return TRUE if the file was found in a system directory.
802
    bool
803
    is_in_system_directory() const
804
    { return (this->flags_ & INCREMENTAL_INPUT_IN_SYSTEM_DIR) != 0; }
805
 
806
    // Return TRUE if the file was linked with --as-needed.
807
    bool
808
    as_needed() const
809
    { return (this->flags_ & INCREMENTAL_INPUT_AS_NEEDED) != 0; }
810
 
811
    // Return the input section count -- for objects only.
812
    unsigned int
813
    get_input_section_count() const
814
    {
815
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
816
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
817
      return Swap32::readval(this->inputs_->p_ + this->info_offset_);
818
    }
819
 
820
    // Return the soname -- for shared libraries only.
821
    const char*
822
    get_soname() const
823
    {
824
      gold_assert(this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
825
      unsigned int offset = Swap32::readval(this->inputs_->p_
826
                                            + this->info_offset_);
827
      return this->inputs_->get_string(offset);
828
    }
829
 
830
    // Return the offset of the supplemental info for symbol SYMNDX --
831
    // for objects only.
832
    unsigned int
833
    get_symbol_offset(unsigned int symndx) const
834
    {
835
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
836
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
837
 
838
      unsigned int section_count = this->get_input_section_count();
839
      return (this->info_offset_ + 28
840
              + section_count * input_section_entry_size
841
              + symndx * 20);
842
    }
843
 
844
    // Return the global symbol count -- for objects & shared libraries only.
845
    unsigned int
846
    get_global_symbol_count() const
847
    {
848
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
849
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER
850
                  || this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
851
      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 4);
852
    }
853
 
854
    // Return the offset of the first local symbol -- for objects only.
855
    unsigned int
856
    get_local_symbol_offset() const
857
    {
858
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
859
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
860
 
861
      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 8);
862
    }
863
 
864
    // Return the local symbol count -- for objects only.
865
    unsigned int
866
    get_local_symbol_count() const
867
    {
868
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
869
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
870
 
871
      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 12);
872
    }
873
 
874
    // Return the index of the first dynamic relocation -- for objects only.
875
    unsigned int
876
    get_first_dyn_reloc() const
877
    {
878
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
879
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
880
 
881
      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 16);
882
    }
883
 
884
    // Return the dynamic relocation count -- for objects only.
885
    unsigned int
886
    get_dyn_reloc_count() const
887
    {
888
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
889
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
890
 
891
      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 20);
892
    }
893
 
894
    // Return the COMDAT group count -- for objects only.
895
    unsigned int
896
    get_comdat_group_count() const
897
    {
898
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
899
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
900
 
901
      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 24);
902
    }
903
 
904
    // Return the object count -- for scripts only.
905
    unsigned int
906
    get_object_count() const
907
    {
908
      gold_assert(this->type() == INCREMENTAL_INPUT_SCRIPT);
909
      return Swap32::readval(this->inputs_->p_ + this->info_offset_);
910
    }
911
 
912
    // Return the input file offset for object N -- for scripts only.
913
    unsigned int
914
    get_object_offset(unsigned int n) const
915
    {
916
      gold_assert(this->type() == INCREMENTAL_INPUT_SCRIPT);
917
      return Swap32::readval(this->inputs_->p_ + this->info_offset_
918
                             + 4 + n * 4);
919
    }
920
 
921
    // Return the member count -- for archives only.
922
    unsigned int
923
    get_member_count() const
924
    {
925
      gold_assert(this->type() == INCREMENTAL_INPUT_ARCHIVE);
926
      return Swap32::readval(this->inputs_->p_ + this->info_offset_);
927
    }
928
 
929
    // Return the unused symbol count -- for archives only.
930
    unsigned int
931
    get_unused_symbol_count() const
932
    {
933
      gold_assert(this->type() == INCREMENTAL_INPUT_ARCHIVE);
934
      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 4);
935
    }
936
 
937
    // Return the input file offset for archive member N -- for archives only.
938
    unsigned int
939
    get_member_offset(unsigned int n) const
940
    {
941
      gold_assert(this->type() == INCREMENTAL_INPUT_ARCHIVE);
942
      return Swap32::readval(this->inputs_->p_ + this->info_offset_
943
                             + 8 + n * 4);
944
    }
945
 
946
    // Return the Nth unused global symbol -- for archives only.
947
    const char*
948
    get_unused_symbol(unsigned int n) const
949
    {
950
      gold_assert(this->type() == INCREMENTAL_INPUT_ARCHIVE);
951
      unsigned int member_count = this->get_member_count();
952
      unsigned int offset = Swap32::readval(this->inputs_->p_
953
                                            + this->info_offset_ + 8
954
                                            + member_count * 4
955
                                            + n * 4);
956
      return this->inputs_->get_string(offset);
957
    }
958
 
959
    // Information about an input section.
960
    struct Input_section_info
961
    {
962
      const char* name;
963
      unsigned int output_shndx;
964
      off_t sh_offset;
965
      off_t sh_size;
966
    };
967
 
968
    // Return info about the Nth input section -- for objects only.
969
    Input_section_info
970
    get_input_section(unsigned int n) const
971
    {
972
      Input_section_info info;
973
      const unsigned char* p = (this->inputs_->p_
974
                                + this->info_offset_ + 28
975
                                + n * input_section_entry_size);
976
      unsigned int name_offset = Swap32::readval(p);
977
      info.name = this->inputs_->get_string(name_offset);
978
      info.output_shndx = Swap32::readval(p + 4);
979
      info.sh_offset = Swap::readval(p + 8);
980
      info.sh_size = Swap::readval(p + 8 + size / 8);
981
      return info;
982
    }
983
 
984
    // Return info about the Nth global symbol -- for objects only.
985
    Incremental_global_symbol_reader<big_endian>
986
    get_global_symbol_reader(unsigned int n) const
987
    {
988
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
989
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
990
      unsigned int section_count = this->get_input_section_count();
991
      const unsigned char* p = (this->inputs_->p_
992
                                + this->info_offset_ + 28
993
                                + section_count * input_section_entry_size
994
                                + n * 20);
995
      return Incremental_global_symbol_reader<big_endian>(p);
996
    }
997
 
998
    // Return the signature of the Nth comdat group -- for objects only.
999
    const char*
1000
    get_comdat_group_signature(unsigned int n) const
1001
    {
1002
      unsigned int section_count = this->get_input_section_count();
1003
      unsigned int symbol_count = this->get_global_symbol_count();
1004
      const unsigned char* p = (this->inputs_->p_
1005
                                + this->info_offset_ + 28
1006
                                + section_count * input_section_entry_size
1007
                                + symbol_count * 20
1008
                                + n * 4);
1009
      unsigned int name_offset = Swap32::readval(p);
1010
      return this->inputs_->get_string(name_offset);
1011
    }
1012
 
1013
    // Return the output symbol index for the Nth global symbol -- for shared
1014
    // libraries only.  Sets *IS_DEF to TRUE if the symbol is defined in this
1015
    // input file.
1016
    unsigned int
1017
    get_output_symbol_index(unsigned int n, bool* is_def)
1018
    {
1019
      gold_assert(this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
1020
      const unsigned char* p = (this->inputs_->p_
1021
                                + this->info_offset_ + 8
1022
                                + n * 4);
1023
      unsigned int output_symndx = Swap32::readval(p);
1024
      *is_def = (output_symndx & (1U << 31)) != 0;
1025
      return output_symndx & ((1U << 31) - 1);
1026
    }
1027
 
1028
   private:
1029
    // Size of an input section entry.
1030
    static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
1031
    // The reader instance for the containing section.
1032
    const Incremental_inputs_reader* inputs_;
1033
    // The flags, including the type of input file.
1034
    unsigned int flags_;
1035
    // Section offset to the input file entry.
1036
    unsigned int offset_;
1037
    // Section offset to the supplemental info for the input file.
1038
    unsigned int info_offset_;
1039
  };
1040
 
1041
  // Return the offset of an input file entry given its index N.
1042
  unsigned int
1043
  input_file_offset(unsigned int n) const
1044
  {
1045
    gold_assert(n < this->input_file_count_);
1046
    return 16 + n * 24;
1047
  }
1048
 
1049
  // Return the index of an input file entry given its OFFSET.
1050
  unsigned int
1051
  input_file_index(unsigned int offset) const
1052
  {
1053
    int n = (offset - 16) / 24;
1054
    gold_assert(input_file_offset(n) == offset);
1055
    return n;
1056
  }
1057
 
1058
  // Return a reader for the Nth input file entry.
1059
  Incremental_input_entry_reader
1060
  input_file(unsigned int n) const
1061
  { return Incremental_input_entry_reader(this, this->input_file_offset(n)); }
1062
 
1063
  // Return a reader for the input file entry at OFFSET.
1064
  Incremental_input_entry_reader
1065
  input_file_at_offset(unsigned int offset) const
1066
  {
1067
    gold_assert(offset < 16 + this->input_file_count_ * 24);
1068
    return Incremental_input_entry_reader(this, offset);
1069
  }
1070
 
1071
  // Return a reader for the global symbol info at OFFSET.
1072
  Incremental_global_symbol_reader<big_endian>
1073
  global_symbol_reader_at_offset(unsigned int offset) const
1074
  {
1075
    const unsigned char* p = this->p_ + offset;
1076
    return Incremental_global_symbol_reader<big_endian>(p);
1077
  }
1078
 
1079
 private:
1080
  // Lookup a string in the ELF string table.
1081
  const char* get_string(unsigned int offset) const
1082
  {
1083
    const char* s;
1084
    if (this->strtab_.get_c_string(offset, &s))
1085
      return s;
1086
    return NULL;
1087
  }
1088
 
1089
  // Base address of the .gnu_incremental_inputs section.
1090
  const unsigned char* p_;
1091
  // The associated ELF string table.
1092
  elfcpp::Elf_strtab strtab_;
1093
  // The number of input file entries in this section.
1094
  unsigned int input_file_count_;
1095
};
1096
 
1097
// Reader class for the .gnu_incremental_symtab section.
1098
 
1099
template<bool big_endian>
1100
class Incremental_symtab_reader
1101
{
1102
 public:
1103
  Incremental_symtab_reader()
1104
    : p_(NULL), len_(0)
1105
  { }
1106
 
1107
  Incremental_symtab_reader(const unsigned char* p, off_t len)
1108
    : p_(p), len_(len)
1109
  { }
1110
 
1111
  // Return the count of symbols in this section.
1112
  unsigned int
1113
  symbol_count() const
1114
  { return static_cast<unsigned int>(this->len_ / 4); }
1115
 
1116
  // Return the list head for symbol table entry N.
1117
  unsigned int
1118
  get_list_head(unsigned int n) const
1119
  { return elfcpp::Swap<32, big_endian>::readval(this->p_ + 4 * n); }
1120
 
1121
 private:
1122
  // Base address of the .gnu_incremental_relocs section.
1123
  const unsigned char* p_;
1124
  // Size of the section.
1125
  off_t len_;
1126
};
1127
 
1128
// Reader class for the .gnu_incremental_relocs section.
1129
 
1130
template<int size, bool big_endian>
1131
class Incremental_relocs_reader
1132
{
1133
 private:
1134
  // Size of each field.
1135
  static const unsigned int field_size = size / 8;
1136
 
1137
 public:
1138
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
1139
  typedef typename elfcpp::Elf_types<size>::Elf_Swxword Addend;
1140
 
1141
  // Size of each entry.
1142
  static const unsigned int reloc_size = 8 + 2 * field_size;
1143
 
1144
  Incremental_relocs_reader()
1145
    : p_(NULL), len_(0)
1146
  { }
1147
 
1148
  Incremental_relocs_reader(const unsigned char* p, off_t len)
1149
    : p_(p), len_(len)
1150
  { }
1151
 
1152
  // Return the count of relocations in this section.
1153
  unsigned int
1154
  reloc_count() const
1155
  { return static_cast<unsigned int>(this->len_ / reloc_size); }
1156
 
1157
  // Return the relocation type for relocation entry at offset OFF.
1158
  unsigned int
1159
  get_r_type(unsigned int off) const
1160
  { return elfcpp::Swap<32, big_endian>::readval(this->p_ + off); }
1161
 
1162
  // Return the output section index for relocation entry at offset OFF.
1163
  unsigned int
1164
  get_r_shndx(unsigned int off) const
1165
  { return elfcpp::Swap<32, big_endian>::readval(this->p_ + off + 4); }
1166
 
1167
  // Return the output section offset for relocation entry at offset OFF.
1168
  Address
1169
  get_r_offset(unsigned int off) const
1170
  { return elfcpp::Swap<size, big_endian>::readval(this->p_ + off + 8); }
1171
 
1172
  // Return the addend for relocation entry at offset OFF.
1173
  Addend
1174
  get_r_addend(unsigned int off) const
1175
  {
1176
    return elfcpp::Swap<size, big_endian>::readval(this->p_ + off + 8
1177
                                                   + this->field_size);
1178
  }
1179
 
1180
  // Return a pointer to the relocation entry at offset OFF.
1181
  const unsigned char*
1182
  data(unsigned int off) const
1183
  { return this->p_ + off; }
1184
 
1185
 private:
1186
  // Base address of the .gnu_incremental_relocs section.
1187
  const unsigned char* p_;
1188
  // Size of the section.
1189
  off_t len_;
1190
};
1191
 
1192
// Reader class for the .gnu_incremental_got_plt section.
1193
 
1194
template<bool big_endian>
1195
class Incremental_got_plt_reader
1196
{
1197
 public:
1198
  Incremental_got_plt_reader()
1199
    : p_(NULL), got_count_(0), got_desc_p_(NULL), plt_desc_p_(NULL)
1200
  { }
1201
 
1202
  Incremental_got_plt_reader(const unsigned char* p) : p_(p)
1203
  {
1204
    this->got_count_ = elfcpp::Swap<32, big_endian>::readval(p);
1205
    this->got_desc_p_ = p + 8 + ((this->got_count_ + 3) & ~3);
1206
    this->plt_desc_p_ = this->got_desc_p_ + this->got_count_ * 8;
1207
  }
1208
 
1209
  // Return the GOT entry count.
1210
  unsigned int
1211
  get_got_entry_count() const
1212
  {
1213
    return this->got_count_;
1214
  }
1215
 
1216
  // Return the PLT entry count.
1217
  unsigned int
1218
  get_plt_entry_count() const
1219
  {
1220
    return elfcpp::Swap<32, big_endian>::readval(this->p_ + 4);
1221
  }
1222
 
1223
  // Return the GOT type for GOT entry N.
1224
  unsigned int
1225
  get_got_type(unsigned int n)
1226
  {
1227
    return this->p_[8 + n];
1228
  }
1229
 
1230
  // Return the symbol index for GOT entry N.
1231
  unsigned int
1232
  get_got_symndx(unsigned int n)
1233
  {
1234
    return elfcpp::Swap<32, big_endian>::readval(this->got_desc_p_ + n * 8);
1235
  }
1236
 
1237
  // Return the input file index for GOT entry N.
1238
  unsigned int
1239
  get_got_input_index(unsigned int n)
1240
  {
1241
    return elfcpp::Swap<32, big_endian>::readval(this->got_desc_p_ + n * 8 + 4);
1242
  }
1243
 
1244
  // Return the PLT descriptor for PLT entry N.
1245
  unsigned int
1246
  get_plt_desc(unsigned int n)
1247
  {
1248
    return elfcpp::Swap<32, big_endian>::readval(this->plt_desc_p_ + n * 4);
1249
  }
1250
 
1251
 private:
1252
  // Base address of the .gnu_incremental_got_plt section.
1253
  const unsigned char* p_;
1254
  // GOT entry count.
1255
  unsigned int got_count_;
1256
  // Base address of the GOT descriptor array.
1257
  const unsigned char* got_desc_p_;
1258
  // Base address of the PLT descriptor array.
1259
  const unsigned char* plt_desc_p_;
1260
};
1261
 
1262
// An object representing the ELF file we edit during an incremental build.
1263
// Similar to Object or Dynobj, but operates on Output_file and contains
1264
// methods to support incremental updating. This is the abstract parent class
1265
// implemented in Sized_incremental_binary<size, big_endian> for a specific
1266
// endianness and size.
1267
 
1268
class Incremental_binary
1269
{
1270
 public:
1271
  Incremental_binary(Output_file* output, Target* target)
1272
    : input_args_map_(), library_map_(), script_map_(),
1273
      output_(output), target_(target)
1274
  { }
1275
 
1276
  virtual
1277
  ~Incremental_binary()
1278
  { }
1279
 
1280
  // Check the .gnu_incremental_inputs section to see whether an incremental
1281
  // build is possible.
1282
  bool
1283
  check_inputs(const Command_line& cmdline,
1284
               Incremental_inputs* incremental_inputs)
1285
  { return this->do_check_inputs(cmdline, incremental_inputs); }
1286
 
1287
  // Report an error.
1288
  void
1289
  error(const char* format, ...) const ATTRIBUTE_PRINTF_2;
1290
 
1291
  // Proxy class for a sized Incremental_input_entry_reader.
1292
 
1293
  class Input_reader
1294
  {
1295
   public:
1296
    Input_reader()
1297
    { }
1298
 
1299
    virtual
1300
    ~Input_reader()
1301
    { }
1302
 
1303
    const char*
1304
    filename() const
1305
    { return this->do_filename(); }
1306
 
1307
    Timespec
1308
    get_mtime() const
1309
    { return this->do_get_mtime(); }
1310
 
1311
    Incremental_input_type
1312
    type() const
1313
    { return this->do_type(); }
1314
 
1315
    unsigned int
1316
    arg_serial() const
1317
    { return this->do_arg_serial(); }
1318
 
1319
    unsigned int
1320
    get_unused_symbol_count() const
1321
    { return this->do_get_unused_symbol_count(); }
1322
 
1323
    const char*
1324
    get_unused_symbol(unsigned int n) const
1325
    { return this->do_get_unused_symbol(n); }
1326
 
1327
   protected:
1328
    virtual const char*
1329
    do_filename() const = 0;
1330
 
1331
    virtual Timespec
1332
    do_get_mtime() const = 0;
1333
 
1334
    virtual Incremental_input_type
1335
    do_type() const = 0;
1336
 
1337
    virtual unsigned int
1338
    do_arg_serial() const = 0;
1339
 
1340
    virtual unsigned int
1341
    do_get_unused_symbol_count() const = 0;
1342
 
1343
    virtual const char*
1344
    do_get_unused_symbol(unsigned int n) const = 0;
1345
  };
1346
 
1347
  // Return the number of input files.
1348
  unsigned int
1349
  input_file_count() const
1350
  { return this->do_input_file_count(); }
1351
 
1352
  // Return an Input_reader for input file N.
1353
  const Input_reader*
1354
  get_input_reader(unsigned int n) const
1355
  { return this->do_get_input_reader(n); }
1356
 
1357
  // Return TRUE if the input file N has changed since the last link.
1358
  bool
1359
  file_has_changed(unsigned int n) const
1360
  { return this->do_file_has_changed(n); }
1361
 
1362
  // Return the Input_argument for input file N.  Returns NULL if
1363
  // the Input_argument is not available.
1364
  const Input_argument*
1365
  get_input_argument(unsigned int n) const
1366
  {
1367
    const Input_reader* input_file = this->do_get_input_reader(n);
1368
    unsigned int arg_serial = input_file->arg_serial();
1369
    if (arg_serial == 0 || arg_serial > this->input_args_map_.size())
1370
      return NULL;
1371
    return this->input_args_map_[arg_serial - 1];
1372
  }
1373
 
1374
  // Return an Incremental_library for the given input file.
1375
  Incremental_library*
1376
  get_library(unsigned int n)
1377
  { return this->library_map_[n]; }
1378
 
1379
  // Return a Script_info for the given input file.
1380
  Script_info*
1381
  get_script_info(unsigned int n)
1382
  { return this->script_map_[n]; }
1383
 
1384
  // Initialize the layout of the output file based on the existing
1385
  // output file.
1386
  void
1387
  init_layout(Layout* layout)
1388
  { this->do_init_layout(layout); }
1389
 
1390
  // Mark regions of the input file that must be kept unchanged.
1391
  void
1392
  reserve_layout(unsigned int input_file_index)
1393
  { this->do_reserve_layout(input_file_index); }
1394
 
1395
  // Process the GOT and PLT entries from the existing output file.
1396
  void
1397
  process_got_plt(Symbol_table* symtab, Layout* layout)
1398
  { this->do_process_got_plt(symtab, layout); }
1399
 
1400
  // Apply incremental relocations for symbols whose values have changed.
1401
  void
1402
  apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
1403
                           Output_file* of)
1404
  { this->do_apply_incremental_relocs(symtab, layout, of); }
1405
 
1406
  // Functions and types for the elfcpp::Elf_file interface.  This
1407
  // permit us to use Incremental_binary as the File template parameter for
1408
  // elfcpp::Elf_file.
1409
 
1410
  // The View class is returned by view.  It must support a single
1411
  // method, data().  This is trivial, because Output_file::get_output_view
1412
  // does what we need.
1413
  class View
1414
  {
1415
   public:
1416
    View(const unsigned char* p)
1417
      : p_(p)
1418
    { }
1419
 
1420
    const unsigned char*
1421
    data() const
1422
    { return this->p_; }
1423
 
1424
   private:
1425
    const unsigned char* p_;
1426
  };
1427
 
1428
  // Return a View.
1429
  View
1430
  view(off_t file_offset, section_size_type data_size)
1431
  { return View(this->output_->get_input_view(file_offset, data_size)); }
1432
 
1433
  // A location in the file.
1434
  struct Location
1435
  {
1436
    off_t file_offset;
1437
    off_t data_size;
1438
 
1439
    Location(off_t fo, section_size_type ds)
1440
      : file_offset(fo), data_size(ds)
1441
    { }
1442
 
1443
    Location()
1444
      : file_offset(0), data_size(0)
1445
    { }
1446
  };
1447
 
1448
  // Get a View given a Location.
1449
  View
1450
  view(Location loc)
1451
  { return View(this->view(loc.file_offset, loc.data_size)); }
1452
 
1453
  // Return the Output_file.
1454
  Output_file*
1455
  output_file()
1456
  { return this->output_; }
1457
 
1458
 protected:
1459
  // Check the .gnu_incremental_inputs section to see whether an incremental
1460
  // build is possible.
1461
  virtual bool
1462
  do_check_inputs(const Command_line& cmdline,
1463
                  Incremental_inputs* incremental_inputs) = 0;
1464
 
1465
  // Return TRUE if input file N has changed since the last incremental link.
1466
  virtual bool
1467
  do_file_has_changed(unsigned int n) const = 0;
1468
 
1469
  // Initialize the layout of the output file based on the existing
1470
  // output file.
1471
  virtual void
1472
  do_init_layout(Layout* layout) = 0;
1473
 
1474
  // Mark regions of the input file that must be kept unchanged.
1475
  virtual void
1476
  do_reserve_layout(unsigned int input_file_index) = 0;
1477
 
1478
  // Process the GOT and PLT entries from the existing output file.
1479
  virtual void
1480
  do_process_got_plt(Symbol_table* symtab, Layout* layout) = 0;
1481
 
1482
  // Apply incremental relocations for symbols whose values have changed.
1483
  virtual void
1484
  do_apply_incremental_relocs(const Symbol_table*, Layout*, Output_file*) = 0;
1485
 
1486
  virtual unsigned int
1487
  do_input_file_count() const = 0;
1488
 
1489
  virtual const Input_reader*
1490
  do_get_input_reader(unsigned int) const = 0;
1491
 
1492
  // Map from input file index to Input_argument.
1493
  std::vector<const Input_argument*> input_args_map_;
1494
  // Map from an input file index to an Incremental_library.
1495
  std::vector<Incremental_library*> library_map_;
1496
  // Map from an input file index to a Script_info.
1497
  std::vector<Script_info*> script_map_;
1498
 
1499
 private:
1500
  // Edited output file object.
1501
  Output_file* output_;
1502
  // Target of the output file.
1503
  Target* target_;
1504
};
1505
 
1506
template<int size, bool big_endian>
1507
class Sized_relobj_incr;
1508
 
1509
template<int size, bool big_endian>
1510
class Sized_incremental_binary : public Incremental_binary
1511
{
1512
 public:
1513
  Sized_incremental_binary(Output_file* output,
1514
                           const elfcpp::Ehdr<size, big_endian>& ehdr,
1515
                           Target* target)
1516
    : Incremental_binary(output, target), elf_file_(this, ehdr),
1517
      input_objects_(), section_map_(), symbol_map_(), main_symtab_loc_(),
1518
      main_strtab_loc_(), has_incremental_info_(false), inputs_reader_(),
1519
      symtab_reader_(), relocs_reader_(), got_plt_reader_(),
1520
      input_entry_readers_()
1521
  { this->setup_readers(); }
1522
 
1523
  // Returns TRUE if the file contains incremental info.
1524
  bool
1525
  has_incremental_info() const
1526
  { return this->has_incremental_info_; }
1527
 
1528
  // Record a pointer to the object for input file N.
1529
  void
1530
  set_input_object(unsigned int n,
1531
                   Sized_relobj_incr<size, big_endian>* obj)
1532
  { this->input_objects_[n] = obj; }
1533
 
1534
  // Return a pointer to the object for input file N.
1535
  Sized_relobj_incr<size, big_endian>*
1536
  input_object(unsigned int n) const
1537
  {
1538
    gold_assert(n < this->input_objects_.size());
1539
    return this->input_objects_[n];
1540
  }
1541
 
1542
  // Return the Output_section for section index SHNDX.
1543
  Output_section*
1544
  output_section(unsigned int shndx)
1545
  { return this->section_map_[shndx]; }
1546
 
1547
  // Map a symbol table entry from the base file to the output symbol table.
1548
  // SYMNDX is relative to the first forced-local or global symbol in the
1549
  // input file symbol table.
1550
  void
1551
  add_global_symbol(unsigned int symndx, Symbol* gsym)
1552
  { this->symbol_map_[symndx] = gsym; }
1553
 
1554
  // Map a symbol table entry from the base file to the output symbol table.
1555
  // SYMNDX is relative to the first forced-local or global symbol in the
1556
  // input file symbol table.
1557
  Symbol*
1558
  global_symbol(unsigned int symndx) const
1559
  { return this->symbol_map_[symndx]; }
1560
 
1561
  // Readers for the incremental info sections.
1562
 
1563
  const Incremental_inputs_reader<size, big_endian>&
1564
  inputs_reader() const
1565
  { return this->inputs_reader_; }
1566
 
1567
  const Incremental_symtab_reader<big_endian>&
1568
  symtab_reader() const
1569
  { return this->symtab_reader_; }
1570
 
1571
  const Incremental_relocs_reader<size, big_endian>&
1572
  relocs_reader() const
1573
  { return this->relocs_reader_; }
1574
 
1575
  const Incremental_got_plt_reader<big_endian>&
1576
  got_plt_reader() const
1577
  { return this->got_plt_reader_; }
1578
 
1579
  void
1580
  get_symtab_view(View* symtab_view, unsigned int* sym_count,
1581
                  elfcpp::Elf_strtab* strtab);
1582
 
1583
 protected:
1584
  typedef Incremental_inputs_reader<size, big_endian> Inputs_reader;
1585
  typedef typename Inputs_reader::Incremental_input_entry_reader
1586
      Input_entry_reader;
1587
 
1588
  virtual bool
1589
  do_check_inputs(const Command_line& cmdline,
1590
                  Incremental_inputs* incremental_inputs);
1591
 
1592
  // Return TRUE if input file N has changed since the last incremental link.
1593
  virtual bool
1594
  do_file_has_changed(unsigned int n) const;
1595
 
1596
  // Initialize the layout of the output file based on the existing
1597
  // output file.
1598
  virtual void
1599
  do_init_layout(Layout* layout);
1600
 
1601
  // Mark regions of the input file that must be kept unchanged.
1602
  virtual void
1603
  do_reserve_layout(unsigned int input_file_index);
1604
 
1605
  // Process the GOT and PLT entries from the existing output file.
1606
  virtual void
1607
  do_process_got_plt(Symbol_table* symtab, Layout* layout);
1608
 
1609
  // Apply incremental relocations for symbols whose values have changed.
1610
  virtual void
1611
  do_apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
1612
                              Output_file* of);
1613
 
1614
  // Proxy class for a sized Incremental_input_entry_reader.
1615
 
1616
  class Sized_input_reader : public Input_reader
1617
  {
1618
   public:
1619
    Sized_input_reader(Input_entry_reader r)
1620
      : Input_reader(), reader_(r)
1621
    { }
1622
 
1623
    virtual
1624
    ~Sized_input_reader()
1625
    { }
1626
 
1627
   private:
1628
    const char*
1629
    do_filename() const
1630
    { return this->reader_.filename(); }
1631
 
1632
    Timespec
1633
    do_get_mtime() const
1634
    { return this->reader_.get_mtime(); }
1635
 
1636
    Incremental_input_type
1637
    do_type() const
1638
    { return this->reader_.type(); }
1639
 
1640
    unsigned int
1641
    do_arg_serial() const
1642
    { return this->reader_.arg_serial(); }
1643
 
1644
    unsigned int
1645
    do_get_unused_symbol_count() const
1646
    { return this->reader_.get_unused_symbol_count(); }
1647
 
1648
    const char*
1649
    do_get_unused_symbol(unsigned int n) const
1650
    { return this->reader_.get_unused_symbol(n); }
1651
 
1652
    Input_entry_reader reader_;
1653
  };
1654
 
1655
  virtual unsigned int
1656
  do_input_file_count() const
1657
  { return this->inputs_reader_.input_file_count(); }
1658
 
1659
  virtual const Input_reader*
1660
  do_get_input_reader(unsigned int n) const
1661
  {
1662
    gold_assert(n < this->input_entry_readers_.size());
1663
    return &this->input_entry_readers_[n];
1664
  }
1665
 
1666
 private:
1667
  bool
1668
  find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
1669
                                   unsigned int* p_symtab_shndx,
1670
                                   unsigned int* p_relocs_shndx,
1671
                                   unsigned int* p_got_plt_shndx,
1672
                                   unsigned int* p_strtab_shndx);
1673
 
1674
  void
1675
  setup_readers();
1676
 
1677
  // Output as an ELF file.
1678
  elfcpp::Elf_file<size, big_endian, Incremental_binary> elf_file_;
1679
 
1680
  // Vector of pointers to the input objects for the unchanged files.
1681
  // For replaced files, the corresponding pointer is NULL.
1682
  std::vector<Sized_relobj_incr<size, big_endian>*> input_objects_;
1683
 
1684
  // Map section index to an Output_section in the updated layout.
1685
  std::vector<Output_section*> section_map_;
1686
 
1687
  // Map global symbols from the input file to the symbol table.
1688
  std::vector<Symbol*> symbol_map_;
1689
 
1690
  // Locations of the main symbol table and symbol string table.
1691
  Location main_symtab_loc_;
1692
  Location main_strtab_loc_;
1693
 
1694
  // Readers for the incremental info sections.
1695
  bool has_incremental_info_;
1696
  Incremental_inputs_reader<size, big_endian> inputs_reader_;
1697
  Incremental_symtab_reader<big_endian> symtab_reader_;
1698
  Incremental_relocs_reader<size, big_endian> relocs_reader_;
1699
  Incremental_got_plt_reader<big_endian> got_plt_reader_;
1700
  std::vector<Sized_input_reader> input_entry_readers_;
1701
};
1702
 
1703
// An incremental Relobj.  This class represents a relocatable object
1704
// that has not changed since the last incremental link, and whose contents
1705
// can be used directly from the base file.
1706
 
1707
template<int size, bool big_endian>
1708
class Sized_relobj_incr : public Sized_relobj<size, big_endian>
1709
{
1710
 public:
1711
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
1712
  typedef typename Sized_relobj<size, big_endian>::Symbols Symbols;
1713
 
1714
  Sized_relobj_incr(const std::string& name,
1715
                    Sized_incremental_binary<size, big_endian>* ibase,
1716
                    unsigned int input_file_index);
1717
 
1718
 private:
1719
  // For convenience.
1720
  typedef Sized_relobj_incr<size, big_endian> This;
1721
  static const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
1722
 
1723
  typedef typename Sized_relobj<size, big_endian>::Output_sections
1724
      Output_sections;
1725
  typedef Incremental_inputs_reader<size, big_endian> Inputs_reader;
1726
  typedef typename Inputs_reader::Incremental_input_entry_reader
1727
      Input_entry_reader;
1728
 
1729
  // A local symbol.
1730
  struct Local_symbol
1731
  {
1732
    Local_symbol(const char* name_, Address value_, unsigned int size_,
1733
                 unsigned int shndx_, unsigned int type_,
1734
                 bool needs_dynsym_entry_)
1735
      : st_value(value_), name(name_), st_size(size_), st_shndx(shndx_),
1736
        st_type(type_), output_dynsym_index(0),
1737
        needs_dynsym_entry(needs_dynsym_entry_)
1738
    { }
1739
    // The symbol value.
1740
    Address st_value;
1741
    // The symbol name.  This points to the stringpool entry.
1742
    const char* name;
1743
    // The symbol size.
1744
    unsigned int st_size;
1745
    // The output section index.
1746
    unsigned int st_shndx : 28;
1747
    // The symbol type.
1748
    unsigned int st_type : 4;
1749
    // The index of the symbol in the output dynamic symbol table.
1750
    unsigned int output_dynsym_index : 31;
1751
    // TRUE if the symbol needs to appear in the dynamic symbol table.
1752
    unsigned int needs_dynsym_entry : 1;
1753
  };
1754
 
1755
  // Return TRUE if this is an incremental (unchanged) input file.
1756
  bool
1757
  do_is_incremental() const
1758
  { return true; }
1759
 
1760
  // Return the last modified time of the file.
1761
  Timespec
1762
  do_get_mtime()
1763
  { return this->input_reader_.get_mtime(); }
1764
 
1765
  // Read the symbols.
1766
  void
1767
  do_read_symbols(Read_symbols_data*);
1768
 
1769
  // Lay out the input sections.
1770
  void
1771
  do_layout(Symbol_table*, Layout*, Read_symbols_data*);
1772
 
1773
  // Layout sections whose layout was deferred while waiting for
1774
  // input files from a plugin.
1775
  void
1776
  do_layout_deferred_sections(Layout*);
1777
 
1778
  // Add the symbols to the symbol table.
1779
  void
1780
  do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);
1781
 
1782
  Archive::Should_include
1783
  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
1784
                           std::string* why);
1785
 
1786
  // Iterate over global symbols, calling a visitor class V for each.
1787
  void
1788
  do_for_all_global_symbols(Read_symbols_data* sd,
1789
                            Library_base::Symbol_visitor_base* v);
1790
 
1791
  // Get the size of a section.
1792
  uint64_t
1793
  do_section_size(unsigned int shndx);
1794
 
1795
  // Get the name of a section.
1796
  std::string
1797
  do_section_name(unsigned int shndx);
1798
 
1799
  // Return a view of the contents of a section.
1800
  Object::Location
1801
  do_section_contents(unsigned int shndx);
1802
 
1803
  // Return section flags.
1804
  uint64_t
1805
  do_section_flags(unsigned int shndx);
1806
 
1807
  // Return section entsize.
1808
  uint64_t
1809
  do_section_entsize(unsigned int shndx);
1810
 
1811
  // Return section address.
1812
  uint64_t
1813
  do_section_address(unsigned int shndx);
1814
 
1815
  // Return section type.
1816
  unsigned int
1817
  do_section_type(unsigned int shndx);
1818
 
1819
  // Return the section link field.
1820
  unsigned int
1821
  do_section_link(unsigned int shndx);
1822
 
1823
  // Return the section link field.
1824
  unsigned int
1825
  do_section_info(unsigned int shndx);
1826
 
1827
  // Return the section alignment.
1828
  uint64_t
1829
  do_section_addralign(unsigned int shndx);
1830
 
1831
  // Return the Xindex structure to use.
1832
  Xindex*
1833
  do_initialize_xindex();
1834
 
1835
  // Get symbol counts.
1836
  void
1837
  do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
1838
 
1839
  // Get global symbols.
1840
  const Symbols*
1841
  do_get_global_symbols() const
1842
  { return &this->symbols_; }
1843
 
1844
  // Return the number of local symbols.
1845
  unsigned int
1846
  do_local_symbol_count() const
1847
  { return this->local_symbol_count_; }
1848
 
1849
  // Return the number of local symbols in the output symbol table.
1850
  unsigned int
1851
  do_output_local_symbol_count() const
1852
  { return this->local_symbol_count_; }
1853
 
1854
  // Return the file offset for local symbols in the output symbol table.
1855
  off_t
1856
  do_local_symbol_offset() const
1857
  { return this->local_symbol_offset_; }
1858
 
1859
  // Read the relocs.
1860
  void
1861
  do_read_relocs(Read_relocs_data*);
1862
 
1863
  // Process the relocs to find list of referenced sections. Used only
1864
  // during garbage collection.
1865
  void
1866
  do_gc_process_relocs(Symbol_table*, Layout*, Read_relocs_data*);
1867
 
1868
  // Scan the relocs and adjust the symbol table.
1869
  void
1870
  do_scan_relocs(Symbol_table*, Layout*, Read_relocs_data*);
1871
 
1872
  // Count the local symbols.
1873
  void
1874
  do_count_local_symbols(Stringpool_template<char>*,
1875
                         Stringpool_template<char>*);
1876
 
1877
  // Finalize the local symbols.
1878
  unsigned int
1879
  do_finalize_local_symbols(unsigned int, off_t, Symbol_table*);
1880
 
1881
  // Set the offset where local dynamic symbol information will be stored.
1882
  unsigned int
1883
  do_set_local_dynsym_indexes(unsigned int);
1884
 
1885
  // Set the offset where local dynamic symbol information will be stored.
1886
  unsigned int
1887
  do_set_local_dynsym_offset(off_t);
1888
 
1889
  // Relocate the input sections and write out the local symbols.
1890
  void
1891
  do_relocate(const Symbol_table* symtab, const Layout*, Output_file* of);
1892
 
1893
  // Set the offset of a section.
1894
  void
1895
  do_set_section_offset(unsigned int shndx, uint64_t off);
1896
 
1897
  // The Incremental_binary base file.
1898
  Sized_incremental_binary<size, big_endian>* ibase_;
1899
  // The index of the object in the input file list.
1900
  unsigned int input_file_index_;
1901
  // The reader for the input file.
1902
  Input_entry_reader input_reader_;
1903
  // The number of local symbols.
1904
  unsigned int local_symbol_count_;
1905
  // The number of local symbols which go into the output file's dynamic
1906
  // symbol table.
1907
  unsigned int output_local_dynsym_count_;
1908
  // This starting symbol index in the output symbol table.
1909
  unsigned int local_symbol_index_;
1910
  // The file offset for local symbols in the output symbol table.
1911
  unsigned int local_symbol_offset_;
1912
  // The file offset for local symbols in the output symbol table.
1913
  unsigned int local_dynsym_offset_;
1914
  // The entries in the symbol table for the external symbols.
1915
  Symbols symbols_;
1916
  // The offset of the first incremental relocation for this object.
1917
  unsigned int incr_reloc_offset_;
1918
  // The number of incremental relocations for this object.
1919
  unsigned int incr_reloc_count_;
1920
  // The index of the first incremental relocation for this object in the
1921
  // updated output file.
1922
  unsigned int incr_reloc_output_index_;
1923
  // A copy of the incremental relocations from this object.
1924
  unsigned char* incr_relocs_;
1925
  // The local symbols.
1926
  std::vector<Local_symbol> local_symbols_;
1927
};
1928
 
1929
// An incremental Dynobj.  This class represents a shared object that has
1930
// not changed since the last incremental link, and whose contents can be
1931
// used directly from the base file.
1932
 
1933
template<int size, bool big_endian>
1934
class Sized_incr_dynobj : public Dynobj
1935
{
1936
 public:
1937
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
1938
 
1939
  static const Address invalid_address = static_cast<Address>(0) - 1;
1940
 
1941
  Sized_incr_dynobj(const std::string& name,
1942
                    Sized_incremental_binary<size, big_endian>* ibase,
1943
                    unsigned int input_file_index);
1944
 
1945
 private:
1946
  typedef Incremental_inputs_reader<size, big_endian> Inputs_reader;
1947
  typedef typename Inputs_reader::Incremental_input_entry_reader
1948
      Input_entry_reader;
1949
 
1950
  // Return TRUE if this is an incremental (unchanged) input file.
1951
  bool
1952
  do_is_incremental() const
1953
  { return true; }
1954
 
1955
  // Return the last modified time of the file.
1956
  Timespec
1957
  do_get_mtime()
1958
  { return this->input_reader_.get_mtime(); }
1959
 
1960
  // Read the symbols.
1961
  void
1962
  do_read_symbols(Read_symbols_data*);
1963
 
1964
  // Lay out the input sections.
1965
  void
1966
  do_layout(Symbol_table*, Layout*, Read_symbols_data*);
1967
 
1968
  // Add the symbols to the symbol table.
1969
  void
1970
  do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);
1971
 
1972
  Archive::Should_include
1973
  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
1974
                           std::string* why);
1975
 
1976
  // Iterate over global symbols, calling a visitor class V for each.
1977
  void
1978
  do_for_all_global_symbols(Read_symbols_data* sd,
1979
                            Library_base::Symbol_visitor_base* v);
1980
 
1981
  // Iterate over local symbols, calling a visitor class V for each GOT offset
1982
  // associated with a local symbol.
1983
  void
1984
  do_for_all_local_got_entries(Got_offset_list::Visitor* v) const;
1985
 
1986
  // Get the size of a section.
1987
  uint64_t
1988
  do_section_size(unsigned int shndx);
1989
 
1990
  // Get the name of a section.
1991
  std::string
1992
  do_section_name(unsigned int shndx);
1993
 
1994
  // Return a view of the contents of a section.
1995
  Object::Location
1996
  do_section_contents(unsigned int shndx);
1997
 
1998
  // Return section flags.
1999
  uint64_t
2000
  do_section_flags(unsigned int shndx);
2001
 
2002
  // Return section entsize.
2003
  uint64_t
2004
  do_section_entsize(unsigned int shndx);
2005
 
2006
  // Return section address.
2007
  uint64_t
2008
  do_section_address(unsigned int shndx);
2009
 
2010
  // Return section type.
2011
  unsigned int
2012
  do_section_type(unsigned int shndx);
2013
 
2014
  // Return the section link field.
2015
  unsigned int
2016
  do_section_link(unsigned int shndx);
2017
 
2018
  // Return the section link field.
2019
  unsigned int
2020
  do_section_info(unsigned int shndx);
2021
 
2022
  // Return the section alignment.
2023
  uint64_t
2024
  do_section_addralign(unsigned int shndx);
2025
 
2026
  // Return the Xindex structure to use.
2027
  Xindex*
2028
  do_initialize_xindex();
2029
 
2030
  // Get symbol counts.
2031
  void
2032
  do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
2033
 
2034
  // Get global symbols.
2035
  const Symbols*
2036
  do_get_global_symbols() const
2037
  { return &this->symbols_; }
2038
 
2039
  // The Incremental_binary base file.
2040
  Sized_incremental_binary<size, big_endian>* ibase_;
2041
  // The index of the object in the input file list.
2042
  unsigned int input_file_index_;
2043
  // The reader for the input file.
2044
  Input_entry_reader input_reader_;
2045
  // The entries in the symbol table for the external symbols.
2046
  Symbols symbols_;
2047
};
2048
 
2049
// Allocate an incremental object of the appropriate size and endianness.
2050
extern Object*
2051
make_sized_incremental_object(
2052
    Incremental_binary* base,
2053
    unsigned int input_file_index,
2054
    Incremental_input_type input_type,
2055
    const Incremental_binary::Input_reader* input_reader);
2056
 
2057
// This class represents an Archive library (or --start-lib/--end-lib group)
2058
// that has not changed since the last incremental link.  Its contents come
2059
// from the incremental inputs entry in the base file.
2060
 
2061
class Incremental_library : public Library_base
2062
{
2063
 public:
2064
  Incremental_library(const char* filename, unsigned int input_file_index,
2065
                      const Incremental_binary::Input_reader* input_reader)
2066
    : Library_base(NULL), filename_(filename),
2067
      input_file_index_(input_file_index), input_reader_(input_reader),
2068
      unused_symbols_(), is_reported_(false)
2069
  { }
2070
 
2071
  // Return the input file index.
2072
  unsigned int
2073
  input_file_index() const
2074
  { return this->input_file_index_; }
2075
 
2076
  // Return the serial number of the input file.
2077
  unsigned int
2078
  arg_serial() const
2079
  { return this->input_reader_->arg_serial(); }
2080
 
2081
  // Copy the unused symbols from the incremental input info.
2082
  // We need to do this because we may be overwriting the incremental
2083
  // input info in the base file before we write the new incremental
2084
  // info.
2085
  void
2086
  copy_unused_symbols();
2087
 
2088
  // Return FALSE on the first call to indicate that the library needs
2089
  // to be recorded; return TRUE subsequently.
2090
  bool
2091
  is_reported()
2092
  {
2093
    bool was_reported = this->is_reported_;
2094
    is_reported_ = true;
2095
    return was_reported;
2096
  }
2097
 
2098
 private:
2099
  typedef std::vector<std::string> Symbol_list;
2100
 
2101
  // The file name.
2102
  const std::string&
2103
  do_filename() const
2104
  { return this->filename_; }
2105
 
2106
  // Return the modification time of the archive file.
2107
  Timespec
2108
  do_get_mtime()
2109
  { return this->input_reader_->get_mtime(); }
2110
 
2111
  // Iterator for unused global symbols in the library.
2112
  void
2113
  do_for_all_unused_symbols(Symbol_visitor_base* v) const;
2114
 
2115
  // The name of the library.
2116
  std::string filename_;
2117
  // The input file index of this library.
2118
  unsigned int input_file_index_;
2119
  // A reader for the incremental input information.
2120
  const Incremental_binary::Input_reader* input_reader_;
2121
  // List of unused symbols defined in this library.
2122
  Symbol_list unused_symbols_;
2123
  // TRUE when this library has been reported to the new incremental info.
2124
  bool is_reported_;
2125
};
2126
 
2127
} // End namespace gold.
2128
 
2129
#endif // !defined(GOLD_INCREMENTAL_H)

powered by: WebSVN 2.1.0

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