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