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 159

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