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 157

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

powered by: WebSVN 2.1.0

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