c1f3c990894cbd06d02a737a10bc1f7c4f399b54
[platform/upstream/binutils.git] / gold / incremental.h
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
35 namespace gold
36 {
37
38 class Archive;
39 class Input_argument;
40 class Incremental_inputs_checker;
41 class Incremental_script_entry;
42 class Incremental_object_entry;
43 class Incremental_archive_entry;
44 class Incremental_inputs;
45 class Object;
46
47 // Incremental input type as stored in .gnu_incremental_inputs.
48
49 enum 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
64 class 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
173 template<int size, bool big_endian>
174 class 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
202 Incremental_binary*
203 open_incremental_binary(Output_file* file);
204
205 // Code invoked early during an incremental link that checks what files need
206 // to be relinked.
207
208 class 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
237 class 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   // Return the type of input file.
245   Incremental_input_type
246   type() const
247   { return this->do_type(); }
248
249   // Set the section offset of this input file entry.
250   void
251   set_offset(unsigned int offset)
252   { this->offset_ = offset; }
253
254   // Set the section offset of the supplemental information for this entry.
255   void
256   set_info_offset(unsigned int info_offset)
257   { this->info_offset_ = info_offset; }
258
259   // Get the section offset of this input file entry.
260   unsigned int
261   get_offset() const
262   { return this->offset_; }
263
264   // Get the section offset of the supplemental information for this entry.
265   unsigned int
266   get_info_offset() const
267   { return this->info_offset_; }
268
269   // Get the stringpool key for the input filename.
270   Stringpool::Key
271   get_filename_key() const
272   { return this->filename_key_; }
273
274   // Get the modification time of the input file.
275   const Timespec&
276   get_mtime() const
277   { return this->mtime_; }
278
279   // Return a pointer to the derived Incremental_script_entry object.
280   // Return NULL for input entries that are not script files.
281   Incremental_script_entry*
282   script_entry()
283   { return this->do_script_entry(); }
284
285   // Return a pointer to the derived Incremental_object_entry object.
286   // Return NULL for input entries that are not object files.
287   Incremental_object_entry*
288   object_entry()
289   { return this->do_object_entry(); }
290
291   // Return a pointer to the derived Incremental_archive_entry object.
292   // Return NULL for input entries that are not archive files.
293   Incremental_archive_entry*
294   archive_entry()
295   { return this->do_archive_entry(); }
296
297  protected:
298   // Return the type of input file.
299   virtual Incremental_input_type
300   do_type() const = 0;
301
302   // Return a pointer to the derived Incremental_script_entry object.
303   // Return NULL for input entries that are not script files.
304   virtual Incremental_script_entry*
305   do_script_entry()
306   { return NULL; }
307
308   // Return a pointer to the derived Incremental_object_entry object.
309   // Return NULL for input entries that are not object files.
310   virtual Incremental_object_entry*
311   do_object_entry()
312   { return NULL; }
313
314   // Return a pointer to the derived Incremental_archive_entry object.
315   // Return NULL for input entries that are not archive files.
316   virtual Incremental_archive_entry*
317   do_archive_entry()
318   { return NULL; }
319
320  private:
321   // Key of the filename string in the section stringtable.
322   Stringpool::Key filename_key_;
323
324   // Offset of the entry in the output section.
325   unsigned int offset_;
326
327   // Offset of the extra information in the output section.
328   unsigned int info_offset_;
329
330   // Last modification time of the file.
331   Timespec mtime_;
332 };
333
334 // Class for recording input scripts.
335
336 class Incremental_script_entry : public Incremental_input_entry
337 {
338  public:
339   Incremental_script_entry(Stringpool::Key filename_key, Script_info* script,
340                            Timespec mtime)
341     : Incremental_input_entry(filename_key, mtime), script_(script)
342   { }
343
344  protected:
345   virtual Incremental_input_type
346   do_type() const
347   { return INCREMENTAL_INPUT_SCRIPT; }
348
349   // Return a pointer to the derived Incremental_script_entry object.
350   virtual Incremental_script_entry*
351   do_script_entry()
352   { return this; }
353
354  private:
355   // Information about the script file.
356   Script_info* script_;
357 };
358
359 // Class for recording input object files.
360
361 class Incremental_object_entry : public Incremental_input_entry
362 {
363  public:
364   Incremental_object_entry(Stringpool::Key filename_key, Object* obj,
365                            Timespec mtime)
366     : Incremental_input_entry(filename_key, mtime), obj_(obj),
367       is_member_(false), sections_()
368   {
369     if (!obj_->is_dynamic())
370       this->sections_.reserve(obj->shnum());
371   }
372
373   // Get the object.
374   Object*
375   object() const
376   { return this->obj_; }
377
378   // Record that this object is an archive member.
379   void
380   set_is_member()
381   { this->is_member_ = true; }
382
383   // Return true if this object is an archive member.
384   bool
385   is_member() const
386   { return this->is_member_; }
387
388   // Add an input section.
389   void
390   add_input_section(unsigned int shndx, Stringpool::Key name_key, off_t sh_size)
391   {
392     if (shndx >= this->sections_.size())
393       this->sections_.resize(shndx + 1);
394     this->sections_[shndx].name_key = name_key;
395     this->sections_[shndx].sh_size = sh_size;
396   }
397
398   // Return the number of input sections in this object.
399   unsigned int
400   get_input_section_count() const
401   { return this->sections_.size(); }
402
403   // Return the stringpool key of the Nth input section.
404   Stringpool::Key
405   get_input_section_name_key(unsigned int n) const
406   { return this->sections_[n].name_key; }
407
408   // Return the size of the Nth input section.
409   off_t
410   get_input_section_size(unsigned int n) const
411   { return this->sections_[n].sh_size; }
412
413  protected:
414   virtual Incremental_input_type
415   do_type() const
416   {
417     return (this->is_member_
418             ? INCREMENTAL_INPUT_ARCHIVE_MEMBER
419             : (this->obj_->is_dynamic()
420                ? INCREMENTAL_INPUT_SHARED_LIBRARY
421                : INCREMENTAL_INPUT_OBJECT));
422   }
423
424   // Return a pointer to the derived Incremental_object_entry object.
425   virtual Incremental_object_entry*
426   do_object_entry()
427   { return this; }
428
429  private:
430   // The object file itself.
431   Object* obj_;
432
433   // Whether this object is an archive member.
434   bool is_member_;
435
436   // Input sections.
437   struct Input_section
438   {
439     Stringpool::Key name_key;
440     off_t sh_size;
441   };
442   std::vector<Input_section> sections_;
443 };
444
445 // Class for recording archive library input files.
446
447 class Incremental_archive_entry : public Incremental_input_entry
448 {
449  public:
450   Incremental_archive_entry(Stringpool::Key filename_key, Archive*,
451                             Timespec mtime)
452     : Incremental_input_entry(filename_key, mtime), members_(), unused_syms_()
453   { }
454
455   // Add a member object to the archive.
456   void
457   add_object(Incremental_object_entry* obj_entry)
458   {
459     this->members_.push_back(obj_entry);
460     obj_entry->set_is_member();
461   }
462
463   // Add an unused global symbol to the archive.
464   void
465   add_unused_global_symbol(Stringpool::Key symbol_key)
466   { this->unused_syms_.push_back(symbol_key); }
467
468   // Return the number of member objects included in the link.
469   unsigned int
470   get_member_count()
471   { return this->members_.size(); }
472
473   // Return the Nth member object.
474   Incremental_object_entry*
475   get_member(unsigned int n)
476   { return this->members_[n]; }
477
478   // Return the number of unused global symbols in this archive.
479   unsigned int
480   get_unused_global_symbol_count()
481   { return this->unused_syms_.size(); }
482
483   // Return the Nth unused global symbol.
484   Stringpool::Key
485   get_unused_global_symbol(unsigned int n)
486   { return this->unused_syms_[n]; }
487
488  protected:
489   virtual Incremental_input_type
490   do_type() const
491   { return INCREMENTAL_INPUT_ARCHIVE; }
492
493   // Return a pointer to the derived Incremental_archive_entry object.
494   virtual Incremental_archive_entry*
495   do_archive_entry()
496   { return this; }
497
498  private:
499   // Members of the archive that have been included in the link.
500   std::vector<Incremental_object_entry*> members_;
501
502   // Unused global symbols from this archive.
503   std::vector<Stringpool::Key> unused_syms_;
504 };
505
506 // This class contains the information needed during an incremental
507 // build about the inputs necessary to build the .gnu_incremental_inputs.
508
509 class Incremental_inputs
510 {
511  public:
512   typedef std::vector<Incremental_input_entry*> Input_list;
513
514   Incremental_inputs()
515     : inputs_(), command_line_(), command_line_key_(0),
516       strtab_(new Stringpool()), current_object_(NULL),
517       current_object_entry_(NULL), inputs_section_(NULL),
518       symtab_section_(NULL), relocs_section_(NULL),
519       reloc_count_(0)
520   { }
521
522   ~Incremental_inputs() { delete this->strtab_; }
523
524   // Record the command line.
525   void
526   report_command_line(int argc, const char* const* argv);
527
528   // Record the initial info for archive file ARCHIVE.
529   void
530   report_archive_begin(Archive* arch);
531
532   // Record the final info for archive file ARCHIVE.
533   void
534   report_archive_end(Archive* arch);
535
536   // Record the info for object file OBJ.  If ARCH is not NULL,
537   // attach the object file to the archive.
538   void
539   report_object(Object* obj, Archive* arch);
540
541   // Record an input section belonging to object file OBJ.
542   void
543   report_input_section(Object* obj, unsigned int shndx, const char* name,
544                        off_t sh_size);
545
546   // Record the info for input script SCRIPT.
547   void
548   report_script(const std::string& filename, Script_info* script,
549                 Timespec mtime);
550
551   // Return the running count of incremental relocations.
552   unsigned int
553   get_reloc_count() const
554   { return this->reloc_count_; }
555
556   // Update the running count of incremental relocations.
557   void
558   set_reloc_count(unsigned int count)
559   { this->reloc_count_ = count; }
560
561   // Prepare for layout.  Called from Layout::finalize.
562   void
563   finalize();
564
565   // Create the .gnu_incremental_inputs and related sections.
566   void
567   create_data_sections(Symbol_table* symtab);
568
569   // Return the .gnu_incremental_inputs section.
570   Output_section_data*
571   inputs_section() const
572   { return this->inputs_section_; }
573
574   // Return the .gnu_incremental_symtab section.
575   Output_data_space*
576   symtab_section() const
577   { return this->symtab_section_; }
578
579   // Return the .gnu_incremental_relocs section.
580   Output_data_space*
581   relocs_section() const
582   { return this->relocs_section_; }
583
584   // Return the .gnu_incremental_got_plt section.
585   Output_data_space*
586   got_plt_section() const
587   { return this->got_plt_section_; }
588
589   // Return the .gnu_incremental_strtab stringpool.
590   Stringpool*
591   get_stringpool() const
592   { return this->strtab_; }
593
594   // Return the canonical form of the command line, as will be stored in
595   // .gnu_incremental_strtab.
596   const std::string&
597   command_line() const
598   { return this->command_line_; }
599
600   // Return the stringpool key of the command line.
601   Stringpool::Key
602   command_line_key() const
603   { return this->command_line_key_; }
604
605   // Return the number of input files.
606   int
607   input_file_count() const
608   { return this->inputs_.size(); }
609
610   // Return the input files.
611   const Input_list&
612   input_files() const
613   { return this->inputs_; }
614
615   // Return the sh_entsize value for the .gnu_incremental_relocs section.
616   unsigned int
617   relocs_entsize() const;
618
619  private:
620   // The list of input files.
621   Input_list inputs_;
622
623   // Canonical form of the command line, as will be stored in
624   // .gnu_incremental_strtab.
625   std::string command_line_;
626
627   // The key of the command line string in the string pool.
628   Stringpool::Key command_line_key_;
629
630   // The .gnu_incremental_strtab string pool associated with the
631   // .gnu_incremental_inputs.
632   Stringpool* strtab_;
633
634   // Keep track of the object currently being processed.
635   Object* current_object_;
636   Incremental_object_entry* current_object_entry_;
637
638   // The .gnu_incremental_inputs section.
639   Output_section_data* inputs_section_;
640
641   // The .gnu_incremental_symtab section.
642   Output_data_space* symtab_section_;
643
644   // The .gnu_incremental_relocs section.
645   Output_data_space* relocs_section_;
646
647   // The .gnu_incremental_got_plt section.
648   Output_data_space* got_plt_section_;
649
650   // Total count of incremental relocations.  Updated during Scan_relocs
651   // phase at the completion of each object file.
652   unsigned int reloc_count_;
653 };
654
655 // Reader class for .gnu_incremental_inputs section.
656
657 template<int size, bool big_endian>
658 class Incremental_inputs_reader
659 {
660  private:
661   typedef elfcpp::Swap<size, big_endian> Swap;
662   typedef elfcpp::Swap<16, big_endian> Swap16;
663   typedef elfcpp::Swap<32, big_endian> Swap32;
664   typedef elfcpp::Swap<64, big_endian> Swap64;
665
666  public:
667   Incremental_inputs_reader(const unsigned char* p, elfcpp::Elf_strtab& strtab)
668     : p_(p), strtab_(strtab)
669   { this->input_file_count_ = Swap32::readval(this->p_ + 4); }
670
671   // Return the version number.
672   unsigned int
673   version() const
674   { return Swap32::readval(this->p_); }
675
676   // Return the count of input file entries.
677   unsigned int
678   input_file_count() const
679   { return this->input_file_count_; }
680
681   // Return the command line.
682   const char*
683   command_line() const
684   {
685     unsigned int offset = Swap32::readval(this->p_ + 8);
686     return this->get_string(offset);
687   }
688
689   // Reader class for an input file entry and its supplemental info.
690   class Incremental_input_entry_reader
691   {
692    public:
693     Incremental_input_entry_reader(const Incremental_inputs_reader* inputs,
694                                    unsigned int offset)
695       : inputs_(inputs), offset_(offset)
696     {
697       this->info_offset_ = Swap32::readval(inputs->p_ + offset + 4);
698       int type = Swap16::readval(this->inputs_->p_ + offset + 20);
699       this->type_ = static_cast<Incremental_input_type>(type);
700     }
701
702     // Return the filename.
703     const char*
704     filename() const
705     {
706       unsigned int offset = Swap32::readval(this->inputs_->p_ + this->offset_);
707       return this->inputs_->get_string(offset);
708     }
709
710     // Return the timestamp.
711     Timespec
712     get_mtime() const
713     {
714       Timespec t;
715       const unsigned char* p = this->inputs_->p_ + this->offset_ + 8;
716       t.seconds = Swap64::readval(p);
717       t.nanoseconds = Swap32::readval(p+8);
718       return t;
719     }
720
721     // Return the type of input file.
722     Incremental_input_type
723     type() const
724     { return this->type_; }
725
726     // Return the input section count -- for objects only.
727     unsigned int
728     get_input_section_count() const
729     {
730       gold_assert(this->type_ == INCREMENTAL_INPUT_OBJECT
731                   || this->type_ == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
732       return Swap32::readval(this->inputs_->p_ + this->info_offset_);
733     }
734
735     // Return the offset of the supplemental info for symbol SYMNDX --
736     // for objects only.
737     unsigned int
738     get_symbol_offset(unsigned int symndx) const
739     {
740       gold_assert(this->type_ == INCREMENTAL_INPUT_OBJECT
741                   || this->type_ == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
742
743       unsigned int section_count = this->get_input_section_count();
744       return (this->info_offset_ + 8
745               + section_count * input_section_entry_size
746               + symndx * 16);
747     }
748
749     // Return the global symbol count -- for objects & shared libraries only.
750     unsigned int
751     get_global_symbol_count() const
752     {
753       switch (this->type_)
754         {
755         case INCREMENTAL_INPUT_OBJECT:
756         case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
757           return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 4);
758         case INCREMENTAL_INPUT_SHARED_LIBRARY:
759           return Swap32::readval(this->inputs_->p_ + this->info_offset_);
760         default:
761           gold_unreachable();
762         }
763     }
764
765     // Return the member count -- for archives only.
766     unsigned int
767     get_member_count() const
768     {
769       gold_assert(this->type_ == INCREMENTAL_INPUT_ARCHIVE);
770       return Swap32::readval(this->inputs_->p_ + this->info_offset_);
771     }
772
773     // Return the unused symbol count -- for archives only.
774     unsigned int
775     get_unused_symbol_count() const
776     {
777       gold_assert(this->type_ == INCREMENTAL_INPUT_ARCHIVE);
778       return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 4);
779     }
780
781     // Return the input file offset for archive member N -- for archives only.
782     unsigned int
783     get_member_offset(unsigned int n) const
784     {
785       gold_assert(this->type_ == INCREMENTAL_INPUT_ARCHIVE);
786       return Swap32::readval(this->inputs_->p_ + this->info_offset_
787                              + 8 + n * 4);
788     }
789
790     // Return the Nth unused global symbol -- for archives only.
791     const char*
792     get_unused_symbol(unsigned int n) const
793     {
794       gold_assert(this->type_ == INCREMENTAL_INPUT_ARCHIVE);
795       unsigned int member_count = this->get_member_count();
796       unsigned int offset = Swap32::readval(this->inputs_->p_
797                                             + this->info_offset_ + 8
798                                             + member_count * 4
799                                             + n * 4);
800       return this->inputs_->get_string(offset);
801     }
802
803     // Information about an input section.
804     struct Input_section_info
805     {
806       const char* name;
807       unsigned int output_shndx;
808       off_t sh_offset;
809       off_t sh_size;
810     };
811
812     // Return info about the Nth input section -- for objects only.
813     Input_section_info
814     get_input_section(unsigned int n) const
815     {
816       Input_section_info info;
817       const unsigned char* p = (this->inputs_->p_
818                                 + this->info_offset_ + 8
819                                 + n * input_section_entry_size);
820       unsigned int name_offset = Swap32::readval(p);
821       info.name = this->inputs_->get_string(name_offset);
822       info.output_shndx = Swap32::readval(p + 4);
823       info.sh_offset = Swap::readval(p + 8);
824       info.sh_size = Swap::readval(p + 8 + size / 8);
825       return info;
826     }
827
828     // Information about a global symbol.
829     struct Global_symbol_info
830     {
831       unsigned int output_symndx;
832       unsigned int next_offset;
833       unsigned int reloc_count;
834       unsigned int reloc_offset;
835     };
836
837     // Return info about the Nth global symbol -- for objects only.
838     Global_symbol_info
839     get_global_symbol_info(unsigned int n) const
840     {
841       Global_symbol_info info;
842       unsigned int section_count = this->get_input_section_count();
843       const unsigned char* p = (this->inputs_->p_
844                                 + this->info_offset_ + 8
845                                 + section_count * input_section_entry_size
846                                 + n * 16);
847       info.output_symndx = Swap32::readval(p);
848       info.next_offset = Swap32::readval(p + 4);
849       info.reloc_count = Swap::readval(p + 8);
850       info.reloc_offset = Swap::readval(p + 12);
851       return info;
852     }
853
854    private:
855     // Size of an input section entry.
856     static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
857     // The reader instance for the containing section.
858     const Incremental_inputs_reader* inputs_;
859     // The type of input file.
860     Incremental_input_type type_;
861     // Section offset to the input file entry.
862     unsigned int offset_;
863     // Section offset to the supplemental info for the input file.
864     unsigned int info_offset_;
865   };
866
867   // Return a reader for the Nth input file entry.
868   Incremental_input_entry_reader
869   input_file(unsigned int n) const
870   {
871     gold_assert(n < this->input_file_count_);
872     Incremental_input_entry_reader input(this, 16 + n * 24);
873     return input;
874   }
875
876  private:
877   // Lookup a string in the ELF string table.
878   const char* get_string(unsigned int offset) const
879   {
880     const char* s;
881     if (this->strtab_.get_c_string(offset, &s))
882       return s;
883     return NULL;
884   }
885
886   // Base address of the .gnu_incremental_inputs section.
887   const unsigned char* p_;
888   // The associated ELF string table.
889   elfcpp::Elf_strtab strtab_;
890   // The number of input file entries in this section.
891   unsigned int input_file_count_;
892 };
893
894 // Reader class for the .gnu_incremental_symtab section.
895
896 template<bool big_endian>
897 class Incremental_symtab_reader
898 {
899  public:
900   Incremental_symtab_reader(const unsigned char* p) : p_(p)
901   { }
902
903   // Return the list head for symbol table entry N.
904   unsigned int get_list_head(unsigned int n) const
905   { return elfcpp::Swap<32, big_endian>::readval(this->p_ + 4 * n); }
906
907  private:
908   // Base address of the .gnu_incremental_relocs section.
909   const unsigned char* p_;
910 };
911
912 // Reader class for the .gnu_incremental_relocs section.
913
914 template<int size, bool big_endian>
915 class Incremental_relocs_reader
916 {
917  private:
918   // Size of each field.
919   static const unsigned int field_size = size / 8;
920
921  public:
922   typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
923   typedef typename elfcpp::Elf_types<size>::Elf_Swxword Addend;
924
925   // Size of each entry.
926   static const unsigned int reloc_size = 8 + 2 * field_size;
927
928   Incremental_relocs_reader(const unsigned char* p) : p_(p)
929   { }
930
931   // Return the relocation type for relocation entry at offset OFF.
932   unsigned int
933   get_r_type(unsigned int off) const
934   {
935     return elfcpp::Swap<32, big_endian>::readval(this->p_ + off);
936   }
937
938   // Return the output section index for relocation entry at offset OFF.
939   unsigned int
940   get_r_shndx(unsigned int off) const
941   {
942     return elfcpp::Swap<32, big_endian>::readval(this->p_ + off + 4);
943   }
944
945   // Return the output section offset for relocation entry at offset OFF.
946   Address
947   get_r_offset(unsigned int off) const
948   {
949     return elfcpp::Swap<size, big_endian>::readval(this->p_ + off + 8);
950   }
951
952   // Return the addend for relocation entry at offset OFF.
953   Addend
954   get_r_addend(unsigned int off) const
955   {
956     return elfcpp::Swap<size, big_endian>::readval(this->p_ + off + 8
957                                                    + this->field_size);
958   }
959
960  private:
961   // Base address of the .gnu_incremental_relocs section.
962   const unsigned char* p_;
963 };
964
965 // Reader class for the .gnu_incremental_got_plt section.
966
967 template<bool big_endian>
968 class Incremental_got_plt_reader
969 {
970  public:
971   Incremental_got_plt_reader(const unsigned char* p) : p_(p)
972   {
973     this->got_count_ = elfcpp::Swap<32, big_endian>::readval(p);
974     this->got_desc_p_ = p + 8 + ((this->got_count_ + 3) & ~3);
975     this->plt_desc_p_ = this->got_desc_p_ + this->got_count_ * 4;
976   }
977
978   // Return the GOT entry count.
979   unsigned int
980   get_got_entry_count() const
981   {
982     return this->got_count_;
983   }
984
985   // Return the PLT entry count.
986   unsigned int
987   get_plt_entry_count() const
988   {
989     return elfcpp::Swap<32, big_endian>::readval(this->p_ + 4);
990   }
991
992   // Return the GOT type for GOT entry N.
993   unsigned int
994   get_got_type(unsigned int n)
995   {
996     return this->p_[8 + n];
997   }
998
999   // Return the GOT descriptor for GOT entry N.
1000   unsigned int
1001   get_got_desc(unsigned int n)
1002   {
1003     return elfcpp::Swap<32, big_endian>::readval(this->got_desc_p_ + n * 4);
1004   }
1005
1006   // Return the PLT descriptor for PLT entry N.
1007   unsigned int
1008   get_plt_desc(unsigned int n)
1009   {
1010     return elfcpp::Swap<32, big_endian>::readval(this->plt_desc_p_ + n * 4);
1011   }
1012
1013  private:
1014   // Base address of the .gnu_incremental_got_plt section.
1015   const unsigned char* p_;
1016   // GOT entry count.
1017   unsigned int got_count_;
1018   // Base address of the GOT descriptor array.
1019   const unsigned char* got_desc_p_;
1020   // Base address of the PLT descriptor array.
1021   const unsigned char* plt_desc_p_;
1022 };
1023
1024 } // End namespace gold.
1025
1026 #endif // !defined(GOLD_INCREMENTAL_H)