Merge branch 'vendor/LESS'
[dragonfly.git] / contrib / binutils-2.20 / gold / plugin.cc
1 // plugin.cc -- plugin manager for gold      -*- C++ -*-
2
3 // Copyright 2008, 2009 Free Software Foundation, Inc.
4 // Written by Cary Coutant <ccoutant@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 <cstdio>
26 #include <cstdarg>
27 #include <cstring>
28 #include <string>
29 #include <vector>
30
31 #ifdef ENABLE_PLUGINS
32 #include <dlfcn.h>
33 #endif
34
35 #include "parameters.h"
36 #include "errors.h"
37 #include "fileread.h"
38 #include "layout.h"
39 #include "options.h"
40 #include "plugin.h"
41 #include "target.h"
42 #include "readsyms.h"
43 #include "symtab.h"
44 #include "elfcpp.h"
45
46 namespace gold
47 {
48
49 #ifdef ENABLE_PLUGINS
50
51 // The linker's exported interfaces.
52
53 extern "C"
54 {
55
56 static enum ld_plugin_status
57 register_claim_file(ld_plugin_claim_file_handler handler);
58
59 static enum ld_plugin_status
60 register_all_symbols_read(ld_plugin_all_symbols_read_handler handler);
61
62 static enum ld_plugin_status
63 register_cleanup(ld_plugin_cleanup_handler handler);
64
65 static enum ld_plugin_status
66 add_symbols(void *handle, int nsyms, const struct ld_plugin_symbol *syms);
67
68 static enum ld_plugin_status
69 get_input_file(const void *handle, struct ld_plugin_input_file *file);
70
71 static enum ld_plugin_status
72 release_input_file(const void *handle);
73
74 static enum ld_plugin_status
75 get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms);
76
77 static enum ld_plugin_status
78 add_input_file(char *pathname);
79
80 static enum ld_plugin_status
81 add_input_library(char *pathname);
82
83 static enum ld_plugin_status
84 message(int level, const char *format, ...);
85
86 };
87
88 #endif // ENABLE_PLUGINS
89
90 static Pluginobj* make_sized_plugin_object(Input_file* input_file,
91                                            off_t offset, off_t filesize);
92
93 // Plugin methods.
94
95 // Load one plugin library.
96
97 void
98 Plugin::load()
99 {
100 #ifdef ENABLE_PLUGINS
101   // Load the plugin library.
102   // FIXME: Look for the library in standard locations.
103   this->handle_ = dlopen(this->filename_.c_str(), RTLD_NOW);
104   if (this->handle_ == NULL)
105     {
106       gold_error(_("%s: could not load plugin library"),
107                  this->filename_.c_str());
108       return;
109     }
110
111   // Find the plugin's onload entry point.
112   ld_plugin_onload onload = reinterpret_cast<ld_plugin_onload>
113     (dlsym(this->handle_, "onload"));
114   if (onload == NULL)
115     {
116       gold_error(_("%s: could not find onload entry point"),
117                  this->filename_.c_str());
118       return;
119     }
120
121   // Get the linker's version number.
122   const char* ver = get_version_string();
123   int major = 0;
124   int minor = 0;
125   sscanf(ver, "%d.%d", &major, &minor);
126
127   // Allocate and populate a transfer vector.
128   const int tv_fixed_size = 14;
129   int tv_size = this->args_.size() + tv_fixed_size;
130   ld_plugin_tv *tv = new ld_plugin_tv[tv_size];
131
132   // Put LDPT_MESSAGE at the front of the list so the plugin can use it
133   // while processing subsequent entries.
134   int i = 0;
135   tv[i].tv_tag = LDPT_MESSAGE;
136   tv[i].tv_u.tv_message = message;
137
138   ++i;
139   tv[i].tv_tag = LDPT_API_VERSION;
140   tv[i].tv_u.tv_val = LD_PLUGIN_API_VERSION;
141
142   ++i;
143   tv[i].tv_tag = LDPT_GOLD_VERSION;
144   tv[i].tv_u.tv_val = major * 100 + minor;
145
146   ++i;
147   tv[i].tv_tag = LDPT_LINKER_OUTPUT;
148   if (parameters->options().relocatable())
149     tv[i].tv_u.tv_val = LDPO_REL;
150   else if (parameters->options().shared())
151     tv[i].tv_u.tv_val = LDPO_DYN;
152   else
153     tv[i].tv_u.tv_val = LDPO_EXEC;
154
155   for (unsigned int j = 0; j < this->args_.size(); ++j)
156     {
157       ++i;
158       tv[i].tv_tag = LDPT_OPTION;
159       tv[i].tv_u.tv_string = this->args_[j].c_str();
160     }
161
162   ++i;
163   tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK;
164   tv[i].tv_u.tv_register_claim_file = register_claim_file;
165
166   ++i;
167   tv[i].tv_tag = LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK;
168   tv[i].tv_u.tv_register_all_symbols_read = register_all_symbols_read;
169
170   ++i;
171   tv[i].tv_tag = LDPT_REGISTER_CLEANUP_HOOK;
172   tv[i].tv_u.tv_register_cleanup = register_cleanup;
173
174   ++i;
175   tv[i].tv_tag = LDPT_ADD_SYMBOLS;
176   tv[i].tv_u.tv_add_symbols = add_symbols;
177
178   ++i;
179   tv[i].tv_tag = LDPT_GET_INPUT_FILE;
180   tv[i].tv_u.tv_get_input_file = get_input_file;
181
182   ++i;
183   tv[i].tv_tag = LDPT_RELEASE_INPUT_FILE;
184   tv[i].tv_u.tv_release_input_file = release_input_file;
185
186   ++i;
187   tv[i].tv_tag = LDPT_GET_SYMBOLS;
188   tv[i].tv_u.tv_get_symbols = get_symbols;
189
190   ++i;
191   tv[i].tv_tag = LDPT_ADD_INPUT_FILE;
192   tv[i].tv_u.tv_add_input_file = add_input_file;
193
194   ++i;
195   tv[i].tv_tag = LDPT_ADD_INPUT_LIBRARY;
196   tv[i].tv_u.tv_add_input_library = add_input_library;
197
198   ++i;
199   tv[i].tv_tag = LDPT_NULL;
200   tv[i].tv_u.tv_val = 0;
201
202   gold_assert(i == tv_size - 1);
203
204   // Call the onload entry point.
205   (*onload)(tv);
206
207   delete[] tv;
208 #endif // ENABLE_PLUGINS
209 }
210
211 // Call the plugin claim-file handler.
212
213 inline bool
214 Plugin::claim_file(struct ld_plugin_input_file *plugin_input_file)
215 {
216   int claimed = 0;
217
218   if (this->claim_file_handler_ != NULL)
219     {
220       (*this->claim_file_handler_)(plugin_input_file, &claimed);
221       if (claimed)
222         return true;
223     }
224   return false;
225 }
226
227 // Call the all-symbols-read handler.
228
229 inline void
230 Plugin::all_symbols_read()
231 {
232   if (this->all_symbols_read_handler_ != NULL)
233     (*this->all_symbols_read_handler_)();
234 }
235
236 // Call the cleanup handler.
237
238 inline void
239 Plugin::cleanup()
240 {
241   if (this->cleanup_handler_ != NULL)
242     (*this->cleanup_handler_)();
243 }
244
245 // Plugin_manager methods.
246
247 Plugin_manager::~Plugin_manager()
248 {
249   for (Plugin_list::iterator p = this->plugins_.begin();
250        p != this->plugins_.end();
251        ++p)
252     delete *p;
253   this->plugins_.clear();
254   for (Object_list::iterator obj = this->objects_.begin();
255        obj != this->objects_.end();
256        ++obj)
257     delete *obj;
258   this->objects_.clear();
259 }
260
261 // Load all plugin libraries.
262
263 void
264 Plugin_manager::load_plugins()
265 {
266   for (this->current_ = this->plugins_.begin();
267        this->current_ != this->plugins_.end();
268        ++this->current_)
269     (*this->current_)->load();
270 }
271
272 // Call the plugin claim-file handlers in turn to see if any claim the file.
273
274 Pluginobj*
275 Plugin_manager::claim_file(Input_file* input_file, off_t offset,
276                            off_t filesize)
277 {
278   if (this->in_replacement_phase_)
279     return NULL;
280
281   unsigned int handle = this->objects_.size();
282   this->input_file_ = input_file;
283   this->plugin_input_file_.name = input_file->filename().c_str();
284   this->plugin_input_file_.fd = input_file->file().descriptor();
285   this->plugin_input_file_.offset = offset;
286   this->plugin_input_file_.filesize = filesize;
287   this->plugin_input_file_.handle = reinterpret_cast<void*>(handle);
288
289   for (this->current_ = this->plugins_.begin();
290        this->current_ != this->plugins_.end();
291        ++this->current_)
292     {
293       if ((*this->current_)->claim_file(&this->plugin_input_file_))
294         {
295           if (this->objects_.size() > handle)
296             return this->objects_[handle];
297
298           // If the plugin claimed the file but did not call the
299           // add_symbols callback, we need to create the Pluginobj now.
300           Pluginobj* obj = this->make_plugin_object(handle);
301           return obj;
302         }
303     }
304
305   return NULL;
306 }
307
308 // Call the all-symbols-read handlers.
309
310 void
311 Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
312                                  Input_objects* input_objects,
313                                  Symbol_table* symtab, Layout* layout,
314                                  Dirsearch* dirpath, Mapfile* mapfile,
315                                  Task_token** last_blocker)
316 {
317   this->in_replacement_phase_ = true;
318   this->workqueue_ = workqueue;
319   this->task_ = task;
320   this->input_objects_ = input_objects;
321   this->symtab_ = symtab;
322   this->layout_ = layout;
323   this->dirpath_ = dirpath;
324   this->mapfile_ = mapfile;
325   this->this_blocker_ = NULL;
326
327   for (this->current_ = this->plugins_.begin();
328        this->current_ != this->plugins_.end();
329        ++this->current_)
330     (*this->current_)->all_symbols_read();
331
332   *last_blocker = this->this_blocker_;
333 }
334
335 // Layout deferred objects.
336
337 void
338 Plugin_manager::layout_deferred_objects()
339 {
340   Deferred_layout_list::iterator obj;
341
342   for (obj = this->deferred_layout_objects_.begin();
343        obj != this->deferred_layout_objects_.end();
344        ++obj)
345     (*obj)->layout_deferred_sections(this->layout_);
346 }
347
348 // Call the cleanup handlers.
349
350 void
351 Plugin_manager::cleanup()
352 {
353   if (this->cleanup_done_)
354     return;
355   for (this->current_ = this->plugins_.begin();
356        this->current_ != this->plugins_.end();
357        ++this->current_)
358     (*this->current_)->cleanup();
359   this->cleanup_done_ = true;
360 }
361
362 // Make a new Pluginobj object.  This is called when the plugin calls
363 // the add_symbols API.
364
365 Pluginobj*
366 Plugin_manager::make_plugin_object(unsigned int handle)
367 {
368   // Make sure we aren't asked to make an object for the same handle twice.
369   if (this->objects_.size() != handle)
370     return NULL;
371
372   Pluginobj* obj = make_sized_plugin_object(this->input_file_,
373                                             this->plugin_input_file_.offset,
374                                             this->plugin_input_file_.filesize);
375   this->objects_.push_back(obj);
376   return obj;
377 }
378
379 // Get the input file information with an open (possibly re-opened)
380 // file descriptor.
381
382 ld_plugin_status
383 Plugin_manager::get_input_file(unsigned int handle,
384                                struct ld_plugin_input_file *file)
385 {
386   Pluginobj* obj = this->object(handle);
387   if (obj == NULL)
388     return LDPS_BAD_HANDLE;
389
390   obj->lock(this->task_);
391   file->name = obj->filename().c_str();
392   file->fd = obj->descriptor();
393   file->offset = obj->offset();
394   file->filesize = obj->filesize();
395   file->handle = reinterpret_cast<void*>(handle);
396   return LDPS_OK;
397 }
398
399 // Release the input file.
400
401 ld_plugin_status
402 Plugin_manager::release_input_file(unsigned int handle)
403 {
404   Pluginobj* obj = this->object(handle);
405   if (obj == NULL)
406     return LDPS_BAD_HANDLE;
407
408   obj->unlock(this->task_);
409   return LDPS_OK;
410 }
411
412 // Add a new input file.
413
414 ld_plugin_status
415 Plugin_manager::add_input_file(char *pathname, bool is_lib)
416 {
417   Input_file_argument file(pathname,
418                            (is_lib
419                             ? Input_file_argument::INPUT_FILE_TYPE_LIBRARY
420                             : Input_file_argument::INPUT_FILE_TYPE_FILE),
421                            "", false, this->options_);
422   Input_argument* input_argument = new Input_argument(file);
423   Task_token* next_blocker = new Task_token(true);
424   next_blocker->add_blocker();
425   if (this->layout_->incremental_inputs())
426     gold_error(_("Input files added by plug-ins in --incremental mode not "
427                  "supported yet.\n"));
428   this->workqueue_->queue_soon(new Read_symbols(this->input_objects_,
429                                                 this->symtab_,
430                                                 this->layout_,
431                                                 this->dirpath_,
432                                                 0,
433                                                 this->mapfile_,
434                                                 input_argument,
435                                                 NULL,
436                                                 this->this_blocker_,
437                                                 next_blocker));
438   this->this_blocker_ = next_blocker;
439   return LDPS_OK;
440 }
441
442 // Class Pluginobj.
443
444 Pluginobj::Pluginobj(const std::string& name, Input_file* input_file,
445                      off_t offset, off_t filesize)
446   : Object(name, input_file, false, offset),
447     nsyms_(0), syms_(NULL), symbols_(), filesize_(filesize), comdat_map_()
448 {
449 }
450
451 // Return TRUE if a defined symbol might be reachable from outside the
452 // universe of claimed objects.
453
454 static inline bool
455 is_visible_from_outside(Symbol* lsym)
456 {
457   if (lsym->in_real_elf())
458     return true;
459   if (parameters->options().relocatable())
460     return true;
461   if (parameters->options().export_dynamic() || parameters->options().shared())
462     return lsym->is_externally_visible();
463   return false;
464 }
465
466 // Get symbol resolution info.
467
468 ld_plugin_status
469 Pluginobj::get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const
470 {
471   if (nsyms > this->nsyms_)
472     return LDPS_NO_SYMS;
473   for (int i = 0; i < nsyms; i++)
474     {
475       ld_plugin_symbol* isym = &syms[i];
476       Symbol* lsym = this->symbols_[i];
477       ld_plugin_symbol_resolution res = LDPR_UNKNOWN;
478
479       if (lsym->is_undefined())
480         // The symbol remains undefined.
481         res = LDPR_UNDEF;
482       else if (isym->def == LDPK_UNDEF
483                || isym->def == LDPK_WEAKUNDEF
484                || isym->def == LDPK_COMMON)
485         {
486           // The original symbol was undefined or common.
487           if (lsym->source() != Symbol::FROM_OBJECT)
488             res = LDPR_RESOLVED_EXEC;
489           else if (lsym->object()->pluginobj() != NULL)
490             res = LDPR_RESOLVED_IR;
491           else if (lsym->object()->is_dynamic())
492             res = LDPR_RESOLVED_DYN;
493           else
494             res = LDPR_RESOLVED_EXEC;
495         }
496       else
497         {
498           // The original symbol was a definition.
499           if (lsym->source() != Symbol::FROM_OBJECT)
500             res = LDPR_PREEMPTED_REG;
501           else if (lsym->object() == static_cast<const Object*>(this))
502             res = (is_visible_from_outside(lsym)
503                    ? LDPR_PREVAILING_DEF
504                    : LDPR_PREVAILING_DEF_IRONLY);
505           else
506             res = (lsym->object()->pluginobj() != NULL
507                    ? LDPR_PREEMPTED_IR
508                    : LDPR_PREEMPTED_REG);
509         }
510       isym->resolution = res;
511     }
512   return LDPS_OK;
513 }
514
515 // Return TRUE if the comdat group with key COMDAT_KEY from this object
516 // should be kept.
517
518 bool
519 Pluginobj::include_comdat_group(std::string comdat_key, Layout* layout)
520 {
521   std::pair<Comdat_map::iterator, bool> ins =
522     this->comdat_map_.insert(std::make_pair(comdat_key, false));
523
524   // If this is the first time we've seen this comdat key, ask the
525   // layout object whether it should be included.
526   if (ins.second)
527     ins.first->second = layout->find_or_add_kept_section(comdat_key,
528                                                          NULL, 0, true,
529                                                          true, NULL);
530
531   return ins.first->second;
532 }
533
534 // Class Sized_pluginobj.
535
536 template<int size, bool big_endian>
537 Sized_pluginobj<size, big_endian>::Sized_pluginobj(
538     const std::string& name,
539     Input_file* input_file,
540     off_t offset,
541     off_t filesize)
542   : Pluginobj(name, input_file, offset, filesize)
543 {
544 }
545
546 // Read the symbols.  Not used for plugin objects.
547
548 template<int size, bool big_endian>
549 void
550 Sized_pluginobj<size, big_endian>::do_read_symbols(Read_symbols_data*)
551 {
552   gold_unreachable();
553 }
554
555 // Lay out the input sections.  Not used for plugin objects.
556
557 template<int size, bool big_endian>
558 void
559 Sized_pluginobj<size, big_endian>::do_layout(Symbol_table*, Layout*,
560                                              Read_symbols_data*)
561 {
562   gold_unreachable();
563 }
564
565 // Add the symbols to the symbol table.
566
567 template<int size, bool big_endian>
568 void
569 Sized_pluginobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
570                                                   Read_symbols_data*,
571                                                   Layout* layout)
572 {
573   const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
574   unsigned char symbuf[sym_size];
575   elfcpp::Sym<size, big_endian> sym(symbuf);
576   elfcpp::Sym_write<size, big_endian> osym(symbuf);
577
578   typedef typename elfcpp::Elf_types<size>::Elf_WXword Elf_size_type;
579
580   this->symbols_.resize(this->nsyms_);
581
582   for (int i = 0; i < this->nsyms_; ++i)
583     {
584       const struct ld_plugin_symbol *isym = &this->syms_[i];
585       const char* name = isym->name;
586       const char* ver = isym->version;
587       elfcpp::Elf_Half shndx;
588       elfcpp::STB bind;
589       elfcpp::STV vis;
590
591       if (name != NULL && name[0] == '\0')
592         name = NULL;
593       if (ver != NULL && ver[0] == '\0')
594         ver = NULL;
595
596       switch (isym->def)
597         {
598         case LDPK_WEAKDEF:
599         case LDPK_WEAKUNDEF:
600           bind = elfcpp::STB_WEAK;
601           break;
602         case LDPK_DEF:
603         case LDPK_UNDEF:
604         case LDPK_COMMON:
605         default:
606           bind = elfcpp::STB_GLOBAL;
607           break;
608         }
609
610       switch (isym->def)
611         {
612         case LDPK_DEF:
613         case LDPK_WEAKDEF:
614           shndx = elfcpp::SHN_ABS;
615           break;
616         case LDPK_COMMON:
617           shndx = elfcpp::SHN_COMMON;
618           break;
619         case LDPK_UNDEF:
620         case LDPK_WEAKUNDEF:
621         default:
622           shndx = elfcpp::SHN_UNDEF;
623           break;
624         }
625
626       switch (isym->visibility)
627         {
628         case LDPV_PROTECTED:
629           vis = elfcpp::STV_DEFAULT;
630           break;
631         case LDPV_INTERNAL:
632           vis = elfcpp::STV_DEFAULT;
633           break;
634         case LDPV_HIDDEN:
635           vis = elfcpp::STV_DEFAULT;
636           break;
637         case LDPV_DEFAULT:
638         default:
639           vis = elfcpp::STV_DEFAULT;
640           break;
641         }
642
643       if (isym->comdat_key != NULL
644           && isym->comdat_key[0] != '\0'
645           && !this->include_comdat_group(isym->comdat_key, layout))
646         shndx = elfcpp::SHN_UNDEF;
647
648       osym.put_st_name(0);
649       osym.put_st_value(0);
650       osym.put_st_size(static_cast<Elf_size_type>(isym->size));
651       osym.put_st_info(bind, elfcpp::STT_NOTYPE);
652       osym.put_st_other(vis, 0);
653       osym.put_st_shndx(shndx);
654
655       this->symbols_[i] =
656         symtab->add_from_pluginobj<size, big_endian>(this, name, ver, &sym);
657     }
658 }
659
660 // Get the size of a section.  Not used for plugin objects.
661
662 template<int size, bool big_endian>
663 uint64_t
664 Sized_pluginobj<size, big_endian>::do_section_size(unsigned int)
665 {
666   gold_unreachable();
667   return 0;
668 }
669
670 // Get the name of a section.  Not used for plugin objects.
671
672 template<int size, bool big_endian>
673 std::string
674 Sized_pluginobj<size, big_endian>::do_section_name(unsigned int)
675 {
676   gold_unreachable();
677   return std::string();
678 }
679
680 // Return a view of the contents of a section.  Not used for plugin objects.
681
682 template<int size, bool big_endian>
683 Object::Location
684 Sized_pluginobj<size, big_endian>::do_section_contents(unsigned int)
685 {
686   Location loc(0, 0);
687
688   gold_unreachable();
689   return loc;
690 }
691
692 // Return section flags.  Not used for plugin objects.
693
694 template<int size, bool big_endian>
695 uint64_t
696 Sized_pluginobj<size, big_endian>::do_section_flags(unsigned int)
697 {
698   gold_unreachable();
699   return 0;
700 }
701
702 // Return section entsize.  Not used for plugin objects.
703
704 template<int size, bool big_endian>
705 uint64_t
706 Sized_pluginobj<size, big_endian>::do_section_entsize(unsigned int)
707 {
708   gold_unreachable();
709   return 0;
710 }
711
712 // Return section address.  Not used for plugin objects.
713
714 template<int size, bool big_endian>
715 uint64_t
716 Sized_pluginobj<size, big_endian>::do_section_address(unsigned int)
717 {
718   gold_unreachable();
719   return 0;
720 }
721
722 // Return section type.  Not used for plugin objects.
723
724 template<int size, bool big_endian>
725 unsigned int
726 Sized_pluginobj<size, big_endian>::do_section_type(unsigned int)
727 {
728   gold_unreachable();
729   return 0;
730 }
731
732 // Return the section link field.  Not used for plugin objects.
733
734 template<int size, bool big_endian>
735 unsigned int
736 Sized_pluginobj<size, big_endian>::do_section_link(unsigned int)
737 {
738   gold_unreachable();
739   return 0;
740 }
741
742 // Return the section link field.  Not used for plugin objects.
743
744 template<int size, bool big_endian>
745 unsigned int
746 Sized_pluginobj<size, big_endian>::do_section_info(unsigned int)
747 {
748   gold_unreachable();
749   return 0;
750 }
751
752 // Return the section alignment.  Not used for plugin objects.
753
754 template<int size, bool big_endian>
755 uint64_t
756 Sized_pluginobj<size, big_endian>::do_section_addralign(unsigned int)
757 {
758   gold_unreachable();
759   return 0;
760 }
761
762 // Return the Xindex structure to use.  Not used for plugin objects.
763
764 template<int size, bool big_endian>
765 Xindex*
766 Sized_pluginobj<size, big_endian>::do_initialize_xindex()
767 {
768   gold_unreachable();
769   return NULL;
770 }
771
772 // Get symbol counts.  Not used for plugin objects.
773
774 template<int size, bool big_endian>
775 void
776 Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(const Symbol_table*,
777                                                    size_t*, size_t*) const
778 {
779   gold_unreachable();
780 }
781
782 // Class Plugin_finish.  This task runs after all replacement files have
783 // been added.  It calls each plugin's cleanup handler.
784
785 class Plugin_finish : public Task
786 {
787  public:
788   Plugin_finish(Task_token* this_blocker, Task_token* next_blocker)
789     : this_blocker_(this_blocker), next_blocker_(next_blocker)
790   { }
791
792   ~Plugin_finish()
793   {
794     if (this->this_blocker_ != NULL)
795       delete this->this_blocker_;
796   }
797
798   Task_token*
799   is_runnable()
800   {
801     if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
802       return this->this_blocker_;
803     return NULL;
804   }
805
806   void
807   locks(Task_locker* tl)
808   { tl->add(this, this->next_blocker_); }
809
810   void
811   run(Workqueue*)
812   {
813     Plugin_manager* plugins = parameters->options().plugins();
814     gold_assert(plugins != NULL);
815     plugins->cleanup();
816   }
817
818   std::string
819   get_name() const
820   { return "Plugin_finish"; }
821
822  private:
823   Task_token* this_blocker_;
824   Task_token* next_blocker_;
825 };
826
827 // Class Plugin_hook.
828
829 Plugin_hook::~Plugin_hook()
830 {
831 }
832
833 // Return whether a Plugin_hook task is runnable.
834
835 Task_token*
836 Plugin_hook::is_runnable()
837 {
838   if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
839     return this->this_blocker_;
840   return NULL;
841 }
842
843 // Return a Task_locker for a Plugin_hook task.  We don't need any
844 // locks here.
845
846 void
847 Plugin_hook::locks(Task_locker*)
848 {
849 }
850
851 // Run the "all symbols read" plugin hook.
852
853 void
854 Plugin_hook::run(Workqueue* workqueue)
855 {
856   gold_assert(this->options_.has_plugins());
857   this->options_.plugins()->all_symbols_read(workqueue,
858                                              this,
859                                              this->input_objects_,
860                                              this->symtab_,
861                                              this->layout_,
862                                              this->dirpath_,
863                                              this->mapfile_,
864                                              &this->this_blocker_);
865   workqueue->queue_soon(new Plugin_finish(this->this_blocker_,
866                                           this->next_blocker_));
867 }
868
869 // The C interface routines called by the plugins.
870
871 #ifdef ENABLE_PLUGINS
872
873 // Register a claim-file handler.
874
875 static enum ld_plugin_status
876 register_claim_file(ld_plugin_claim_file_handler handler)
877 {
878   gold_assert(parameters->options().has_plugins());
879   parameters->options().plugins()->set_claim_file_handler(handler);
880   return LDPS_OK;
881 }
882
883 // Register an all-symbols-read handler.
884
885 static enum ld_plugin_status
886 register_all_symbols_read(ld_plugin_all_symbols_read_handler handler)
887 {
888   gold_assert(parameters->options().has_plugins());
889   parameters->options().plugins()->set_all_symbols_read_handler(handler);
890   return LDPS_OK;
891 }
892
893 // Register a cleanup handler.
894
895 static enum ld_plugin_status
896 register_cleanup(ld_plugin_cleanup_handler handler)
897 {
898   gold_assert(parameters->options().has_plugins());
899   parameters->options().plugins()->set_cleanup_handler(handler);
900   return LDPS_OK;
901 }
902
903 // Add symbols from a plugin-claimed input file.
904
905 static enum ld_plugin_status
906 add_symbols(void* handle, int nsyms, const ld_plugin_symbol *syms)
907 {
908   gold_assert(parameters->options().has_plugins());
909   Pluginobj* obj = parameters->options().plugins()->make_plugin_object(
910       static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
911   if (obj == NULL)
912     return LDPS_ERR;
913   obj->store_incoming_symbols(nsyms, syms);
914   return LDPS_OK;
915 }
916
917 // Get the input file information with an open (possibly re-opened)
918 // file descriptor.
919
920 static enum ld_plugin_status
921 get_input_file(const void *handle, struct ld_plugin_input_file *file)
922 {
923   gold_assert(parameters->options().has_plugins());
924   unsigned int obj_index =
925       static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
926   return parameters->options().plugins()->get_input_file(obj_index, file);
927 }
928
929 // Release the input file.
930
931 static enum ld_plugin_status
932 release_input_file(const void *handle)
933 {
934   gold_assert(parameters->options().has_plugins());
935   unsigned int obj_index =
936       static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
937   return parameters->options().plugins()->release_input_file(obj_index);
938 }
939
940 // Get the symbol resolution info for a plugin-claimed input file.
941
942 static enum ld_plugin_status
943 get_symbols(const void * handle, int nsyms, ld_plugin_symbol* syms)
944 {
945   gold_assert(parameters->options().has_plugins());
946   Pluginobj* obj = parameters->options().plugins()->object(
947       static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
948   if (obj == NULL)
949     return LDPS_ERR;
950   return obj->get_symbol_resolution_info(nsyms, syms);
951 }
952
953 // Add a new (real) input file generated by a plugin.
954
955 static enum ld_plugin_status
956 add_input_file(char *pathname)
957 {
958   gold_assert(parameters->options().has_plugins());
959   return parameters->options().plugins()->add_input_file(pathname, false);
960 }
961
962 // Add a new (real) library required by a plugin.
963
964 static enum ld_plugin_status
965 add_input_library(char *pathname)
966 {
967   gold_assert(parameters->options().has_plugins());
968   return parameters->options().plugins()->add_input_file(pathname, true);
969 }
970
971 // Issue a diagnostic message from a plugin.
972
973 static enum ld_plugin_status
974 message(int level, const char * format, ...)
975 {
976   va_list args;
977   va_start(args, format);
978
979   switch (level)
980     {
981     case LDPL_INFO:
982       parameters->errors()->info(format, args);
983       break;
984     case LDPL_WARNING:
985       parameters->errors()->warning(format, args);
986       break;
987     case LDPL_ERROR:
988     default:
989       parameters->errors()->error(format, args);
990       break;
991     case LDPL_FATAL:
992       parameters->errors()->fatal(format, args);
993       break;
994     }
995
996   va_end(args);
997   return LDPS_OK;
998 }
999
1000 #endif // ENABLE_PLUGINS
1001
1002 // Allocate a Pluginobj object of the appropriate size and endianness.
1003
1004 static Pluginobj*
1005 make_sized_plugin_object(Input_file* input_file, off_t offset, off_t filesize)
1006 {
1007   Pluginobj* obj = NULL;
1008
1009   parameters_force_valid_target();
1010   const Target& target(parameters->target());
1011
1012   if (target.get_size() == 32)
1013     {
1014       if (target.is_big_endian())
1015 #ifdef HAVE_TARGET_32_BIG
1016         obj = new Sized_pluginobj<32, true>(input_file->filename(),
1017                                             input_file, offset, filesize);
1018 #else
1019         gold_error(_("%s: not configured to support "
1020                      "32-bit big-endian object"),
1021                    input_file->filename().c_str());
1022 #endif
1023       else
1024 #ifdef HAVE_TARGET_32_LITTLE
1025         obj = new Sized_pluginobj<32, false>(input_file->filename(),
1026                                              input_file, offset, filesize);
1027 #else
1028         gold_error(_("%s: not configured to support "
1029                      "32-bit little-endian object"),
1030                    input_file->filename().c_str());
1031 #endif
1032     }
1033   else if (target.get_size() == 64)
1034     {
1035       if (target.is_big_endian())
1036 #ifdef HAVE_TARGET_64_BIG
1037         obj = new Sized_pluginobj<64, true>(input_file->filename(),
1038                                             input_file, offset, filesize);
1039 #else
1040         gold_error(_("%s: not configured to support "
1041                      "64-bit big-endian object"),
1042                    input_file->filename().c_str());
1043 #endif
1044       else
1045 #ifdef HAVE_TARGET_64_LITTLE
1046         obj = new Sized_pluginobj<64, false>(input_file->filename(),
1047                                              input_file, offset, filesize);
1048 #else
1049         gold_error(_("%s: not configured to support "
1050                      "64-bit little-endian object"),
1051                    input_file->filename().c_str());
1052 #endif
1053     }
1054
1055   gold_assert(obj != NULL);
1056   return obj;
1057 }
1058
1059 } // End namespace gold.