Implement --whole-archive.
[external/binutils.git] / gold / archive.cc
1 // archive.cc -- archive support for gold
2
3 #include "gold.h"
4
5 #include <cerrno>
6 #include <cstring>
7 #include <climits>
8 #include <vector>
9
10 #include "elfcpp.h"
11 #include "fileread.h"
12 #include "readsyms.h"
13 #include "symtab.h"
14 #include "object.h"
15 #include "archive.h"
16
17 namespace gold
18 {
19
20 // The header of an entry in the archive.  This is all readable text,
21 // padded with spaces where necesary.  If the contents of an archive
22 // are all text file, the entire archive is readable.
23
24 struct Archive::Archive_header
25 {
26   // The entry name.
27   char ar_name[16];
28   // The file modification time.
29   char ar_date[12];
30   // The user's UID in decimal.
31   char ar_uid[6];
32   // The user's GID in decimal.
33   char ar_gid[6];
34   // The file mode in octal.
35   char ar_mode[8];
36   // The file size in decimal.
37   char ar_size[10];
38   // The final magic code.
39   char ar_fmag[2];
40 };
41
42 // Archive methods.
43
44 const char Archive::armag[sarmag] =
45 {
46   '!', '<', 'a', 'r', 'c', 'h', '>', '\n'
47 };
48
49 const char Archive::arfmag[2] = { '`', '\n' };
50
51 // Set up the archive: read the symbol map and the extended name
52 // table.
53
54 void
55 Archive::setup()
56 {
57   // The first member of the archive should be the symbol table.
58   std::string armap_name;
59   off_t armap_size = this->read_header(sarmag, &armap_name);
60   off_t off;
61   if (armap_name.empty())
62     {
63       this->read_armap(sarmag + sizeof(Archive_header), armap_size);
64       off = sarmag + sizeof(Archive_header) + armap_size;
65     }
66   else if (!this->input_file_->options().include_whole_archive())
67     {
68       fprintf(stderr, _("%s: %s: no archive symbol table (run ranlib)\n"),
69               program_name, this->name().c_str());
70       gold_exit(false);
71     }
72   else
73     off = sarmag;
74
75   // See if there is an extended name table.
76   if ((off & 1) != 0)
77     ++off;
78   std::string xname;
79   off_t extended_size = this->read_header(off, &xname);
80   if (xname == "/")
81     {
82       const unsigned char* p = this->get_view(off + sizeof(Archive_header),
83                                               extended_size);
84       const char* px = reinterpret_cast<const char*>(p);
85       this->extended_names_.assign(px, extended_size);
86     }
87
88   // Opening the file locked it.  Unlock it now.
89   this->input_file_->file().unlock();
90 }
91
92 // Read the archive symbol map.
93
94 void
95 Archive::read_armap(off_t start, off_t size)
96 {
97   // Read in the entire armap.
98   const unsigned char* p = this->get_view(start, size);
99
100   // Numbers in the armap are always big-endian.
101   const elfcpp::Elf_Word* pword = reinterpret_cast<const elfcpp::Elf_Word*>(p);
102   unsigned int nsyms = elfcpp::Swap<32, true>::readval(pword);
103   ++pword;
104
105   // Note that the addition is in units of sizeof(elfcpp::Elf_Word).
106   const char* pnames = reinterpret_cast<const char*>(pword + nsyms);
107
108   this->armap_.resize(nsyms);
109
110   for (unsigned int i = 0; i < nsyms; ++i)
111     {
112       this->armap_[i].name = pnames;
113       this->armap_[i].offset = elfcpp::Swap<32, true>::readval(pword);
114       pnames += strlen(pnames) + 1;
115       ++pword;
116     }
117
118   if (reinterpret_cast<const unsigned char*>(pnames) - p > size)
119     {
120       fprintf(stderr, _("%s: %s: bad archive symbol table names\n"),
121               program_name, this->name().c_str());
122       gold_exit(false);
123     }
124
125   // This array keeps track of which symbols are for archive elements
126   // which we have already included in the link.
127   this->seen_.resize(nsyms);
128 }
129
130 // Read the header of an archive member at OFF.  Fail if something
131 // goes wrong.  Return the size of the member.  Set *PNAME to the name
132 // of the member.
133
134 off_t
135 Archive::read_header(off_t off, std::string* pname)
136 {
137   const unsigned char* p = this->get_view(off, sizeof(Archive_header));
138   const Archive_header* hdr = reinterpret_cast<const Archive_header*>(p);
139   return this->interpret_header(hdr, off,  pname);
140 }
141
142 // Interpret the header of HDR, the header of the archive member at
143 // file offset OFF.  Fail if something goes wrong.  Return the size of
144 // the member.  Set *PNAME to the name of the member.
145
146 off_t
147 Archive::interpret_header(const Archive_header* hdr, off_t off,
148                           std::string* pname)
149 {
150   if (memcmp(hdr->ar_fmag, arfmag, sizeof arfmag) != 0)
151     {
152       fprintf(stderr, _("%s; %s: malformed archive header at %ld\n"),
153               program_name, this->name().c_str(),
154               static_cast<long>(off));
155       gold_exit(false);
156     }
157
158   const int size_string_size = sizeof hdr->ar_size;
159   char size_string[size_string_size + 1];
160   memcpy(size_string, hdr->ar_size, size_string_size);
161   char* ps = size_string + size_string_size;
162   while (ps[-1] == ' ')
163     --ps;
164   *ps = '\0';
165
166   errno = 0;
167   char* end;
168   off_t member_size = strtol(size_string, &end, 10);
169   if (*end != '\0'
170       || member_size < 0
171       || (member_size == LONG_MAX && errno == ERANGE))
172     {
173       fprintf(stderr, _("%s: %s: malformed archive header size at %ld\n"),
174               program_name, this->name().c_str(),
175               static_cast<long>(off));
176       gold_exit(false);
177     }
178
179   if (hdr->ar_name[0] != '/')
180     {
181       const char* name_end = strchr(hdr->ar_name, '/');
182       if (name_end == NULL
183           || name_end - hdr->ar_name >= static_cast<int>(sizeof hdr->ar_name))
184         {
185           fprintf(stderr, _("%s: %s: malformed archive header name at %ld\n"),
186                   program_name, this->name().c_str(),
187                   static_cast<long>(off));
188           gold_exit(false);
189         }
190       pname->assign(hdr->ar_name, name_end - hdr->ar_name);
191     }
192   else if (hdr->ar_name[1] == ' ')
193     {
194       // This is the symbol table.
195       pname->clear();
196     }
197   else if (hdr->ar_name[1] == '/')
198     {
199       // This is the extended name table.
200       pname->assign(1, '/');
201     }
202   else
203     {
204       errno = 0;
205       long x = strtol(hdr->ar_name + 1, &end, 10);
206       if (*end != ' '
207           || x < 0
208           || (x == LONG_MAX && errno == ERANGE)
209           || static_cast<size_t>(x) >= this->extended_names_.size())
210         {
211           fprintf(stderr, _("%s: %s: bad extended name index at %ld\n"),
212                   program_name, this->name().c_str(),
213                   static_cast<long>(off));
214           gold_exit(false);
215         }
216
217       const char* name = this->extended_names_.data() + x;
218       const char* name_end = strchr(name, '/');
219       if (static_cast<size_t>(name_end - name) > this->extended_names_.size()
220           || name_end[1] != '\n')
221         {
222           fprintf(stderr, _("%s: %s: bad extended name entry at header %ld\n"),
223                   program_name, this->name().c_str(),
224                   static_cast<long>(off));
225           gold_exit(false);
226         }
227       pname->assign(name, name_end - name);
228     }
229
230   return member_size;
231 }
232
233 // Select members from the archive and add them to the link.  We walk
234 // through the elements in the archive map, and look each one up in
235 // the symbol table.  If it exists as a strong undefined symbol, we
236 // pull in the corresponding element.  We have to do this in a loop,
237 // since pulling in one element may create new undefined symbols which
238 // may be satisfied by other objects in the archive.
239
240 void
241 Archive::add_symbols(const General_options& options, Symbol_table* symtab,
242                      Layout* layout, Input_objects* input_objects)
243 {
244   if (this->input_file_->options().include_whole_archive())
245     return this->include_all_members(options, symtab, layout, input_objects);
246
247   const size_t armap_size = this->armap_.size();
248
249   bool added_new_object;
250   do
251     {
252       added_new_object = false;
253       off_t last = -1;
254       for (size_t i = 0; i < armap_size; ++i)
255         {
256           if (this->seen_[i])
257             continue;
258           if (this->armap_[i].offset == last)
259             {
260               this->seen_[i] = true;
261               continue;
262             }
263
264           Symbol* sym = symtab->lookup(this->armap_[i].name);
265           if (sym == NULL)
266             continue;
267           else if (!sym->is_undefined())
268             {
269               this->seen_[i] = true;
270               continue;
271             }
272           else if (sym->binding() == elfcpp::STB_WEAK)
273             continue;
274
275           // We want to include this object in the link.
276           last = this->armap_[i].offset;
277           this->include_member(options, symtab, layout, input_objects, last);
278           this->seen_[i] = true;
279           added_new_object = true;
280         }
281     }
282   while (added_new_object);
283 }
284
285 // Include all the archive members in the link.  This is for --whole-archive.
286
287 void
288 Archive::include_all_members(const General_options& options,
289                              Symbol_table* symtab, Layout* layout,
290                              Input_objects* input_objects)
291 {
292   off_t off = sarmag;
293   while (true)
294     {
295       off_t bytes;
296       const unsigned char* p = this->get_view(off, sizeof(Archive_header),
297                                               &bytes);
298       if (bytes < sizeof(Archive_header))
299         {
300           if (bytes != 0)
301             {
302               fprintf(stderr, _("%s: %s: short archive header at %ld\n"),
303                       program_name, this->name().c_str(),
304                       static_cast<long>(off));
305               gold_exit(false);
306             }
307
308           break;
309         }
310
311       const Archive_header* hdr = reinterpret_cast<const Archive_header*>(p);
312       std::string name;
313       off_t size = this->interpret_header(hdr, off, &name);
314       if (name.empty())
315         {
316           // Symbol table.
317         }
318       else if (name == "/")
319         {
320           // Extended name table.
321         }
322       else
323         this->include_member(options, symtab, layout, input_objects, off);
324
325       off += sizeof(Archive_header) + size;
326       if ((off & 1) != 0)
327         ++off;
328     }
329 }
330
331 // Include an archive member in the link.  OFF is the file offset of
332 // the member header.
333
334 void
335 Archive::include_member(const General_options& options, Symbol_table* symtab,
336                         Layout* layout, Input_objects* input_objects,
337                         off_t off)
338 {
339   std::string n;
340   this->read_header(off, &n);
341
342   size_t memoff = off + sizeof(Archive_header);
343
344   // Read enough of the file to pick up the entire ELF header.
345   int ehdr_size = elfcpp::Elf_sizes<64>::ehdr_size;
346   off_t bytes;
347   const unsigned char* p = this->input_file_->file().get_view(memoff,
348                                                               ehdr_size,
349                                                               &bytes);
350   if (bytes < 4)
351     {
352       fprintf(stderr, _("%s: %s: member at %ld is not an ELF object"),
353               program_name, this->name().c_str(),
354               static_cast<long>(off));
355       gold_exit(false);
356     }
357
358   static unsigned char elfmagic[4] =
359     {
360       elfcpp::ELFMAG0, elfcpp::ELFMAG1,
361       elfcpp::ELFMAG2, elfcpp::ELFMAG3
362     };
363   if (memcmp(p, elfmagic, 4) != 0)
364     {
365       fprintf(stderr, _("%s: %s: member at %ld is not an ELF object"),
366               program_name, this->name().c_str(),
367               static_cast<long>(off));
368       gold_exit(false);
369     }
370
371   Object* obj = make_elf_object((std::string(this->input_file_->filename())
372                                  + "(" + n + ")"),
373                                 this->input_file_, memoff, p, bytes);
374
375   input_objects->add_object(obj);
376
377   Read_symbols_data sd;
378   obj->read_symbols(&sd);
379   obj->layout(options, symtab, layout, &sd);
380   obj->add_symbols(symtab, &sd);
381 }
382
383 // Add_archive_symbols methods.
384
385 Add_archive_symbols::~Add_archive_symbols()
386 {
387   if (this->this_blocker_ != NULL)
388     delete this->this_blocker_;
389   // next_blocker_ is deleted by the task associated with the next
390   // input file.
391 }
392
393 // Return whether we can add the archive symbols.  We are blocked by
394 // this_blocker_.  We block next_blocker_.  We also lock the file.
395
396 Task::Is_runnable_type
397 Add_archive_symbols::is_runnable(Workqueue*)
398 {
399   if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
400     return IS_BLOCKED;
401   return IS_RUNNABLE;
402 }
403
404 class Add_archive_symbols::Add_archive_symbols_locker : public Task_locker
405 {
406  public:
407   Add_archive_symbols_locker(Task_token& token, Workqueue* workqueue,
408                              File_read& file)
409     : blocker_(token, workqueue), filelock_(file)
410   { }
411
412  private:
413   Task_locker_block blocker_;
414   Task_locker_obj<File_read> filelock_;
415 };
416
417 Task_locker*
418 Add_archive_symbols::locks(Workqueue* workqueue)
419 {
420   return new Add_archive_symbols_locker(*this->next_blocker_,
421                                         workqueue,
422                                         this->archive_->file());
423 }
424
425 void
426 Add_archive_symbols::run(Workqueue*)
427 {
428   this->archive_->add_symbols(this->options_, this->symtab_, this->layout_,
429                               this->input_objects_);
430
431   if (this->input_group_ != NULL)
432     this->input_group_->add_archive(this->archive_);
433   else
434     {
435       // We no longer need to know about this archive.
436       delete this->archive_;
437     }
438 }
439
440 } // End namespace gold.