1ed0d50c3Schristos // archive.h -- archive support for gold -*- C++ -*- 2ed0d50c3Schristos 3*b88e3e88Schristos // Copyright (C) 2006-2020 Free Software Foundation, Inc. 4ed0d50c3Schristos // Written by Ian Lance Taylor <iant@google.com>. 5ed0d50c3Schristos 6ed0d50c3Schristos // This file is part of gold. 7ed0d50c3Schristos 8ed0d50c3Schristos // This program is free software; you can redistribute it and/or modify 9ed0d50c3Schristos // it under the terms of the GNU General Public License as published by 10ed0d50c3Schristos // the Free Software Foundation; either version 3 of the License, or 11ed0d50c3Schristos // (at your option) any later version. 12ed0d50c3Schristos 13ed0d50c3Schristos // This program is distributed in the hope that it will be useful, 14ed0d50c3Schristos // but WITHOUT ANY WARRANTY; without even the implied warranty of 15ed0d50c3Schristos // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16ed0d50c3Schristos // GNU General Public License for more details. 17ed0d50c3Schristos 18ed0d50c3Schristos // You should have received a copy of the GNU General Public License 19ed0d50c3Schristos // along with this program; if not, write to the Free Software 20ed0d50c3Schristos // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21ed0d50c3Schristos // MA 02110-1301, USA. 22ed0d50c3Schristos 23ed0d50c3Schristos #ifndef GOLD_ARCHIVE_H 24ed0d50c3Schristos #define GOLD_ARCHIVE_H 25ed0d50c3Schristos 26ed0d50c3Schristos #include <string> 27ed0d50c3Schristos #include <vector> 28ed0d50c3Schristos 29ed0d50c3Schristos #include "fileread.h" 30ed0d50c3Schristos #include "workqueue.h" 31ed0d50c3Schristos 32ed0d50c3Schristos namespace gold 33ed0d50c3Schristos { 34ed0d50c3Schristos 35ed0d50c3Schristos class Task; 36ed0d50c3Schristos class Input_argument; 37ed0d50c3Schristos class Input_file; 38ed0d50c3Schristos class Input_objects; 39ed0d50c3Schristos class Input_group; 40ed0d50c3Schristos class Layout; 41ed0d50c3Schristos class Symbol_table; 42ed0d50c3Schristos class Object; 43ed0d50c3Schristos struct Read_symbols_data; 44ed0d50c3Schristos class Input_file_lib; 45ed0d50c3Schristos class Incremental_archive_entry; 46ed0d50c3Schristos 47ed0d50c3Schristos // An entry in the archive map of offsets to members. 48ed0d50c3Schristos struct Archive_member 49ed0d50c3Schristos { Archive_memberArchive_member50ed0d50c3Schristos Archive_member() 51ed0d50c3Schristos : obj_(NULL), sd_(NULL), arg_serial_(0) 52ed0d50c3Schristos { } Archive_memberArchive_member53ed0d50c3Schristos Archive_member(Object* obj, Read_symbols_data* sd) 54ed0d50c3Schristos : obj_(obj), sd_(sd), arg_serial_(0) 55ed0d50c3Schristos { } 56ed0d50c3Schristos // The object file. 57ed0d50c3Schristos Object* obj_; 58ed0d50c3Schristos // The data to pass from read_symbols() to add_symbols(). 59ed0d50c3Schristos Read_symbols_data* sd_; 60ed0d50c3Schristos // The serial number of the file in the argument list. 61ed0d50c3Schristos unsigned int arg_serial_; 62ed0d50c3Schristos }; 63ed0d50c3Schristos 64ed0d50c3Schristos // This class serves as a base class for Archive and Lib_group objects. 65ed0d50c3Schristos 66ed0d50c3Schristos class Library_base 67ed0d50c3Schristos { 68ed0d50c3Schristos public: Library_base(Task * task)69ed0d50c3Schristos Library_base(Task* task) 70ed0d50c3Schristos : task_(task), incremental_info_(NULL) 71ed0d50c3Schristos { } 72ed0d50c3Schristos 73ed0d50c3Schristos virtual ~Library_base()74ed0d50c3Schristos ~Library_base() 75ed0d50c3Schristos { } 76ed0d50c3Schristos 77ed0d50c3Schristos // The file name. 78ed0d50c3Schristos const std::string& filename()79ed0d50c3Schristos filename() const 80ed0d50c3Schristos { return this->do_filename(); } 81ed0d50c3Schristos 82ed0d50c3Schristos // The modification time of the archive file. 83ed0d50c3Schristos Timespec get_mtime()84ed0d50c3Schristos get_mtime() 85ed0d50c3Schristos { return this->do_get_mtime(); } 86ed0d50c3Schristos 87ed0d50c3Schristos // When we see a symbol in an archive we might decide to include the member, 88ed0d50c3Schristos // not include the member or be undecided. This enum represents these 89ed0d50c3Schristos // possibilities. 90ed0d50c3Schristos 91ed0d50c3Schristos enum Should_include 92ed0d50c3Schristos { 93ed0d50c3Schristos SHOULD_INCLUDE_NO, 94ed0d50c3Schristos SHOULD_INCLUDE_YES, 95ed0d50c3Schristos SHOULD_INCLUDE_UNKNOWN 96ed0d50c3Schristos }; 97ed0d50c3Schristos 98ed0d50c3Schristos static Should_include 99ed0d50c3Schristos should_include_member(Symbol_table* symtab, Layout*, const char* sym_name, 100ed0d50c3Schristos Symbol** symp, std::string* why, char** tmpbufp, 101ed0d50c3Schristos size_t* tmpbuflen); 102ed0d50c3Schristos 103ed0d50c3Schristos // Store a pointer to the incremental link info for the library. 104ed0d50c3Schristos void set_incremental_info(Incremental_archive_entry * info)105ed0d50c3Schristos set_incremental_info(Incremental_archive_entry* info) 106ed0d50c3Schristos { this->incremental_info_ = info; } 107ed0d50c3Schristos 108ed0d50c3Schristos // Return the pointer to the incremental link info for the library. 109ed0d50c3Schristos Incremental_archive_entry* incremental_info()110ed0d50c3Schristos incremental_info() const 111ed0d50c3Schristos { return this->incremental_info_; } 112ed0d50c3Schristos 113ed0d50c3Schristos // Abstract base class for processing unused symbols. 114ed0d50c3Schristos class Symbol_visitor_base 115ed0d50c3Schristos { 116ed0d50c3Schristos public: Symbol_visitor_base()117ed0d50c3Schristos Symbol_visitor_base() 118ed0d50c3Schristos { } 119ed0d50c3Schristos 120ed0d50c3Schristos virtual ~Symbol_visitor_base()121ed0d50c3Schristos ~Symbol_visitor_base() 122ed0d50c3Schristos { } 123ed0d50c3Schristos 124ed0d50c3Schristos // This function will be called for each unused global 125ed0d50c3Schristos // symbol in a library, with a pointer to the symbol name. 126ed0d50c3Schristos virtual void 127ed0d50c3Schristos visit(const char* /* name */) = 0; 128ed0d50c3Schristos }; 129ed0d50c3Schristos 130ed0d50c3Schristos // Iterator for unused global symbols in the library. 131ed0d50c3Schristos // Calls v->visit() for each global symbol defined 132ed0d50c3Schristos // in each unused library member, passing a pointer to 133ed0d50c3Schristos // the symbol name. 134ed0d50c3Schristos void for_all_unused_symbols(Symbol_visitor_base * v)135ed0d50c3Schristos for_all_unused_symbols(Symbol_visitor_base* v) const 136ed0d50c3Schristos { this->do_for_all_unused_symbols(v); } 137ed0d50c3Schristos 138ed0d50c3Schristos protected: 139ed0d50c3Schristos // The task reading this archive. 140ed0d50c3Schristos Task *task_; 141ed0d50c3Schristos 142ed0d50c3Schristos private: 143ed0d50c3Schristos // The file name. 144ed0d50c3Schristos virtual const std::string& 145ed0d50c3Schristos do_filename() const = 0; 146ed0d50c3Schristos 147ed0d50c3Schristos // Return the modification time of the archive file. 148ed0d50c3Schristos virtual Timespec 149ed0d50c3Schristos do_get_mtime() = 0; 150ed0d50c3Schristos 151ed0d50c3Schristos // Iterator for unused global symbols in the library. 152ed0d50c3Schristos virtual void 153ed0d50c3Schristos do_for_all_unused_symbols(Symbol_visitor_base* v) const = 0; 154ed0d50c3Schristos 155ed0d50c3Schristos // The incremental link information for this archive. 156ed0d50c3Schristos Incremental_archive_entry* incremental_info_; 157ed0d50c3Schristos }; 158ed0d50c3Schristos 159ed0d50c3Schristos // This class represents an archive--generally a libNAME.a file. 160ed0d50c3Schristos // Archives have a symbol table and a list of objects. 161ed0d50c3Schristos 162ed0d50c3Schristos class Archive : public Library_base 163ed0d50c3Schristos { 164ed0d50c3Schristos public: 165ed0d50c3Schristos Archive(const std::string& name, Input_file* input_file, 166ed0d50c3Schristos bool is_thin_archive, Dirsearch* dirpath, Task* task); 167ed0d50c3Schristos 168ed0d50c3Schristos // The length of the magic string at the start of an archive. 169ed0d50c3Schristos static const int sarmag = 8; 170ed0d50c3Schristos 171ed0d50c3Schristos // The magic string at the start of an archive. 172ed0d50c3Schristos static const char armag[sarmag]; 173ed0d50c3Schristos static const char armagt[sarmag]; 174ed0d50c3Schristos 175ed0d50c3Schristos // The string expected at the end of an archive member header. 176ed0d50c3Schristos static const char arfmag[2]; 177ed0d50c3Schristos 178ed0d50c3Schristos // Name of 64-bit symbol table member. 179ed0d50c3Schristos static const char sym64name[7]; 180ed0d50c3Schristos 181ed0d50c3Schristos // The name of the object. This is the name used on the command 182ed0d50c3Schristos // line; e.g., if "-lgcc" is on the command line, this will be 183ed0d50c3Schristos // "gcc". 184ed0d50c3Schristos const std::string& name()185ed0d50c3Schristos name() const 186ed0d50c3Schristos { return this->name_; } 187ed0d50c3Schristos 188ed0d50c3Schristos // The input file. 189ed0d50c3Schristos const Input_file* input_file()190ed0d50c3Schristos input_file() const 191ed0d50c3Schristos { return this->input_file_; } 192ed0d50c3Schristos 193ed0d50c3Schristos // Set up the archive: read the symbol map. 194ed0d50c3Schristos void 195ed0d50c3Schristos setup(); 196ed0d50c3Schristos 197ed0d50c3Schristos // Get a reference to the underlying file. 198ed0d50c3Schristos File_read& file()199ed0d50c3Schristos file() 200ed0d50c3Schristos { return this->input_file_->file(); } 201ed0d50c3Schristos 202ed0d50c3Schristos const File_read& file()203ed0d50c3Schristos file() const 204ed0d50c3Schristos { return this->input_file_->file(); } 205ed0d50c3Schristos 206ed0d50c3Schristos // Lock the underlying file. 207ed0d50c3Schristos void lock(const Task * t)208ed0d50c3Schristos lock(const Task* t) 209ed0d50c3Schristos { this->input_file_->file().lock(t); } 210ed0d50c3Schristos 211ed0d50c3Schristos // Unlock the underlying file. 212ed0d50c3Schristos void unlock(const Task * t)213ed0d50c3Schristos unlock(const Task* t) 214ed0d50c3Schristos { this->input_file_->file().unlock(t); } 215ed0d50c3Schristos 216ed0d50c3Schristos // Return whether the underlying file is locked. 217ed0d50c3Schristos bool is_locked()218ed0d50c3Schristos is_locked() const 219ed0d50c3Schristos { return this->input_file_->file().is_locked(); } 220ed0d50c3Schristos 221ed0d50c3Schristos // Return the token, so that the task can be queued. 222ed0d50c3Schristos Task_token* token()223ed0d50c3Schristos token() 224ed0d50c3Schristos { return this->input_file_->file().token(); } 225ed0d50c3Schristos 226ed0d50c3Schristos // Release the underlying file. 227ed0d50c3Schristos void release()228ed0d50c3Schristos release() 229ed0d50c3Schristos { this->input_file_->file().release(); } 230ed0d50c3Schristos 231ed0d50c3Schristos // Clear uncached views in the underlying file. 232ed0d50c3Schristos void clear_uncached_views()233ed0d50c3Schristos clear_uncached_views() 234ed0d50c3Schristos { this->input_file_->file().clear_uncached_views(); } 235ed0d50c3Schristos 236ed0d50c3Schristos // Whether this is a thin archive. 237ed0d50c3Schristos bool is_thin_archive()238ed0d50c3Schristos is_thin_archive() const 239ed0d50c3Schristos { return this->is_thin_archive_; } 240ed0d50c3Schristos 241ed0d50c3Schristos // Unlock any nested archives. 242ed0d50c3Schristos void 243ed0d50c3Schristos unlock_nested_archives(); 244ed0d50c3Schristos 245ed0d50c3Schristos // Select members from the archive as needed and add them to the 246ed0d50c3Schristos // link. 247ed0d50c3Schristos bool 248ed0d50c3Schristos add_symbols(Symbol_table*, Layout*, Input_objects*, Mapfile*); 249ed0d50c3Schristos 250ed0d50c3Schristos // Return whether the archive defines the symbol. 251ed0d50c3Schristos bool 252ed0d50c3Schristos defines_symbol(Symbol*) const; 253ed0d50c3Schristos 254ed0d50c3Schristos // Dump statistical information to stderr. 255ed0d50c3Schristos static void 256ed0d50c3Schristos print_stats(); 257ed0d50c3Schristos 258ed0d50c3Schristos // Return the number of members in the archive. 259ed0d50c3Schristos size_t 260ed0d50c3Schristos count_members(); 261ed0d50c3Schristos 262ed0d50c3Schristos // Return the no-export flag. 263ed0d50c3Schristos bool no_export()264ed0d50c3Schristos no_export() 265ed0d50c3Schristos { return this->no_export_; } 266ed0d50c3Schristos 267ed0d50c3Schristos private: 268ed0d50c3Schristos Archive(const Archive&); 269ed0d50c3Schristos Archive& operator=(const Archive&); 270ed0d50c3Schristos 271ed0d50c3Schristos // The file name. 272ed0d50c3Schristos const std::string& do_filename()273ed0d50c3Schristos do_filename() const 274ed0d50c3Schristos { return this->input_file_->filename(); } 275ed0d50c3Schristos 276ed0d50c3Schristos // The modification time of the archive file. 277ed0d50c3Schristos Timespec do_get_mtime()278ed0d50c3Schristos do_get_mtime() 279ed0d50c3Schristos { return this->file().get_mtime(); } 280ed0d50c3Schristos 281ed0d50c3Schristos struct Archive_header; 282ed0d50c3Schristos 283ed0d50c3Schristos // Total number of archives seen. 284ed0d50c3Schristos static unsigned int total_archives; 285ed0d50c3Schristos // Total number of archive members seen. 286ed0d50c3Schristos static unsigned int total_members; 287ed0d50c3Schristos // Number of archive members loaded. 288ed0d50c3Schristos static unsigned int total_members_loaded; 289ed0d50c3Schristos 290ed0d50c3Schristos // Get a view into the underlying file. 291ed0d50c3Schristos const unsigned char* get_view(off_t start,section_size_type size,bool aligned,bool cache)292ed0d50c3Schristos get_view(off_t start, section_size_type size, bool aligned, bool cache) 293ed0d50c3Schristos { return this->input_file_->file().get_view(0, start, size, aligned, cache); } 294ed0d50c3Schristos 295ed0d50c3Schristos // Read the archive symbol map. 296ed0d50c3Schristos template<int mapsize> 297ed0d50c3Schristos void 298ed0d50c3Schristos read_armap(off_t start, section_size_type size); 299ed0d50c3Schristos 300ed0d50c3Schristos // Read an archive member header at OFF. CACHE is whether to cache 301ed0d50c3Schristos // the file view. Return the size of the member, and set *PNAME to 302ed0d50c3Schristos // the name. 303ed0d50c3Schristos off_t 304ed0d50c3Schristos read_header(off_t off, bool cache, std::string* pname, off_t* nested_off); 305ed0d50c3Schristos 306ed0d50c3Schristos // Interpret an archive header HDR at OFF. Return the size of the 307ed0d50c3Schristos // member, and set *PNAME to the name. 308ed0d50c3Schristos off_t 309ed0d50c3Schristos interpret_header(const Archive_header* hdr, off_t off, std::string* pname, 310ed0d50c3Schristos off_t* nested_off) const; 311ed0d50c3Schristos 312ed0d50c3Schristos // Get the file and offset for an archive member, which may be an 313ed0d50c3Schristos // external member of a thin archive. Set *INPUT_FILE to the 314ed0d50c3Schristos // file containing the actual member, *MEMOFF to the offset 315ed0d50c3Schristos // within that file (0 if not a nested archive), and *MEMBER_NAME 316ed0d50c3Schristos // to the name of the archive member. Return TRUE on success. 317ed0d50c3Schristos bool 318ed0d50c3Schristos get_file_and_offset(off_t off, Input_file** input_file, off_t* memoff, 319ed0d50c3Schristos off_t* memsize, std::string* member_name); 320ed0d50c3Schristos 321ed0d50c3Schristos // Return an ELF object for the member at offset OFF. 322ed0d50c3Schristos Object* 323ed0d50c3Schristos get_elf_object_for_member(off_t off, bool*); 324ed0d50c3Schristos 325ed0d50c3Schristos // Read the symbols from all the archive members in the link. 326ed0d50c3Schristos void 327ed0d50c3Schristos read_all_symbols(); 328ed0d50c3Schristos 329ed0d50c3Schristos // Read the symbols from an archive member in the link. OFF is the file 330ed0d50c3Schristos // offset of the member header. 331ed0d50c3Schristos void 332ed0d50c3Schristos read_symbols(off_t off); 333ed0d50c3Schristos 334ed0d50c3Schristos // Include all the archive members in the link. 335ed0d50c3Schristos bool 336ed0d50c3Schristos include_all_members(Symbol_table*, Layout*, Input_objects*, Mapfile*); 337ed0d50c3Schristos 338ed0d50c3Schristos // Include an archive member in the link. 339ed0d50c3Schristos bool 340ed0d50c3Schristos include_member(Symbol_table*, Layout*, Input_objects*, off_t off, 341ed0d50c3Schristos Mapfile*, Symbol*, const char* why); 342ed0d50c3Schristos 343ed0d50c3Schristos // Return whether we found this archive by searching a directory. 344ed0d50c3Schristos bool searched_for()345ed0d50c3Schristos searched_for() const 346ed0d50c3Schristos { return this->input_file_->will_search_for(); } 347ed0d50c3Schristos 348ed0d50c3Schristos // Iterate over archive members. 349ed0d50c3Schristos class const_iterator; 350ed0d50c3Schristos 351ed0d50c3Schristos const_iterator 352ed0d50c3Schristos begin(); 353ed0d50c3Schristos 354ed0d50c3Schristos const_iterator 355ed0d50c3Schristos end(); 356ed0d50c3Schristos 357ed0d50c3Schristos friend class const_iterator; 358ed0d50c3Schristos 359ed0d50c3Schristos // Iterator for unused global symbols in the library. 360ed0d50c3Schristos void 361ed0d50c3Schristos do_for_all_unused_symbols(Symbol_visitor_base* v) const; 362ed0d50c3Schristos 363ed0d50c3Schristos // An entry in the archive map of symbols to object files. 364ed0d50c3Schristos struct Armap_entry 365ed0d50c3Schristos { 366ed0d50c3Schristos // The offset to the symbol name in armap_names_. 367ed0d50c3Schristos off_t name_offset; 368ed0d50c3Schristos // The file offset to the object in the archive. 369ed0d50c3Schristos off_t file_offset; 370ed0d50c3Schristos }; 371ed0d50c3Schristos 372ed0d50c3Schristos // A simple hash code for off_t values. 373ed0d50c3Schristos class Seen_hash 374ed0d50c3Schristos { 375ed0d50c3Schristos public: operator()376ed0d50c3Schristos size_t operator()(off_t val) const 377ed0d50c3Schristos { return static_cast<size_t>(val); } 378ed0d50c3Schristos }; 379ed0d50c3Schristos 380ed0d50c3Schristos // For keeping track of open nested archives in a thin archive file. 381ed0d50c3Schristos typedef Unordered_map<std::string, Archive*> Nested_archive_table; 382ed0d50c3Schristos 383ed0d50c3Schristos // Name of object as printed to user. 384ed0d50c3Schristos std::string name_; 385ed0d50c3Schristos // For reading the file. 386ed0d50c3Schristos Input_file* input_file_; 387ed0d50c3Schristos // The archive map. 388ed0d50c3Schristos std::vector<Armap_entry> armap_; 389ed0d50c3Schristos // The names in the archive map. 390ed0d50c3Schristos std::string armap_names_; 391ed0d50c3Schristos // The extended name table. 392ed0d50c3Schristos std::string extended_names_; 393ed0d50c3Schristos // Track which symbols in the archive map are for elements which are 394ed0d50c3Schristos // defined or which have already been included in the link. 395ed0d50c3Schristos std::vector<bool> armap_checked_; 396ed0d50c3Schristos // Track which elements have been included by offset. 397ed0d50c3Schristos Unordered_set<off_t, Seen_hash> seen_offsets_; 398ed0d50c3Schristos // Table of objects whose symbols have been pre-read. 399ed0d50c3Schristos std::map<off_t, Archive_member> members_; 400ed0d50c3Schristos // True if this is a thin archive. 401ed0d50c3Schristos const bool is_thin_archive_; 402ed0d50c3Schristos // True if we have included at least one object from this archive. 403ed0d50c3Schristos bool included_member_; 404ed0d50c3Schristos // Table of nested archives, indexed by filename. 405ed0d50c3Schristos Nested_archive_table nested_archives_; 406ed0d50c3Schristos // The directory search path. 407ed0d50c3Schristos Dirsearch* dirpath_; 408ed0d50c3Schristos // Number of members in this archive; 409ed0d50c3Schristos unsigned int num_members_; 410ed0d50c3Schristos // True if we exclude this library archive from automatic export. 411ed0d50c3Schristos bool no_export_; 412ed0d50c3Schristos // True if this library has been included as a --whole-archive. 413ed0d50c3Schristos bool included_all_members_; 414ed0d50c3Schristos }; 415ed0d50c3Schristos 416ed0d50c3Schristos // This class is used to read an archive and pick out the desired 417ed0d50c3Schristos // elements and add them to the link. 418ed0d50c3Schristos 419ed0d50c3Schristos class Add_archive_symbols : public Task 420ed0d50c3Schristos { 421ed0d50c3Schristos public: Add_archive_symbols(Symbol_table * symtab,Layout * layout,Input_objects * input_objects,Dirsearch * dirpath,int dirindex,Mapfile * mapfile,const Input_argument * input_argument,Archive * archive,Input_group * input_group,Task_token * this_blocker,Task_token * next_blocker)422ed0d50c3Schristos Add_archive_symbols(Symbol_table* symtab, Layout* layout, 423ed0d50c3Schristos Input_objects* input_objects, Dirsearch* dirpath, 424ed0d50c3Schristos int dirindex, Mapfile* mapfile, 425ed0d50c3Schristos const Input_argument* input_argument, 426ed0d50c3Schristos Archive* archive, Input_group* input_group, 427ed0d50c3Schristos Task_token* this_blocker, 428ed0d50c3Schristos Task_token* next_blocker) 429ed0d50c3Schristos : symtab_(symtab), layout_(layout), input_objects_(input_objects), 430ed0d50c3Schristos dirpath_(dirpath), dirindex_(dirindex), mapfile_(mapfile), 431ed0d50c3Schristos input_argument_(input_argument), archive_(archive), 432ed0d50c3Schristos input_group_(input_group), this_blocker_(this_blocker), 433ed0d50c3Schristos next_blocker_(next_blocker) 434ed0d50c3Schristos { } 435ed0d50c3Schristos 436ed0d50c3Schristos ~Add_archive_symbols(); 437ed0d50c3Schristos 438ed0d50c3Schristos // The standard Task methods. 439ed0d50c3Schristos 440ed0d50c3Schristos Task_token* 441ed0d50c3Schristos is_runnable(); 442ed0d50c3Schristos 443ed0d50c3Schristos void 444ed0d50c3Schristos locks(Task_locker*); 445ed0d50c3Schristos 446ed0d50c3Schristos void 447ed0d50c3Schristos run(Workqueue*); 448ed0d50c3Schristos 449ed0d50c3Schristos std::string get_name()450ed0d50c3Schristos get_name() const 451ed0d50c3Schristos { 452ed0d50c3Schristos if (this->archive_ == NULL) 453ed0d50c3Schristos return "Add_archive_symbols"; 454ed0d50c3Schristos return "Add_archive_symbols " + this->archive_->file().filename(); 455ed0d50c3Schristos } 456ed0d50c3Schristos 457ed0d50c3Schristos private: 458ed0d50c3Schristos Symbol_table* symtab_; 459ed0d50c3Schristos Layout* layout_; 460ed0d50c3Schristos Input_objects* input_objects_; 461ed0d50c3Schristos Dirsearch* dirpath_; 462ed0d50c3Schristos int dirindex_; 463ed0d50c3Schristos Mapfile* mapfile_; 464ed0d50c3Schristos const Input_argument* input_argument_; 465ed0d50c3Schristos Archive* archive_; 466ed0d50c3Schristos Input_group* input_group_; 467ed0d50c3Schristos Task_token* this_blocker_; 468ed0d50c3Schristos Task_token* next_blocker_; 469ed0d50c3Schristos }; 470ed0d50c3Schristos 471ed0d50c3Schristos // This class represents the files surrounded by a --start-lib ... --end-lib. 472ed0d50c3Schristos 473ed0d50c3Schristos class Lib_group : public Library_base 474ed0d50c3Schristos { 475ed0d50c3Schristos public: 476ed0d50c3Schristos Lib_group(const Input_file_lib* lib, Task* task); 477ed0d50c3Schristos 478ed0d50c3Schristos // Select members from the lib group as needed and add them to the link. 479ed0d50c3Schristos void 480ed0d50c3Schristos add_symbols(Symbol_table*, Layout*, Input_objects*); 481ed0d50c3Schristos 482ed0d50c3Schristos // Include a member of the lib group in the link. 483ed0d50c3Schristos void 484ed0d50c3Schristos include_member(Symbol_table*, Layout*, Input_objects*, const Archive_member&); 485ed0d50c3Schristos 486ed0d50c3Schristos Archive_member* get_member(int i)487ed0d50c3Schristos get_member(int i) 488ed0d50c3Schristos { 489ed0d50c3Schristos return &this->members_[i]; 490ed0d50c3Schristos } 491ed0d50c3Schristos 492ed0d50c3Schristos // Total number of archives seen. 493ed0d50c3Schristos static unsigned int total_lib_groups; 494ed0d50c3Schristos // Total number of archive members seen. 495ed0d50c3Schristos static unsigned int total_members; 496ed0d50c3Schristos // Number of archive members loaded. 497ed0d50c3Schristos static unsigned int total_members_loaded; 498ed0d50c3Schristos 499ed0d50c3Schristos // Dump statistical information to stderr. 500ed0d50c3Schristos static void 501ed0d50c3Schristos print_stats(); 502ed0d50c3Schristos 503ed0d50c3Schristos private: 504ed0d50c3Schristos // The file name. 505ed0d50c3Schristos const std::string& 506ed0d50c3Schristos do_filename() const; 507ed0d50c3Schristos 508ed0d50c3Schristos // A Lib_group does not have a modification time, since there is no 509ed0d50c3Schristos // real library file. 510ed0d50c3Schristos Timespec do_get_mtime()511ed0d50c3Schristos do_get_mtime() 512ed0d50c3Schristos { return Timespec(0, 0); } 513ed0d50c3Schristos 514ed0d50c3Schristos // Iterator for unused global symbols in the library. 515ed0d50c3Schristos void 516ed0d50c3Schristos do_for_all_unused_symbols(Symbol_visitor_base*) const; 517ed0d50c3Schristos 518ed0d50c3Schristos // Table of the objects in the group. 519ed0d50c3Schristos std::vector<Archive_member> members_; 520ed0d50c3Schristos }; 521ed0d50c3Schristos 522ed0d50c3Schristos // This class is used to pick out the desired elements and add them to the link. 523ed0d50c3Schristos 524ed0d50c3Schristos class Add_lib_group_symbols : public Task 525ed0d50c3Schristos { 526ed0d50c3Schristos public: Add_lib_group_symbols(Symbol_table * symtab,Layout * layout,Input_objects * input_objects,Lib_group * lib,Task_token * next_blocker)527ed0d50c3Schristos Add_lib_group_symbols(Symbol_table* symtab, Layout* layout, 528ed0d50c3Schristos Input_objects* input_objects, 529ed0d50c3Schristos Lib_group* lib, Task_token* next_blocker) 530ed0d50c3Schristos : symtab_(symtab), layout_(layout), input_objects_(input_objects), 531ed0d50c3Schristos lib_(lib), readsyms_blocker_(NULL), this_blocker_(NULL), 532ed0d50c3Schristos next_blocker_(next_blocker) 533ed0d50c3Schristos { } 534ed0d50c3Schristos 535ed0d50c3Schristos ~Add_lib_group_symbols(); 536ed0d50c3Schristos 537ed0d50c3Schristos // The standard Task methods. 538ed0d50c3Schristos 539ed0d50c3Schristos Task_token* 540ed0d50c3Schristos is_runnable(); 541ed0d50c3Schristos 542ed0d50c3Schristos void 543ed0d50c3Schristos locks(Task_locker*); 544ed0d50c3Schristos 545ed0d50c3Schristos void 546ed0d50c3Schristos run(Workqueue*); 547ed0d50c3Schristos 548ed0d50c3Schristos // Set the blocker to use for this task. 549ed0d50c3Schristos void set_blocker(Task_token * readsyms_blocker,Task_token * this_blocker)550ed0d50c3Schristos set_blocker(Task_token* readsyms_blocker, Task_token* this_blocker) 551ed0d50c3Schristos { 552ed0d50c3Schristos gold_assert(this->readsyms_blocker_ == NULL && this->this_blocker_ == NULL); 553ed0d50c3Schristos this->readsyms_blocker_ = readsyms_blocker; 554ed0d50c3Schristos this->this_blocker_ = this_blocker; 555ed0d50c3Schristos } 556ed0d50c3Schristos 557ed0d50c3Schristos std::string get_name()558ed0d50c3Schristos get_name() const 559ed0d50c3Schristos { 560ed0d50c3Schristos return "Add_lib_group_symbols"; 561ed0d50c3Schristos } 562ed0d50c3Schristos 563ed0d50c3Schristos private: 564ed0d50c3Schristos Symbol_table* symtab_; 565ed0d50c3Schristos Layout* layout_; 566ed0d50c3Schristos Input_objects* input_objects_; 567ed0d50c3Schristos Lib_group* lib_; 568ed0d50c3Schristos Task_token* readsyms_blocker_; 569ed0d50c3Schristos Task_token* this_blocker_; 570ed0d50c3Schristos Task_token* next_blocker_; 571ed0d50c3Schristos }; 572ed0d50c3Schristos 573ed0d50c3Schristos } // End namespace gold. 574ed0d50c3Schristos 575ed0d50c3Schristos #endif // !defined(GOLD_ARCHIVE_H) 576