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