2008-08-06 Cary Coutant <ccoutant@google.com>
[external/binutils.git] / gold / archive.cc
1 // archive.cc -- archive support for gold
2
3 // Copyright 2006, 2007, 2008 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 #include "gold.h"
24
25 #include <cerrno>
26 #include <cstring>
27 #include <climits>
28 #include <vector>
29 #include "libiberty.h"
30 #include "filenames.h"
31
32 #include "elfcpp.h"
33 #include "options.h"
34 #include "mapfile.h"
35 #include "fileread.h"
36 #include "readsyms.h"
37 #include "symtab.h"
38 #include "object.h"
39 #include "archive.h"
40
41 namespace gold
42 {
43
44 // The header of an entry in the archive.  This is all readable text,
45 // padded with spaces where necesary.  If the contents of an archive
46 // are all text file, the entire archive is readable.
47
48 struct Archive::Archive_header
49 {
50   // The entry name.
51   char ar_name[16];
52   // The file modification time.
53   char ar_date[12];
54   // The user's UID in decimal.
55   char ar_uid[6];
56   // The user's GID in decimal.
57   char ar_gid[6];
58   // The file mode in octal.
59   char ar_mode[8];
60   // The file size in decimal.
61   char ar_size[10];
62   // The final magic code.
63   char ar_fmag[2];
64 };
65
66 // Class Archive static variables.
67 unsigned int Archive::total_archives;
68 unsigned int Archive::total_members;
69 unsigned int Archive::total_members_loaded;
70
71 // Archive methods.
72
73 const char Archive::armag[sarmag] =
74 {
75   '!', '<', 'a', 'r', 'c', 'h', '>', '\n'
76 };
77
78 const char Archive::armagt[sarmag] =
79 {
80   '!', '<', 't', 'h', 'i', 'n', '>', '\n'
81 };
82
83 const char Archive::arfmag[2] = { '`', '\n' };
84
85 // Set up the archive: read the symbol map and the extended name
86 // table.
87
88 void
89 Archive::setup(Input_objects* input_objects)
90 {
91   // We need to ignore empty archives.
92   if (this->input_file_->file().filesize() == sarmag)
93     return;
94
95   // The first member of the archive should be the symbol table.
96   std::string armap_name;
97   section_size_type armap_size =
98     convert_to_section_size_type(this->read_header(sarmag, false,
99                                                    &armap_name, NULL));
100   off_t off = sarmag;
101   if (armap_name.empty())
102     {
103       this->read_armap(sarmag + sizeof(Archive_header), armap_size);
104       off = sarmag + sizeof(Archive_header) + armap_size;
105     }
106   else if (!this->input_file_->options().whole_archive())
107     gold_error(_("%s: no archive symbol table (run ranlib)"),
108                this->name().c_str());
109
110   // See if there is an extended name table.  We cache these views
111   // because it is likely that we will want to read the following
112   // header in the add_symbols routine.
113   if ((off & 1) != 0)
114     ++off;
115   std::string xname;
116   section_size_type extended_size =
117     convert_to_section_size_type(this->read_header(off, true, &xname, NULL));
118   if (xname == "/")
119     {
120       const unsigned char* p = this->get_view(off + sizeof(Archive_header),
121                                               extended_size, false, true);
122       const char* px = reinterpret_cast<const char*>(p);
123       this->extended_names_.assign(px, extended_size);
124     }
125   bool preread_syms = (parameters->options().threads()
126                        && parameters->options().preread_archive_symbols());
127 #ifndef ENABLE_THREADS
128   preread_syms = false;
129 #endif
130   if (preread_syms)
131     this->read_all_symbols(input_objects);
132 }
133
134 // Unlock any nested archives.
135
136 void
137 Archive::unlock_nested_archives()
138 {
139   for (Nested_archive_table::iterator p = this->nested_archives_.begin();
140        p != this->nested_archives_.end();
141        ++p)
142     {
143       p->second->unlock(this->task_);
144     }
145 }
146
147 // Read the archive symbol map.
148
149 void
150 Archive::read_armap(off_t start, section_size_type size)
151 {
152   // To count the total number of archive members, we'll just count
153   // the number of times the file offset changes.  Since most archives
154   // group the symbols in the armap by object, this ought to give us
155   // an accurate count.
156   off_t last_seen_offset = -1;
157
158   // Read in the entire armap.
159   const unsigned char* p = this->get_view(start, size, true, false);
160
161   // Numbers in the armap are always big-endian.
162   const elfcpp::Elf_Word* pword = reinterpret_cast<const elfcpp::Elf_Word*>(p);
163   unsigned int nsyms = elfcpp::Swap<32, true>::readval(pword);
164   ++pword;
165
166   // Note that the addition is in units of sizeof(elfcpp::Elf_Word).
167   const char* pnames = reinterpret_cast<const char*>(pword + nsyms);
168   section_size_type names_size =
169     reinterpret_cast<const char*>(p) + size - pnames;
170   this->armap_names_.assign(pnames, names_size);
171
172   this->armap_.resize(nsyms);
173
174   section_offset_type name_offset = 0;
175   for (unsigned int i = 0; i < nsyms; ++i)
176     {
177       this->armap_[i].name_offset = name_offset;
178       this->armap_[i].file_offset = elfcpp::Swap<32, true>::readval(pword);
179       name_offset += strlen(pnames + name_offset) + 1;
180       ++pword;
181       if (this->armap_[i].file_offset != last_seen_offset)
182         {
183           last_seen_offset = this->armap_[i].file_offset;
184           ++this->num_members_;
185         }
186     }
187
188   if (static_cast<section_size_type>(name_offset) > names_size)
189     gold_error(_("%s: bad archive symbol table names"),
190                this->name().c_str());
191
192   // This array keeps track of which symbols are for archive elements
193   // which we have already included in the link.
194   this->armap_checked_.resize(nsyms);
195 }
196
197 // Read the header of an archive member at OFF.  Fail if something
198 // goes wrong.  Return the size of the member.  Set *PNAME to the name
199 // of the member.
200
201 off_t
202 Archive::read_header(off_t off, bool cache, std::string* pname,
203                      off_t* nested_off)
204 {
205   const unsigned char* p = this->get_view(off, sizeof(Archive_header), true,
206                                           cache);
207   const Archive_header* hdr = reinterpret_cast<const Archive_header*>(p);
208   return this->interpret_header(hdr, off,  pname, nested_off);
209 }
210
211 // Interpret the header of HDR, the header of the archive member at
212 // file offset OFF.  Fail if something goes wrong.  Return the size of
213 // the member.  Set *PNAME to the name of the member.
214
215 off_t
216 Archive::interpret_header(const Archive_header* hdr, off_t off,
217                           std::string* pname, off_t* nested_off) const
218 {
219   if (memcmp(hdr->ar_fmag, arfmag, sizeof arfmag) != 0)
220     {
221       gold_error(_("%s: malformed archive header at %zu"),
222                  this->name().c_str(), static_cast<size_t>(off));
223       return this->input_file_->file().filesize() - off;
224     }
225
226   const int size_string_size = sizeof hdr->ar_size;
227   char size_string[size_string_size + 1];
228   memcpy(size_string, hdr->ar_size, size_string_size);
229   char* ps = size_string + size_string_size;
230   while (ps[-1] == ' ')
231     --ps;
232   *ps = '\0';
233
234   errno = 0;
235   char* end;
236   off_t member_size = strtol(size_string, &end, 10);
237   if (*end != '\0'
238       || member_size < 0
239       || (member_size == LONG_MAX && errno == ERANGE))
240     {
241       gold_error(_("%s: malformed archive header size at %zu"),
242                  this->name().c_str(), static_cast<size_t>(off));
243       return this->input_file_->file().filesize() - off;
244     }
245
246   if (hdr->ar_name[0] != '/')
247     {
248       const char* name_end = strchr(hdr->ar_name, '/');
249       if (name_end == NULL
250           || name_end - hdr->ar_name >= static_cast<int>(sizeof hdr->ar_name))
251         {
252           gold_error(_("%s: malformed archive header name at %zu"),
253                      this->name().c_str(), static_cast<size_t>(off));
254           return this->input_file_->file().filesize() - off;
255         }
256       pname->assign(hdr->ar_name, name_end - hdr->ar_name);
257       if (nested_off != NULL)
258         *nested_off = 0;
259     }
260   else if (hdr->ar_name[1] == ' ')
261     {
262       // This is the symbol table.
263       pname->clear();
264     }
265   else if (hdr->ar_name[1] == '/')
266     {
267       // This is the extended name table.
268       pname->assign(1, '/');
269     }
270   else
271     {
272       errno = 0;
273       long x = strtol(hdr->ar_name + 1, &end, 10);
274       long y = 0;
275       if (*end == ':')
276         y = strtol(end + 1, &end, 10);
277       if (*end != ' '
278           || x < 0
279           || (x == LONG_MAX && errno == ERANGE)
280           || static_cast<size_t>(x) >= this->extended_names_.size())
281         {
282           gold_error(_("%s: bad extended name index at %zu"),
283                      this->name().c_str(), static_cast<size_t>(off));
284           return this->input_file_->file().filesize() - off;
285         }
286
287       const char* name = this->extended_names_.data() + x;
288       const char* name_end = strchr(name, '\n');
289       if (static_cast<size_t>(name_end - name) > this->extended_names_.size()
290           || name_end[-1] != '/')
291         {
292           gold_error(_("%s: bad extended name entry at header %zu"),
293                      this->name().c_str(), static_cast<size_t>(off));
294           return this->input_file_->file().filesize() - off;
295         }
296       pname->assign(name, name_end - 1 - name);
297       if (nested_off != NULL)
298         *nested_off = y;
299     }
300
301   return member_size;
302 }
303
304 // An archive member iterator.
305
306 class Archive::const_iterator
307 {
308  public:
309   // The header of an archive member.  This is what this iterator
310   // points to.
311   struct Header
312   {
313     // The name of the member.
314     std::string name;
315     // The file offset of the member.
316     off_t off;
317     // The file offset of a nested archive member.
318     off_t nested_off;
319     // The size of the member.
320     off_t size;
321   };
322
323   const_iterator(Archive* archive, off_t off)
324     : archive_(archive), off_(off)
325   { this->read_next_header(); }
326
327   const Header&
328   operator*() const
329   { return this->header_; }
330
331   const Header*
332   operator->() const
333   { return &this->header_; }
334
335   const_iterator&
336   operator++()
337   {
338     if (this->off_ == this->archive_->file().filesize())
339       return *this;
340     this->off_ += sizeof(Archive_header);
341     if (!this->archive_->is_thin_archive())
342       this->off_ += this->header_.size;
343     if ((this->off_ & 1) != 0)
344       ++this->off_;
345     this->read_next_header();
346     return *this;
347   }
348
349   const_iterator
350   operator++(int)
351   {
352     const_iterator ret = *this;
353     ++*this;
354     return ret;
355   }
356
357   bool
358   operator==(const const_iterator p) const
359   { return this->off_ == p->off; }
360
361   bool
362   operator!=(const const_iterator p) const
363   { return this->off_ != p->off; }
364
365  private:
366   void
367   read_next_header();
368
369   // The underlying archive.
370   Archive* archive_;
371   // The current offset in the file.
372   off_t off_;
373   // The current archive header.
374   Header header_;
375 };
376
377 // Read the next archive header.
378
379 void
380 Archive::const_iterator::read_next_header()
381 {
382   off_t filesize = this->archive_->file().filesize();
383   while (true)
384     {
385       if (filesize - this->off_ < static_cast<off_t>(sizeof(Archive_header)))
386         {
387           if (filesize != this->off_)
388             {
389               gold_error(_("%s: short archive header at %zu"),
390                          this->archive_->filename().c_str(),
391                          static_cast<size_t>(this->off_));
392               this->off_ = filesize;
393             }
394           this->header_.off = filesize;
395           return;
396         }
397
398       unsigned char buf[sizeof(Archive_header)];
399       this->archive_->file().read(this->off_, sizeof(Archive_header), buf);
400
401       const Archive_header* hdr = reinterpret_cast<const Archive_header*>(buf);
402       this->header_.size =
403         this->archive_->interpret_header(hdr, this->off_, &this->header_.name,
404                                          &this->header_.nested_off);
405       this->header_.off = this->off_;
406
407       // Skip special members.
408       if (!this->header_.name.empty() && this->header_.name != "/")
409         return;
410
411       this->off_ += sizeof(Archive_header) + this->header_.size;
412       if ((this->off_ & 1) != 0)
413         ++this->off_;
414     }
415 }
416
417 // Initial iterator.
418
419 Archive::const_iterator
420 Archive::begin()
421 {
422   return Archive::const_iterator(this, sarmag);
423 }
424
425 // Final iterator.
426
427 Archive::const_iterator
428 Archive::end()
429 {
430   return Archive::const_iterator(this, this->input_file_->file().filesize());
431 }
432
433 // Get the file and offset for an archive member, which may be an
434 // external member of a thin archive.  Set *INPUT_FILE to the
435 // file containing the actual member, *MEMOFF to the offset
436 // within that file (0 if not a nested archive), and *MEMBER_NAME
437 // to the name of the archive member.  Return TRUE on success.
438
439 bool
440 Archive::get_file_and_offset(off_t off, Input_objects* input_objects,
441                              Input_file** input_file, off_t* memoff,
442                              std::string* member_name)
443 {
444   off_t nested_off;
445
446   this->read_header(off, false, member_name, &nested_off);
447
448   *input_file = this->input_file_;
449   *memoff = off + static_cast<off_t>(sizeof(Archive_header));
450
451   if (!this->is_thin_archive_)
452     return true;
453
454   // Adjust a relative pathname so that it is relative
455   // to the directory containing the archive.
456   if (!IS_ABSOLUTE_PATH(member_name->c_str()))
457     {
458       const char* arch_path = this->name().c_str();
459       const char* basename = lbasename(arch_path);
460       if (basename > arch_path)
461         member_name->replace(0, 0,
462                              this->name().substr(0, basename - arch_path));
463     }
464
465   if (nested_off > 0)
466     {
467       // This is a member of a nested archive.  Open the containing
468       // archive if we don't already have it open, then do a recursive
469       // call to include the member from that archive.
470       Archive* arch;
471       Nested_archive_table::const_iterator p =
472         this->nested_archives_.find(*member_name);
473       if (p != this->nested_archives_.end())
474         arch = p->second;
475       else
476         {
477           Input_file_argument* input_file_arg =
478             new Input_file_argument(member_name->c_str(), false, "", false,
479                                     parameters->options());
480           *input_file = new Input_file(input_file_arg);
481           if (!(*input_file)->open(parameters->options(), *this->dirpath_,
482                                    this->task_))
483             return false;
484           arch = new Archive(*member_name, *input_file, false, this->dirpath_,
485                              this->task_);
486           arch->setup(input_objects);
487           std::pair<Nested_archive_table::iterator, bool> ins =
488             this->nested_archives_.insert(std::make_pair(*member_name, arch));
489           gold_assert(ins.second);
490         }
491       return arch->get_file_and_offset(nested_off, input_objects,
492                                        input_file, memoff, member_name);
493     }
494
495   // This is an external member of a thin archive.  Open the
496   // file as a regular relocatable object file.
497   Input_file_argument* input_file_arg =
498       new Input_file_argument(member_name->c_str(), false, "", false,
499                               this->input_file_->options());
500   *input_file = new Input_file(input_file_arg);
501   if (!(*input_file)->open(parameters->options(), *this->dirpath_,
502                            this->task_))
503     return false;
504
505   *memoff = 0;
506   return true;
507 }
508
509 // Return an ELF object for the member at offset OFF.  Set *MEMBER_NAME to
510 // the name of the member.
511
512 Object*
513 Archive::get_elf_object_for_member(off_t off, Input_objects* input_objects)
514 {
515   std::string member_name;
516   Input_file* input_file;
517   off_t memoff;
518
519   if (!this->get_file_and_offset(off, input_objects, &input_file, &memoff,
520                                  &member_name))
521     return NULL;
522
523   off_t filesize = input_file->file().filesize();
524   int read_size = elfcpp::Elf_sizes<64>::ehdr_size;
525   if (filesize - memoff < read_size)
526     read_size = filesize - memoff;
527
528   if (read_size < 4)
529     {
530       gold_error(_("%s: member at %zu is not an ELF object"),
531                  this->name().c_str(), static_cast<size_t>(off));
532       return NULL;
533     }
534
535   const unsigned char* ehdr = input_file->file().get_view(memoff, 0, read_size,
536                                                           true, false);
537
538   static unsigned char elfmagic[4] =
539     {
540       elfcpp::ELFMAG0, elfcpp::ELFMAG1,
541       elfcpp::ELFMAG2, elfcpp::ELFMAG3
542     };
543   if (memcmp(ehdr, elfmagic, 4) != 0)
544     {
545       gold_error(_("%s: member at %zu is not an ELF object"),
546                  this->name().c_str(), static_cast<size_t>(off));
547       return NULL;
548     }
549
550   return make_elf_object((std::string(this->input_file_->filename())
551                                  + "(" + member_name + ")"),
552                                 input_file, memoff, ehdr, read_size);
553 }
554
555 // Read the symbols from all the archive members in the link.
556
557 void
558 Archive::read_all_symbols(Input_objects* input_objects)
559 {
560   for (Archive::const_iterator p = this->begin();
561        p != this->end();
562        ++p)
563     this->read_symbols(input_objects, p->off);
564 }
565
566 // Read the symbols from an archive member in the link.  OFF is the file
567 // offset of the member header.
568
569 void
570 Archive::read_symbols(Input_objects* input_objects, off_t off)
571 {
572   Object* obj = this->get_elf_object_for_member(off, input_objects);
573
574   if (obj == NULL)
575     return;
576
577   Read_symbols_data* sd = new Read_symbols_data;
578   obj->read_symbols(sd);
579   Archive_member member(obj, sd);
580   this->members_[off] = member;
581 }
582
583 // Select members from the archive and add them to the link.  We walk
584 // through the elements in the archive map, and look each one up in
585 // the symbol table.  If it exists as a strong undefined symbol, we
586 // pull in the corresponding element.  We have to do this in a loop,
587 // since pulling in one element may create new undefined symbols which
588 // may be satisfied by other objects in the archive.
589
590 void
591 Archive::add_symbols(Symbol_table* symtab, Layout* layout,
592                      Input_objects* input_objects, Mapfile* mapfile)
593 {
594   ++Archive::total_archives;
595
596   if (this->input_file_->options().whole_archive())
597     return this->include_all_members(symtab, layout, input_objects,
598                                      mapfile);
599
600   Archive::total_members += this->num_members_;
601
602   input_objects->archive_start(this);
603
604   const size_t armap_size = this->armap_.size();
605
606   // This is a quick optimization, since we usually see many symbols
607   // in a row with the same offset.  last_seen_offset holds the last
608   // offset we saw that was present in the seen_offsets_ set.
609   off_t last_seen_offset = -1;
610
611   // Track which symbols in the symbol table we've already found to be
612   // defined.
613
614   bool added_new_object;
615   do
616     {
617       added_new_object = false;
618       for (size_t i = 0; i < armap_size; ++i)
619         {
620           if (this->armap_checked_[i])
621             continue;
622           if (this->armap_[i].file_offset == last_seen_offset)
623             {
624               this->armap_checked_[i] = true;
625               continue;
626             }
627           if (this->seen_offsets_.find(this->armap_[i].file_offset)
628               != this->seen_offsets_.end())
629             {
630               this->armap_checked_[i] = true;
631               last_seen_offset = this->armap_[i].file_offset;
632               continue;
633             }
634
635           const char* sym_name = (this->armap_names_.data()
636                                   + this->armap_[i].name_offset);
637           Symbol* sym = symtab->lookup(sym_name);
638           if (sym == NULL)
639             {
640               // Check whether the symbol was named in a -u option.
641               if (!parameters->options().is_undefined(sym_name))
642                 continue;
643             }
644           else if (!sym->is_undefined())
645             {
646               this->armap_checked_[i] = true;
647               continue;
648             }
649           else if (sym->binding() == elfcpp::STB_WEAK)
650             continue;
651
652           // We want to include this object in the link.
653           last_seen_offset = this->armap_[i].file_offset;
654           this->seen_offsets_.insert(last_seen_offset);
655           this->armap_checked_[i] = true;
656
657           std::string why;
658           if (sym == NULL)
659             {
660               why = "-u ";
661               why += sym_name;
662             }
663           this->include_member(symtab, layout, input_objects,
664                                last_seen_offset, mapfile, sym, why.c_str());
665
666           added_new_object = true;
667         }
668     }
669   while (added_new_object);
670
671   input_objects->archive_stop(this);
672 }
673
674 // Include all the archive members in the link.  This is for --whole-archive.
675
676 void
677 Archive::include_all_members(Symbol_table* symtab, Layout* layout,
678                              Input_objects* input_objects, Mapfile* mapfile)
679 {
680   input_objects->archive_start(this);
681
682   if (this->members_.size() > 0)
683     {
684       std::map<off_t, Archive_member>::const_iterator p;
685       for (p = this->members_.begin();
686            p != this->members_.end();
687            ++p)
688         {
689           this->include_member(symtab, layout, input_objects, p->first,
690                                mapfile, NULL, "--whole-archive");
691           ++Archive::total_members;
692         }
693     }
694   else
695     {
696       for (Archive::const_iterator p = this->begin();
697            p != this->end();
698            ++p)
699         {
700           this->include_member(symtab, layout, input_objects, p->off,
701                                mapfile, NULL, "--whole-archive");
702           ++Archive::total_members;
703         }
704     }
705
706   input_objects->archive_stop(this);
707 }
708
709 // Return the number of members in the archive.  This is only used for
710 // reports.
711
712 size_t
713 Archive::count_members()
714 {
715   size_t ret = 0;
716   for (Archive::const_iterator p = this->begin();
717        p != this->end();
718        ++p)
719     ++ret;
720   return ret;
721 }
722
723 // Include an archive member in the link.  OFF is the file offset of
724 // the member header.  WHY is the reason we are including this member.
725
726 void
727 Archive::include_member(Symbol_table* symtab, Layout* layout,
728                         Input_objects* input_objects, off_t off,
729                         Mapfile* mapfile, Symbol* sym, const char* why)
730 {
731   ++Archive::total_members_loaded;
732
733   std::map<off_t, Archive_member>::const_iterator p = this->members_.find(off);
734   if (p != this->members_.end())
735     {
736       Object *obj = p->second.obj_;
737       Read_symbols_data *sd = p->second.sd_;
738       if (mapfile != NULL)
739         mapfile->report_include_archive_member(obj->name(), sym, why);
740       if (input_objects->add_object(obj))
741         {
742           obj->layout(symtab, layout, sd);
743           obj->add_symbols(symtab, sd);
744         }
745       delete sd;
746       return;
747     }
748
749   Object* obj = this->get_elf_object_for_member(off, input_objects);
750   if (obj == NULL)
751     return;
752
753   if (mapfile != NULL)
754     mapfile->report_include_archive_member(obj->name(), sym, why);
755
756   if (input_objects->add_object(obj))
757     {
758       Read_symbols_data sd;
759       obj->read_symbols(&sd);
760       obj->layout(symtab, layout, &sd);
761       obj->add_symbols(symtab, &sd);
762     }
763   else
764     {
765       // FIXME: We need to close the descriptor here.
766       delete obj;
767     }
768 }
769
770 // Print statistical information to stderr.  This is used for --stats.
771
772 void
773 Archive::print_stats()
774 {
775   fprintf(stderr, _("%s: archive libraries: %u\n"),
776           program_name, Archive::total_archives);
777   fprintf(stderr, _("%s: total archive members: %u\n"),
778           program_name, Archive::total_members);
779   fprintf(stderr, _("%s: loaded archive members: %u\n"),
780           program_name, Archive::total_members_loaded);
781 }
782
783 // Add_archive_symbols methods.
784
785 Add_archive_symbols::~Add_archive_symbols()
786 {
787   if (this->this_blocker_ != NULL)
788     delete this->this_blocker_;
789   // next_blocker_ is deleted by the task associated with the next
790   // input file.
791 }
792
793 // Return whether we can add the archive symbols.  We are blocked by
794 // this_blocker_.  We block next_blocker_.  We also lock the file.
795
796 Task_token*
797 Add_archive_symbols::is_runnable()
798 {
799   if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
800     return this->this_blocker_;
801   return NULL;
802 }
803
804 void
805 Add_archive_symbols::locks(Task_locker* tl)
806 {
807   tl->add(this, this->next_blocker_);
808   tl->add(this, this->archive_->token());
809 }
810
811 void
812 Add_archive_symbols::run(Workqueue*)
813 {
814   this->archive_->add_symbols(this->symtab_, this->layout_,
815                               this->input_objects_, this->mapfile_);
816
817   this->archive_->unlock_nested_archives();
818
819   this->archive_->release();
820   this->archive_->clear_uncached_views();
821
822   if (this->input_group_ != NULL)
823     this->input_group_->add_archive(this->archive_);
824   else
825     {
826       // We no longer need to know about this archive.
827       delete this->archive_;
828       this->archive_ = NULL;
829     }
830 }
831
832 } // End namespace gold.