1// 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
35namespace gold
36{
37
38class Archive;
39class Input_argument;
40class Incremental_inputs_checker;
41class Incremental_script_entry;
42class Incremental_object_entry;
43class Incremental_archive_entry;
44class Incremental_inputs;
45class Object;
46
47// Incremental input type as stored in .gnu_incremental_inputs.
48
49enum Incremental_input_type
50{
51  INCREMENTAL_INPUT_OBJECT = 1,
52  INCREMENTAL_INPUT_ARCHIVE_MEMBER = 2,
53  INCREMENTAL_INPUT_ARCHIVE = 3,
54  INCREMENTAL_INPUT_SHARED_LIBRARY = 4,
55  INCREMENTAL_INPUT_SCRIPT = 5
56};
57
58// An object representing the ELF file we edit during an incremental build.
59// Similar to Object or Dynobj, but operates on Output_file and contains
60// method specific to file edition (TBD). This is the abstract parent class
61// implemented in Sized_incremental_binary<size, big_endian> for a specific
62// endianness and size.
63
64class Incremental_binary
65{
66 public:
67  Incremental_binary(Output_file* output, Target* target)
68    : output_(output), target_(target)
69  { }
70
71  virtual
72  ~Incremental_binary()
73  { }
74
75  // Functions and types for the elfcpp::Elf_file interface.  This
76  // permit us to use Incremental_binary as the File template parameter for
77  // elfcpp::Elf_file.
78
79  // The View class is returned by view.  It must support a single
80  // method, data().  This is trivial, because Output_file::get_output_view
81  // does what we need.
82  class View
83  {
84   public:
85    View(const unsigned char* p)
86      : p_(p)
87    { }
88
89    const unsigned char*
90    data() const
91    { return this->p_; }
92
93   private:
94    const unsigned char* p_;
95  };
96
97  // Return a View.
98  View
99  view(off_t file_offset, section_size_type data_size)
100  { return View(this->output_->get_input_view(file_offset, data_size)); }
101
102  // A location in the file.
103  struct Location
104  {
105    off_t file_offset;
106    off_t data_size;
107
108    Location(off_t fo, section_size_type ds)
109      : file_offset(fo), data_size(ds)
110    { }
111
112    Location()
113      : file_offset(0), data_size(0)
114    { }
115  };
116
117  // Get a View given a Location.
118  View
119  view(Location loc)
120  { return View(this->view(loc.file_offset, loc.data_size)); }
121
122  // Report an error.
123  void
124  error(const char* format, ...) const ATTRIBUTE_PRINTF_2;
125
126  // Find the .gnu_incremental_inputs and related sections.  It selects the
127  // first section of type SHT_GNU_INCREMENTAL_INPUTS,
128  // SHT_GNU_INCRMENTAL_SYMTAB, and SHT_GNU_INCREMENTAL_RELOCS.
129  // Returns false if the sections are not found.
130  bool
131  find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
132				   unsigned int* p_symtab_shndx,
133				   unsigned int* p_relocs_shndx,
134				   unsigned int* p_got_plt_shndx,
135				   unsigned int* p_strtab_shndx)
136  {
137    return do_find_incremental_inputs_sections(p_inputs_shndx, p_symtab_shndx,
138					       p_relocs_shndx, p_got_plt_shndx,
139  					       p_strtab_shndx);
140  }
141
142  // Check the .gnu_incremental_inputs section to see whether an incremental
143  // build is possible.
144  // TODO: on success, should report what files needs to be rebuilt.
145  // INCREMENTAL_INPUTS is used to read the canonical form of the command line
146  // and read the input arguments.  TODO: for items that don't need to be
147  // rebuilt, we should also copy the incremental input information.
148  virtual bool
149  check_inputs(Incremental_inputs* incremental_inputs)
150  { return do_check_inputs(incremental_inputs); }
151
152 protected:
153  // Find incremental inputs section.
154  virtual bool
155  do_find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
156				      unsigned int* p_symtab_shndx,
157				      unsigned int* p_relocs_shndx,
158				      unsigned int* p_got_plt_shndx,
159				      unsigned int* p_strtab_shndx) = 0;
160
161  // Check the .gnu_incremental_inputs section to see whether an incremental
162  // build is possible.
163  virtual bool
164  do_check_inputs(Incremental_inputs* incremental_inputs) = 0;
165
166 private:
167  // Edited output file object.
168  Output_file* output_;
169  // Target of the output file.
170  Target* target_;
171};
172
173template<int size, bool big_endian>
174class Sized_incremental_binary : public Incremental_binary
175{
176 public:
177  Sized_incremental_binary(Output_file* output,
178                           const elfcpp::Ehdr<size, big_endian>& ehdr,
179                           Target* target)
180    : Incremental_binary(output, target), elf_file_(this, ehdr)
181  { }
182
183 protected:
184  virtual bool
185  do_find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
186				      unsigned int* p_symtab_shndx,
187				      unsigned int* p_relocs_shndx,
188				      unsigned int* p_got_plt_shndx,
189				      unsigned int* p_strtab_shndx);
190
191  virtual bool
192  do_check_inputs(Incremental_inputs* incremental_inputs);
193
194 private:
195  // Output as an ELF file.
196  elfcpp::Elf_file<size, big_endian, Incremental_binary> elf_file_;
197};
198
199// Create an Incremental_binary object for FILE. Returns NULL is this is not
200// possible, e.g. FILE is not an ELF file or has an unsupported target.
201
202Incremental_binary*
203open_incremental_binary(Output_file* file);
204
205// Code invoked early during an incremental link that checks what files need
206// to be relinked.
207
208class Incremental_checker
209{
210 public:
211  // Check if the file named OUTPUT_NAME can be linked incrementally.
212  // INCREMENTAL_INPUTS must have the canonical form of the command line
213  // and input arguments filled - at this point of linking other fields are
214  // probably not filled yet.  TODO: for inputs that don't need to be
215  // rebuilt, this function should fill the incremental input information.
216  Incremental_checker(const char* output_name,
217                      Incremental_inputs* incremental_inputs)
218    : output_name_(output_name), incremental_inputs_(incremental_inputs)
219  { }
220
221  // Analyzes the output file to check if incremental linking is possible and
222  // what files needs to be relinked.
223  bool
224  can_incrementally_link_output_file();
225
226 private:
227  // Name of the output file to analyze.
228  const char* output_name_;
229
230  // The Incremental_inputs object. At this stage of link, only the command
231  // line and inputs are filled.
232  Incremental_inputs* incremental_inputs_;
233};
234
235// Base class for recording each input file.
236
237class Incremental_input_entry
238{
239 public:
240  Incremental_input_entry(Stringpool::Key filename_key, Timespec mtime)
241    : filename_key_(filename_key), offset_(0), info_offset_(0), mtime_(mtime)
242  { }
243
244  virtual
245  ~Incremental_input_entry()
246  { }
247
248  // Return the type of input file.
249  Incremental_input_type
250  type() const
251  { return this->do_type(); }
252
253  // Set the section offset of this input file entry.
254  void
255  set_offset(unsigned int offset)
256  { this->offset_ = offset; }
257
258  // Set the section offset of the supplemental information for this entry.
259  void
260  set_info_offset(unsigned int info_offset)
261  { this->info_offset_ = info_offset; }
262
263  // Get the section offset of this input file entry.
264  unsigned int
265  get_offset() const
266  { return this->offset_; }
267
268  // Get the section offset of the supplemental information for this entry.
269  unsigned int
270  get_info_offset() const
271  { return this->info_offset_; }
272
273  // Get the stringpool key for the input filename.
274  Stringpool::Key
275  get_filename_key() const
276  { return this->filename_key_; }
277
278  // Get the modification time of the input file.
279  const Timespec&
280  get_mtime() const
281  { return this->mtime_; }
282
283  // Return a pointer to the derived Incremental_script_entry object.
284  // Return NULL for input entries that are not script files.
285  Incremental_script_entry*
286  script_entry()
287  { return this->do_script_entry(); }
288
289  // Return a pointer to the derived Incremental_object_entry object.
290  // Return NULL for input entries that are not object files.
291  Incremental_object_entry*
292  object_entry()
293  { return this->do_object_entry(); }
294
295  // Return a pointer to the derived Incremental_archive_entry object.
296  // Return NULL for input entries that are not archive files.
297  Incremental_archive_entry*
298  archive_entry()
299  { return this->do_archive_entry(); }
300
301 protected:
302  // Return the type of input file.
303  virtual Incremental_input_type
304  do_type() const = 0;
305
306  // Return a pointer to the derived Incremental_script_entry object.
307  // Return NULL for input entries that are not script files.
308  virtual Incremental_script_entry*
309  do_script_entry()
310  { return NULL; }
311
312  // Return a pointer to the derived Incremental_object_entry object.
313  // Return NULL for input entries that are not object files.
314  virtual Incremental_object_entry*
315  do_object_entry()
316  { return NULL; }
317
318  // Return a pointer to the derived Incremental_archive_entry object.
319  // Return NULL for input entries that are not archive files.
320  virtual Incremental_archive_entry*
321  do_archive_entry()
322  { return NULL; }
323
324 private:
325  // Key of the filename string in the section stringtable.
326  Stringpool::Key filename_key_;
327
328  // Offset of the entry in the output section.
329  unsigned int offset_;
330
331  // Offset of the extra information in the output section.
332  unsigned int info_offset_;
333
334  // Last modification time of the file.
335  Timespec mtime_;
336};
337
338// Class for recording input scripts.
339
340class Incremental_script_entry : public Incremental_input_entry
341{
342 public:
343  Incremental_script_entry(Stringpool::Key filename_key, Script_info* script,
344			   Timespec mtime)
345    : Incremental_input_entry(filename_key, mtime), script_(script)
346  { }
347
348 protected:
349  virtual Incremental_input_type
350  do_type() const
351  { return INCREMENTAL_INPUT_SCRIPT; }
352
353  // Return a pointer to the derived Incremental_script_entry object.
354  virtual Incremental_script_entry*
355  do_script_entry()
356  { return this; }
357
358 private:
359  // Information about the script file.
360  Script_info* script_;
361};
362
363// Class for recording input object files.
364
365class Incremental_object_entry : public Incremental_input_entry
366{
367 public:
368  Incremental_object_entry(Stringpool::Key filename_key, Object* obj,
369			   Timespec mtime)
370    : Incremental_input_entry(filename_key, mtime), obj_(obj),
371      is_member_(false), sections_()
372  {
373    if (!obj_->is_dynamic())
374      this->sections_.reserve(obj->shnum());
375  }
376
377  // Get the object.
378  Object*
379  object() const
380  { return this->obj_; }
381
382  // Record that this object is an archive member.
383  void
384  set_is_member()
385  { this->is_member_ = true; }
386
387  // Return true if this object is an archive member.
388  bool
389  is_member() const
390  { return this->is_member_; }
391
392  // Add an input section.
393  void
394  add_input_section(unsigned int shndx, Stringpool::Key name_key, off_t sh_size)
395  {
396    if (shndx >= this->sections_.size())
397      this->sections_.resize(shndx + 1);
398    this->sections_[shndx].name_key = name_key;
399    this->sections_[shndx].sh_size = sh_size;
400  }
401
402  // Return the number of input sections in this object.
403  unsigned int
404  get_input_section_count() const
405  { return this->sections_.size(); }
406
407  // Return the stringpool key of the Nth input section.
408  Stringpool::Key
409  get_input_section_name_key(unsigned int n) const
410  { return this->sections_[n].name_key; }
411
412  // Return the size of the Nth input section.
413  off_t
414  get_input_section_size(unsigned int n) const
415  { return this->sections_[n].sh_size; }
416
417 protected:
418  virtual Incremental_input_type
419  do_type() const
420  {
421    return (this->is_member_
422	    ? INCREMENTAL_INPUT_ARCHIVE_MEMBER
423	    : (this->obj_->is_dynamic()
424	       ? INCREMENTAL_INPUT_SHARED_LIBRARY
425	       : INCREMENTAL_INPUT_OBJECT));
426  }
427
428  // Return a pointer to the derived Incremental_object_entry object.
429  virtual Incremental_object_entry*
430  do_object_entry()
431  { return this; }
432
433 private:
434  // The object file itself.
435  Object* obj_;
436
437  // Whether this object is an archive member.
438  bool is_member_;
439
440  // Input sections.
441  struct Input_section
442  {
443    Stringpool::Key name_key;
444    off_t sh_size;
445  };
446  std::vector<Input_section> sections_;
447};
448
449// Class for recording archive library input files.
450
451class Incremental_archive_entry : public Incremental_input_entry
452{
453 public:
454  Incremental_archive_entry(Stringpool::Key filename_key, Archive*,
455			    Timespec mtime)
456    : Incremental_input_entry(filename_key, mtime), members_(), unused_syms_()
457  { }
458
459  // Add a member object to the archive.
460  void
461  add_object(Incremental_object_entry* obj_entry)
462  {
463    this->members_.push_back(obj_entry);
464    obj_entry->set_is_member();
465  }
466
467  // Add an unused global symbol to the archive.
468  void
469  add_unused_global_symbol(Stringpool::Key symbol_key)
470  { this->unused_syms_.push_back(symbol_key); }
471
472  // Return the number of member objects included in the link.
473  unsigned int
474  get_member_count()
475  { return this->members_.size(); }
476
477  // Return the Nth member object.
478  Incremental_object_entry*
479  get_member(unsigned int n)
480  { return this->members_[n]; }
481
482  // Return the number of unused global symbols in this archive.
483  unsigned int
484  get_unused_global_symbol_count()
485  { return this->unused_syms_.size(); }
486
487  // Return the Nth unused global symbol.
488  Stringpool::Key
489  get_unused_global_symbol(unsigned int n)
490  { return this->unused_syms_[n]; }
491
492 protected:
493  virtual Incremental_input_type
494  do_type() const
495  { return INCREMENTAL_INPUT_ARCHIVE; }
496
497  // Return a pointer to the derived Incremental_archive_entry object.
498  virtual Incremental_archive_entry*
499  do_archive_entry()
500  { return this; }
501
502 private:
503  // Members of the archive that have been included in the link.
504  std::vector<Incremental_object_entry*> members_;
505
506  // Unused global symbols from this archive.
507  std::vector<Stringpool::Key> unused_syms_;
508};
509
510// This class contains the information needed during an incremental
511// build about the inputs necessary to build the .gnu_incremental_inputs.
512
513class Incremental_inputs
514{
515 public:
516  typedef std::vector<Incremental_input_entry*> Input_list;
517
518  Incremental_inputs()
519    : inputs_(), command_line_(), command_line_key_(0),
520      strtab_(new Stringpool()), current_object_(NULL),
521      current_object_entry_(NULL), inputs_section_(NULL),
522      symtab_section_(NULL), relocs_section_(NULL),
523      reloc_count_(0)
524  { }
525
526  ~Incremental_inputs() { delete this->strtab_; }
527
528  // Record the command line.
529  void
530  report_command_line(int argc, const char* const* argv);
531
532  // Record the initial info for archive file ARCHIVE.
533  void
534  report_archive_begin(Archive* arch);
535
536  // Record the final info for archive file ARCHIVE.
537  void
538  report_archive_end(Archive* arch);
539
540  // Record the info for object file OBJ.  If ARCH is not NULL,
541  // attach the object file to the archive.
542  void
543  report_object(Object* obj, Archive* arch);
544
545  // Record an input section belonging to object file OBJ.
546  void
547  report_input_section(Object* obj, unsigned int shndx, const char* name,
548		       off_t sh_size);
549
550  // Record the info for input script SCRIPT.
551  void
552  report_script(const std::string& filename, Script_info* script,
553		Timespec mtime);
554
555  // Return the running count of incremental relocations.
556  unsigned int
557  get_reloc_count() const
558  { return this->reloc_count_; }
559
560  // Update the running count of incremental relocations.
561  void
562  set_reloc_count(unsigned int count)
563  { this->reloc_count_ = count; }
564
565  // Prepare for layout.  Called from Layout::finalize.
566  void
567  finalize();
568
569  // Create the .gnu_incremental_inputs and related sections.
570  void
571  create_data_sections(Symbol_table* symtab);
572
573  // Return the .gnu_incremental_inputs section.
574  Output_section_data*
575  inputs_section() const
576  { return this->inputs_section_; }
577
578  // Return the .gnu_incremental_symtab section.
579  Output_data_space*
580  symtab_section() const
581  { return this->symtab_section_; }
582
583  // Return the .gnu_incremental_relocs section.
584  Output_data_space*
585  relocs_section() const
586  { return this->relocs_section_; }
587
588  // Return the .gnu_incremental_got_plt section.
589  Output_data_space*
590  got_plt_section() const
591  { return this->got_plt_section_; }
592
593  // Return the .gnu_incremental_strtab stringpool.
594  Stringpool*
595  get_stringpool() const
596  { return this->strtab_; }
597
598  // Return the canonical form of the command line, as will be stored in
599  // .gnu_incremental_strtab.
600  const std::string&
601  command_line() const
602  { return this->command_line_; }
603
604  // Return the stringpool key of the command line.
605  Stringpool::Key
606  command_line_key() const
607  { return this->command_line_key_; }
608
609  // Return the number of input files.
610  int
611  input_file_count() const
612  { return this->inputs_.size(); }
613
614  // Return the input files.
615  const Input_list&
616  input_files() const
617  { return this->inputs_; }
618
619  // Return the sh_entsize value for the .gnu_incremental_relocs section.
620  unsigned int
621  relocs_entsize() const;
622
623 private:
624  // The list of input files.
625  Input_list inputs_;
626
627  // Canonical form of the command line, as will be stored in
628  // .gnu_incremental_strtab.
629  std::string command_line_;
630
631  // The key of the command line string in the string pool.
632  Stringpool::Key command_line_key_;
633
634  // The .gnu_incremental_strtab string pool associated with the
635  // .gnu_incremental_inputs.
636  Stringpool* strtab_;
637
638  // Keep track of the object currently being processed.
639  Object* current_object_;
640  Incremental_object_entry* current_object_entry_;
641
642  // The .gnu_incremental_inputs section.
643  Output_section_data* inputs_section_;
644
645  // The .gnu_incremental_symtab section.
646  Output_data_space* symtab_section_;
647
648  // The .gnu_incremental_relocs section.
649  Output_data_space* relocs_section_;
650
651  // The .gnu_incremental_got_plt section.
652  Output_data_space* got_plt_section_;
653
654  // Total count of incremental relocations.  Updated during Scan_relocs
655  // phase at the completion of each object file.
656  unsigned int reloc_count_;
657};
658
659// Reader class for .gnu_incremental_inputs section.
660
661template<int size, bool big_endian>
662class Incremental_inputs_reader
663{
664 private:
665  typedef elfcpp::Swap<size, big_endian> Swap;
666  typedef elfcpp::Swap<16, big_endian> Swap16;
667  typedef elfcpp::Swap<32, big_endian> Swap32;
668  typedef elfcpp::Swap<64, big_endian> Swap64;
669
670 public:
671  Incremental_inputs_reader(const unsigned char* p, elfcpp::Elf_strtab& strtab)
672    : p_(p), strtab_(strtab)
673  { this->input_file_count_ = Swap32::readval(this->p_ + 4); }
674
675  // Return the version number.
676  unsigned int
677  version() const
678  { return Swap32::readval(this->p_); }
679
680  // Return the count of input file entries.
681  unsigned int
682  input_file_count() const
683  { return this->input_file_count_; }
684
685  // Return the command line.
686  const char*
687  command_line() const
688  {
689    unsigned int offset = Swap32::readval(this->p_ + 8);
690    return this->get_string(offset);
691  }
692
693  // Reader class for an input file entry and its supplemental info.
694  class Incremental_input_entry_reader
695  {
696   public:
697    Incremental_input_entry_reader(const Incremental_inputs_reader* inputs,
698				   unsigned int offset)
699      : inputs_(inputs), offset_(offset)
700    {
701      this->info_offset_ = Swap32::readval(inputs->p_ + offset + 4);
702      int type = Swap16::readval(this->inputs_->p_ + offset + 20);
703      this->type_ = static_cast<Incremental_input_type>(type);
704    }
705
706    // Return the filename.
707    const char*
708    filename() const
709    {
710      unsigned int offset = Swap32::readval(this->inputs_->p_ + this->offset_);
711      return this->inputs_->get_string(offset);
712    }
713
714    // Return the timestamp.
715    Timespec
716    get_mtime() const
717    {
718      Timespec t;
719      const unsigned char* p = this->inputs_->p_ + this->offset_ + 8;
720      t.seconds = Swap64::readval(p);
721      t.nanoseconds = Swap32::readval(p+8);
722      return t;
723    }
724
725    // Return the type of input file.
726    Incremental_input_type
727    type() const
728    { return this->type_; }
729
730    // Return the input section count -- for objects only.
731    unsigned int
732    get_input_section_count() const
733    {
734      gold_assert(this->type_ == INCREMENTAL_INPUT_OBJECT
735		  || this->type_ == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
736      return Swap32::readval(this->inputs_->p_ + this->info_offset_);
737    }
738
739    // Return the offset of the supplemental info for symbol SYMNDX --
740    // for objects only.
741    unsigned int
742    get_symbol_offset(unsigned int symndx) const
743    {
744      gold_assert(this->type_ == INCREMENTAL_INPUT_OBJECT
745		  || this->type_ == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
746
747      unsigned int section_count = this->get_input_section_count();
748      return (this->info_offset_ + 8
749	      + section_count * input_section_entry_size
750	      + symndx * 16);
751    }
752
753    // Return the global symbol count -- for objects & shared libraries only.
754    unsigned int
755    get_global_symbol_count() const
756    {
757      switch (this->type_)
758	{
759	case INCREMENTAL_INPUT_OBJECT:
760	case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
761	  return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 4);
762	case INCREMENTAL_INPUT_SHARED_LIBRARY:
763	  return Swap32::readval(this->inputs_->p_ + this->info_offset_);
764	default:
765	  gold_unreachable();
766	}
767    }
768
769    // Return the member count -- for archives only.
770    unsigned int
771    get_member_count() const
772    {
773      gold_assert(this->type_ == INCREMENTAL_INPUT_ARCHIVE);
774      return Swap32::readval(this->inputs_->p_ + this->info_offset_);
775    }
776
777    // Return the unused symbol count -- for archives only.
778    unsigned int
779    get_unused_symbol_count() const
780    {
781      gold_assert(this->type_ == INCREMENTAL_INPUT_ARCHIVE);
782      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 4);
783    }
784
785    // Return the input file offset for archive member N -- for archives only.
786    unsigned int
787    get_member_offset(unsigned int n) const
788    {
789      gold_assert(this->type_ == INCREMENTAL_INPUT_ARCHIVE);
790      return Swap32::readval(this->inputs_->p_ + this->info_offset_
791			     + 8 + n * 4);
792    }
793
794    // Return the Nth unused global symbol -- for archives only.
795    const char*
796    get_unused_symbol(unsigned int n) const
797    {
798      gold_assert(this->type_ == INCREMENTAL_INPUT_ARCHIVE);
799      unsigned int member_count = this->get_member_count();
800      unsigned int offset = Swap32::readval(this->inputs_->p_
801					    + this->info_offset_ + 8
802					    + member_count * 4
803					    + n * 4);
804      return this->inputs_->get_string(offset);
805    }
806
807    // Information about an input section.
808    struct Input_section_info
809    {
810      const char* name;
811      unsigned int output_shndx;
812      off_t sh_offset;
813      off_t sh_size;
814    };
815
816    // Return info about the Nth input section -- for objects only.
817    Input_section_info
818    get_input_section(unsigned int n) const
819    {
820      Input_section_info info;
821      const unsigned char* p = (this->inputs_->p_
822				+ this->info_offset_ + 8
823				+ n * input_section_entry_size);
824      unsigned int name_offset = Swap32::readval(p);
825      info.name = this->inputs_->get_string(name_offset);
826      info.output_shndx = Swap32::readval(p + 4);
827      info.sh_offset = Swap::readval(p + 8);
828      info.sh_size = Swap::readval(p + 8 + size / 8);
829      return info;
830    }
831
832    // Information about a global symbol.
833    struct Global_symbol_info
834    {
835      unsigned int output_symndx;
836      unsigned int next_offset;
837      unsigned int reloc_count;
838      unsigned int reloc_offset;
839    };
840
841    // Return info about the Nth global symbol -- for objects only.
842    Global_symbol_info
843    get_global_symbol_info(unsigned int n) const
844    {
845      Global_symbol_info info;
846      unsigned int section_count = this->get_input_section_count();
847      const unsigned char* p = (this->inputs_->p_
848				+ this->info_offset_ + 8
849				+ section_count * input_section_entry_size
850				+ n * 16);
851      info.output_symndx = Swap32::readval(p);
852      info.next_offset = Swap32::readval(p + 4);
853      info.reloc_count = Swap::readval(p + 8);
854      info.reloc_offset = Swap::readval(p + 12);
855      return info;
856    }
857
858   private:
859    // Size of an input section entry.
860    static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
861    // The reader instance for the containing section.
862    const Incremental_inputs_reader* inputs_;
863    // The type of input file.
864    Incremental_input_type type_;
865    // Section offset to the input file entry.
866    unsigned int offset_;
867    // Section offset to the supplemental info for the input file.
868    unsigned int info_offset_;
869  };
870
871  // Return a reader for the Nth input file entry.
872  Incremental_input_entry_reader
873  input_file(unsigned int n) const
874  {
875    gold_assert(n < this->input_file_count_);
876    Incremental_input_entry_reader input(this, 16 + n * 24);
877    return input;
878  }
879
880 private:
881  // Lookup a string in the ELF string table.
882  const char* get_string(unsigned int offset) const
883  {
884    const char* s;
885    if (this->strtab_.get_c_string(offset, &s))
886      return s;
887    return NULL;
888  }
889
890  // Base address of the .gnu_incremental_inputs section.
891  const unsigned char* p_;
892  // The associated ELF string table.
893  elfcpp::Elf_strtab strtab_;
894  // The number of input file entries in this section.
895  unsigned int input_file_count_;
896};
897
898// Reader class for the .gnu_incremental_symtab section.
899
900template<bool big_endian>
901class Incremental_symtab_reader
902{
903 public:
904  Incremental_symtab_reader(const unsigned char* p) : p_(p)
905  { }
906
907  // Return the list head for symbol table entry N.
908  unsigned int get_list_head(unsigned int n) const
909  { return elfcpp::Swap<32, big_endian>::readval(this->p_ + 4 * n); }
910
911 private:
912  // Base address of the .gnu_incremental_relocs section.
913  const unsigned char* p_;
914};
915
916// Reader class for the .gnu_incremental_relocs section.
917
918template<int size, bool big_endian>
919class Incremental_relocs_reader
920{
921 private:
922  // Size of each field.
923  static const unsigned int field_size = size / 8;
924
925 public:
926  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
927  typedef typename elfcpp::Elf_types<size>::Elf_Swxword Addend;
928
929  // Size of each entry.
930  static const unsigned int reloc_size = 8 + 2 * field_size;
931
932  Incremental_relocs_reader(const unsigned char* p) : p_(p)
933  { }
934
935  // Return the relocation type for relocation entry at offset OFF.
936  unsigned int
937  get_r_type(unsigned int off) const
938  {
939    return elfcpp::Swap<32, big_endian>::readval(this->p_ + off);
940  }
941
942  // Return the output section index for relocation entry at offset OFF.
943  unsigned int
944  get_r_shndx(unsigned int off) const
945  {
946    return elfcpp::Swap<32, big_endian>::readval(this->p_ + off + 4);
947  }
948
949  // Return the output section offset for relocation entry at offset OFF.
950  Address
951  get_r_offset(unsigned int off) const
952  {
953    return elfcpp::Swap<size, big_endian>::readval(this->p_ + off + 8);
954  }
955
956  // Return the addend for relocation entry at offset OFF.
957  Addend
958  get_r_addend(unsigned int off) const
959  {
960    return elfcpp::Swap<size, big_endian>::readval(this->p_ + off + 8
961						   + this->field_size);
962  }
963
964 private:
965  // Base address of the .gnu_incremental_relocs section.
966  const unsigned char* p_;
967};
968
969// Reader class for the .gnu_incremental_got_plt section.
970
971template<bool big_endian>
972class Incremental_got_plt_reader
973{
974 public:
975  Incremental_got_plt_reader(const unsigned char* p) : p_(p)
976  {
977    this->got_count_ = elfcpp::Swap<32, big_endian>::readval(p);
978    this->got_desc_p_ = p + 8 + ((this->got_count_ + 3) & ~3);
979    this->plt_desc_p_ = this->got_desc_p_ + this->got_count_ * 4;
980  }
981
982  // Return the GOT entry count.
983  unsigned int
984  get_got_entry_count() const
985  {
986    return this->got_count_;
987  }
988
989  // Return the PLT entry count.
990  unsigned int
991  get_plt_entry_count() const
992  {
993    return elfcpp::Swap<32, big_endian>::readval(this->p_ + 4);
994  }
995
996  // Return the GOT type for GOT entry N.
997  unsigned int
998  get_got_type(unsigned int n)
999  {
1000    return this->p_[8 + n];
1001  }
1002
1003  // Return the GOT descriptor for GOT entry N.
1004  unsigned int
1005  get_got_desc(unsigned int n)
1006  {
1007    return elfcpp::Swap<32, big_endian>::readval(this->got_desc_p_ + n * 4);
1008  }
1009
1010  // Return the PLT descriptor for PLT entry N.
1011  unsigned int
1012  get_plt_desc(unsigned int n)
1013  {
1014    return elfcpp::Swap<32, big_endian>::readval(this->plt_desc_p_ + n * 4);
1015  }
1016
1017 private:
1018  // Base address of the .gnu_incremental_got_plt section.
1019  const unsigned char* p_;
1020  // GOT entry count.
1021  unsigned int got_count_;
1022  // Base address of the GOT descriptor array.
1023  const unsigned char* got_desc_p_;
1024  // Base address of the PLT descriptor array.
1025  const unsigned char* plt_desc_p_;
1026};
1027
1028} // End namespace gold.
1029
1030#endif // !defined(GOLD_INCREMENTAL_H)
1031