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 163

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