Home | History | Annotate | Download | only in gold
      1 // archive.h -- archive support for gold      -*- C++ -*-
      2 
      3 // Copyright (C) 2006-2014 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   // The name of the object.  This is the name used on the command
    179   // line; e.g., if "-lgcc" is on the command line, this will be
    180   // "gcc".
    181   const std::string&
    182   name() const
    183   { return this->name_; }
    184 
    185   // The input file.
    186   const Input_file*
    187   input_file() const
    188   { return this->input_file_; }
    189 
    190   // Set up the archive: read the symbol map.
    191   void
    192   setup();
    193 
    194   // Get a reference to the underlying file.
    195   File_read&
    196   file()
    197   { return this->input_file_->file(); }
    198 
    199   const File_read&
    200   file() const
    201   { return this->input_file_->file(); }
    202 
    203   // Lock the underlying file.
    204   void
    205   lock(const Task* t)
    206   { this->input_file_->file().lock(t); }
    207 
    208   // Unlock the underlying file.
    209   void
    210   unlock(const Task* t)
    211   { this->input_file_->file().unlock(t); }
    212 
    213   // Return whether the underlying file is locked.
    214   bool
    215   is_locked() const
    216   { return this->input_file_->file().is_locked(); }
    217 
    218   // Return the token, so that the task can be queued.
    219   Task_token*
    220   token()
    221   { return this->input_file_->file().token(); }
    222 
    223   // Release the underlying file.
    224   void
    225   release()
    226   { this->input_file_->file().release(); }
    227 
    228   // Clear uncached views in the underlying file.
    229   void
    230   clear_uncached_views()
    231   { this->input_file_->file().clear_uncached_views(); }
    232 
    233   // Whether this is a thin archive.
    234   bool
    235   is_thin_archive() const
    236   { return this->is_thin_archive_; }
    237 
    238   // Unlock any nested archives.
    239   void
    240   unlock_nested_archives();
    241 
    242   // Select members from the archive as needed and add them to the
    243   // link.
    244   bool
    245   add_symbols(Symbol_table*, Layout*, Input_objects*, Mapfile*);
    246 
    247   // Return whether the archive defines the symbol.
    248   bool
    249   defines_symbol(Symbol*) const;
    250 
    251   // Dump statistical information to stderr.
    252   static void
    253   print_stats();
    254 
    255   // Return the number of members in the archive.
    256   size_t
    257   count_members();
    258 
    259   // Return the no-export flag.
    260   bool
    261   no_export()
    262   { return this->no_export_; }
    263 
    264  private:
    265   Archive(const Archive&);
    266   Archive& operator=(const Archive&);
    267 
    268   // The file name.
    269   const std::string&
    270   do_filename() const
    271   { return this->input_file_->filename(); }
    272 
    273   // The modification time of the archive file.
    274   Timespec
    275   do_get_mtime()
    276   { return this->file().get_mtime(); }
    277 
    278   struct Archive_header;
    279 
    280   // Total number of archives seen.
    281   static unsigned int total_archives;
    282   // Total number of archive members seen.
    283   static unsigned int total_members;
    284   // Number of archive members loaded.
    285   static unsigned int total_members_loaded;
    286 
    287   // Get a view into the underlying file.
    288   const unsigned char*
    289   get_view(off_t start, section_size_type size, bool aligned, bool cache)
    290   { return this->input_file_->file().get_view(0, start, size, aligned, cache); }
    291 
    292   // Read the archive symbol map.
    293   void
    294   read_armap(off_t start, section_size_type size);
    295 
    296   // Read an archive member header at OFF.  CACHE is whether to cache
    297   // the file view.  Return the size of the member, and set *PNAME to
    298   // the name.
    299   off_t
    300   read_header(off_t off, bool cache, std::string* pname, off_t* nested_off);
    301 
    302   // Interpret an archive header HDR at OFF.  Return the size of the
    303   // member, and set *PNAME to the name.
    304   off_t
    305   interpret_header(const Archive_header* hdr, off_t off, std::string* pname,
    306                    off_t* nested_off) const;
    307 
    308   // Get the file and offset for an archive member, which may be an
    309   // external member of a thin archive.  Set *INPUT_FILE to the
    310   // file containing the actual member, *MEMOFF to the offset
    311   // within that file (0 if not a nested archive), and *MEMBER_NAME
    312   // to the name of the archive member.  Return TRUE on success.
    313   bool
    314   get_file_and_offset(off_t off, Input_file** input_file, off_t* memoff,
    315                       off_t* memsize, std::string* member_name);
    316 
    317   // Return an ELF object for the member at offset OFF.
    318   Object*
    319   get_elf_object_for_member(off_t off, bool*);
    320 
    321   // Read the symbols from all the archive members in the link.
    322   void
    323   read_all_symbols();
    324 
    325   // Read the symbols from an archive member in the link.  OFF is the file
    326   // offset of the member header.
    327   void
    328   read_symbols(off_t off);
    329 
    330   // Include all the archive members in the link.
    331   bool
    332   include_all_members(Symbol_table*, Layout*, Input_objects*, Mapfile*);
    333 
    334   // Include an archive member in the link.
    335   bool
    336   include_member(Symbol_table*, Layout*, Input_objects*, off_t off,
    337 		 Mapfile*, Symbol*, const char* why);
    338 
    339   // Return whether we found this archive by searching a directory.
    340   bool
    341   searched_for() const
    342   { return this->input_file_->will_search_for(); }
    343 
    344   // Iterate over archive members.
    345   class const_iterator;
    346 
    347   const_iterator
    348   begin();
    349 
    350   const_iterator
    351   end();
    352 
    353   friend class const_iterator;
    354 
    355   // Iterator for unused global symbols in the library.
    356   void
    357   do_for_all_unused_symbols(Symbol_visitor_base* v) const;
    358 
    359   // An entry in the archive map of symbols to object files.
    360   struct Armap_entry
    361   {
    362     // The offset to the symbol name in armap_names_.
    363     off_t name_offset;
    364     // The file offset to the object in the archive.
    365     off_t file_offset;
    366   };
    367 
    368   // A simple hash code for off_t values.
    369   class Seen_hash
    370   {
    371    public:
    372     size_t operator()(off_t val) const
    373     { return static_cast<size_t>(val); }
    374   };
    375 
    376   // For keeping track of open nested archives in a thin archive file.
    377   typedef Unordered_map<std::string, Archive*> Nested_archive_table;
    378 
    379   // Name of object as printed to user.
    380   std::string name_;
    381   // For reading the file.
    382   Input_file* input_file_;
    383   // The archive map.
    384   std::vector<Armap_entry> armap_;
    385   // The names in the archive map.
    386   std::string armap_names_;
    387   // The extended name table.
    388   std::string extended_names_;
    389   // Track which symbols in the archive map are for elements which are
    390   // defined or which have already been included in the link.
    391   std::vector<bool> armap_checked_;
    392   // Track which elements have been included by offset.
    393   Unordered_set<off_t, Seen_hash> seen_offsets_;
    394   // Table of objects whose symbols have been pre-read.
    395   std::map<off_t, Archive_member> members_;
    396   // True if this is a thin archive.
    397   const bool is_thin_archive_;
    398   // True if we have included at least one object from this archive.
    399   bool included_member_;
    400   // Table of nested archives, indexed by filename.
    401   Nested_archive_table nested_archives_;
    402   // The directory search path.
    403   Dirsearch* dirpath_;
    404   // Number of members in this archive;
    405   unsigned int num_members_;
    406   // True if we exclude this library archive from automatic export.
    407   bool no_export_;
    408   // True if this library has been included as a --whole-archive.
    409   bool included_all_members_;
    410 };
    411 
    412 // This class is used to read an archive and pick out the desired
    413 // elements and add them to the link.
    414 
    415 class Add_archive_symbols : public Task
    416 {
    417  public:
    418   Add_archive_symbols(Symbol_table* symtab, Layout* layout,
    419 		      Input_objects* input_objects, Dirsearch* dirpath,
    420 		      int dirindex, Mapfile* mapfile,
    421 		      const Input_argument* input_argument,
    422 		      Archive* archive, Input_group* input_group,
    423 		      Task_token* this_blocker,
    424 		      Task_token* next_blocker)
    425     : symtab_(symtab), layout_(layout), input_objects_(input_objects),
    426       dirpath_(dirpath), dirindex_(dirindex), mapfile_(mapfile),
    427       input_argument_(input_argument), archive_(archive),
    428       input_group_(input_group), this_blocker_(this_blocker),
    429       next_blocker_(next_blocker)
    430   { }
    431 
    432   ~Add_archive_symbols();
    433 
    434   // The standard Task methods.
    435 
    436   Task_token*
    437   is_runnable();
    438 
    439   void
    440   locks(Task_locker*);
    441 
    442   void
    443   run(Workqueue*);
    444 
    445   std::string
    446   get_name() const
    447   {
    448     if (this->archive_ == NULL)
    449       return "Add_archive_symbols";
    450     return "Add_archive_symbols " + this->archive_->file().filename();
    451   }
    452 
    453  private:
    454   Symbol_table* symtab_;
    455   Layout* layout_;
    456   Input_objects* input_objects_;
    457   Dirsearch* dirpath_;
    458   int dirindex_;
    459   Mapfile* mapfile_;
    460   const Input_argument* input_argument_;
    461   Archive* archive_;
    462   Input_group* input_group_;
    463   Task_token* this_blocker_;
    464   Task_token* next_blocker_;
    465 };
    466 
    467 // This class represents the files surrounded by a --start-lib ... --end-lib.
    468 
    469 class Lib_group : public Library_base
    470 {
    471  public:
    472   Lib_group(const Input_file_lib* lib, Task* task);
    473 
    474   // Select members from the lib group as needed and add them to the link.
    475   void
    476   add_symbols(Symbol_table*, Layout*, Input_objects*);
    477 
    478   // Include a member of the lib group in the link.
    479   void
    480   include_member(Symbol_table*, Layout*, Input_objects*, const Archive_member&);
    481 
    482   Archive_member*
    483   get_member(int i)
    484   {
    485     return &this->members_[i];
    486   }
    487 
    488   // Total number of archives seen.
    489   static unsigned int total_lib_groups;
    490   // Total number of archive members seen.
    491   static unsigned int total_members;
    492   // Number of archive members loaded.
    493   static unsigned int total_members_loaded;
    494 
    495   // Dump statistical information to stderr.
    496   static void
    497   print_stats();
    498 
    499  private:
    500   // The file name.
    501   const std::string&
    502   do_filename() const;
    503 
    504   // A Lib_group does not have a modification time, since there is no
    505   // real library file.
    506   Timespec
    507   do_get_mtime()
    508   { return Timespec(0, 0); }
    509 
    510   // Iterator for unused global symbols in the library.
    511   void
    512   do_for_all_unused_symbols(Symbol_visitor_base*) const;
    513 
    514   // Table of the objects in the group.
    515   std::vector<Archive_member> members_;
    516 };
    517 
    518 // This class is used to pick out the desired elements and add them to the link.
    519 
    520 class Add_lib_group_symbols : public Task
    521 {
    522  public:
    523   Add_lib_group_symbols(Symbol_table* symtab, Layout* layout,
    524                         Input_objects* input_objects,
    525                         Lib_group* lib, Task_token* next_blocker)
    526       : symtab_(symtab), layout_(layout), input_objects_(input_objects),
    527         lib_(lib), readsyms_blocker_(NULL), this_blocker_(NULL),
    528         next_blocker_(next_blocker)
    529   { }
    530 
    531   ~Add_lib_group_symbols();
    532 
    533   // The standard Task methods.
    534 
    535   Task_token*
    536   is_runnable();
    537 
    538   void
    539   locks(Task_locker*);
    540 
    541   void
    542   run(Workqueue*);
    543 
    544   // Set the blocker to use for this task.
    545   void
    546   set_blocker(Task_token* readsyms_blocker, Task_token* this_blocker)
    547   {
    548     gold_assert(this->readsyms_blocker_ == NULL && this->this_blocker_ == NULL);
    549     this->readsyms_blocker_ = readsyms_blocker;
    550     this->this_blocker_ = this_blocker;
    551   }
    552 
    553   std::string
    554   get_name() const
    555   {
    556     return "Add_lib_group_symbols";
    557   }
    558 
    559  private:
    560   Symbol_table* symtab_;
    561   Layout* layout_;
    562   Input_objects* input_objects_;
    563   Lib_group* lib_;
    564   Task_token* readsyms_blocker_;
    565   Task_token* this_blocker_;
    566   Task_token* next_blocker_;
    567 };
    568 
    569 } // End namespace gold.
    570 
    571 #endif // !defined(GOLD_ARCHIVE_H)
    572