Home | History | Annotate | Download | only in gold
      1 // archive.h -- archive support for gold      -*- C++ -*-
      2 
      3 // Copyright (C) 2006-2016 Free Software Foundation, Inc.
      4 // Written by Ian Lance Taylor <iant (at) 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)
    576