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