* Makefile.am: Remove spurious sanitization marker.
[binutils.git] / gold / plugin.cc
blobed334ab8ee7227819fd7b16a351826d4cc4f08da
1 // plugin.cc -- plugin manager for gold -*- C++ -*-
3 // Copyright 2008, 2009 Free Software Foundation, Inc.
4 // Written by Cary Coutant <ccoutant@google.com>.
6 // This file is part of gold.
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.
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.
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.
23 #include "gold.h"
25 #include <cstdio>
26 #include <cstdarg>
27 #include <cstring>
28 #include <string>
29 #include <vector>
31 #ifdef ENABLE_PLUGINS
32 #include <dlfcn.h>
33 #endif
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"
46 namespace gold
49 #ifdef ENABLE_PLUGINS
51 // The linker's exported interfaces.
53 extern "C"
56 static enum ld_plugin_status
57 register_claim_file(ld_plugin_claim_file_handler handler);
59 static enum ld_plugin_status
60 register_all_symbols_read(ld_plugin_all_symbols_read_handler handler);
62 static enum ld_plugin_status
63 register_cleanup(ld_plugin_cleanup_handler handler);
65 static enum ld_plugin_status
66 add_symbols(void *handle, int nsyms, const struct ld_plugin_symbol *syms);
68 static enum ld_plugin_status
69 get_input_file(const void *handle, struct ld_plugin_input_file *file);
71 static enum ld_plugin_status
72 release_input_file(const void *handle);
74 static enum ld_plugin_status
75 get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms);
77 static enum ld_plugin_status
78 add_input_file(char *pathname);
80 static enum ld_plugin_status
81 add_input_library(char *pathname);
83 static enum ld_plugin_status
84 message(int level, const char *format, ...);
88 #endif // ENABLE_PLUGINS
90 static Pluginobj* make_sized_plugin_object(Input_file* input_file,
91 off_t offset, off_t filesize);
93 // Plugin methods.
95 // Load one plugin library.
97 void
98 Plugin::load()
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)
106 gold_error(_("%s: could not load plugin library"),
107 this->filename_.c_str());
108 return;
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)
116 gold_error(_("%s: could not find onload entry point"),
117 this->filename_.c_str());
118 return;
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);
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];
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;
138 ++i;
139 tv[i].tv_tag = LDPT_API_VERSION;
140 tv[i].tv_u.tv_val = LD_PLUGIN_API_VERSION;
142 ++i;
143 tv[i].tv_tag = LDPT_GOLD_VERSION;
144 tv[i].tv_u.tv_val = major * 100 + minor;
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;
155 for (unsigned int j = 0; j < this->args_.size(); ++j)
157 ++i;
158 tv[i].tv_tag = LDPT_OPTION;
159 tv[i].tv_u.tv_string = this->args_[j].c_str();
162 ++i;
163 tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK;
164 tv[i].tv_u.tv_register_claim_file = register_claim_file;
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;
170 ++i;
171 tv[i].tv_tag = LDPT_REGISTER_CLEANUP_HOOK;
172 tv[i].tv_u.tv_register_cleanup = register_cleanup;
174 ++i;
175 tv[i].tv_tag = LDPT_ADD_SYMBOLS;
176 tv[i].tv_u.tv_add_symbols = add_symbols;
178 ++i;
179 tv[i].tv_tag = LDPT_GET_INPUT_FILE;
180 tv[i].tv_u.tv_get_input_file = get_input_file;
182 ++i;
183 tv[i].tv_tag = LDPT_RELEASE_INPUT_FILE;
184 tv[i].tv_u.tv_release_input_file = release_input_file;
186 ++i;
187 tv[i].tv_tag = LDPT_GET_SYMBOLS;
188 tv[i].tv_u.tv_get_symbols = get_symbols;
190 ++i;
191 tv[i].tv_tag = LDPT_ADD_INPUT_FILE;
192 tv[i].tv_u.tv_add_input_file = add_input_file;
194 ++i;
195 tv[i].tv_tag = LDPT_ADD_INPUT_LIBRARY;
196 tv[i].tv_u.tv_add_input_library = add_input_library;
198 ++i;
199 tv[i].tv_tag = LDPT_NULL;
200 tv[i].tv_u.tv_val = 0;
202 gold_assert(i == tv_size - 1);
204 // Call the onload entry point.
205 (*onload)(tv);
207 delete[] tv;
208 #endif // ENABLE_PLUGINS
211 // Call the plugin claim-file handler.
213 inline bool
214 Plugin::claim_file(struct ld_plugin_input_file *plugin_input_file)
216 int claimed = 0;
218 if (this->claim_file_handler_ != NULL)
220 (*this->claim_file_handler_)(plugin_input_file, &claimed);
221 if (claimed)
222 return true;
224 return false;
227 // Call the all-symbols-read handler.
229 inline void
230 Plugin::all_symbols_read()
232 if (this->all_symbols_read_handler_ != NULL)
233 (*this->all_symbols_read_handler_)();
236 // Call the cleanup handler.
238 inline void
239 Plugin::cleanup()
241 if (this->cleanup_handler_ != NULL)
242 (*this->cleanup_handler_)();
245 // Plugin_manager methods.
247 Plugin_manager::~Plugin_manager()
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();
261 // Load all plugin libraries.
263 void
264 Plugin_manager::load_plugins()
266 for (this->current_ = this->plugins_.begin();
267 this->current_ != this->plugins_.end();
268 ++this->current_)
269 (*this->current_)->load();
272 // Call the plugin claim-file handlers in turn to see if any claim the file.
274 Pluginobj*
275 Plugin_manager::claim_file(Input_file* input_file, off_t offset,
276 off_t filesize)
278 if (this->in_replacement_phase_)
279 return NULL;
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);
289 for (this->current_ = this->plugins_.begin();
290 this->current_ != this->plugins_.end();
291 ++this->current_)
293 if ((*this->current_)->claim_file(&this->plugin_input_file_))
295 if (this->objects_.size() > handle)
296 return this->objects_[handle];
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;
305 return NULL;
308 // Call the all-symbols-read handlers.
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)
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;
327 for (this->current_ = this->plugins_.begin();
328 this->current_ != this->plugins_.end();
329 ++this->current_)
330 (*this->current_)->all_symbols_read();
332 *last_blocker = this->this_blocker_;
335 // Layout deferred objects.
337 void
338 Plugin_manager::layout_deferred_objects()
340 Deferred_layout_list::iterator obj;
342 for (obj = this->deferred_layout_objects_.begin();
343 obj != this->deferred_layout_objects_.end();
344 ++obj)
345 (*obj)->layout_deferred_sections(this->layout_);
348 // Call the cleanup handlers.
350 void
351 Plugin_manager::cleanup()
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;
362 // Make a new Pluginobj object. This is called when the plugin calls
363 // the add_symbols API.
365 Pluginobj*
366 Plugin_manager::make_plugin_object(unsigned int handle)
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;
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;
379 // Get the input file information with an open (possibly re-opened)
380 // file descriptor.
382 ld_plugin_status
383 Plugin_manager::get_input_file(unsigned int handle,
384 struct ld_plugin_input_file *file)
386 Pluginobj* obj = this->object(handle);
387 if (obj == NULL)
388 return LDPS_BAD_HANDLE;
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;
399 // Release the input file.
401 ld_plugin_status
402 Plugin_manager::release_input_file(unsigned int handle)
404 Pluginobj* obj = this->object(handle);
405 if (obj == NULL)
406 return LDPS_BAD_HANDLE;
408 obj->unlock(this->task_);
409 return LDPS_OK;
412 // Add a new input file.
414 ld_plugin_status
415 Plugin_manager::add_input_file(char *pathname, bool is_lib)
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_,
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;
442 // Class Pluginobj.
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_()
451 // Return TRUE if a defined symbol might be reachable from outside the
452 // universe of claimed objects.
454 static inline bool
455 is_visible_from_outside(Symbol* lsym)
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;
466 // Get symbol resolution info.
468 ld_plugin_status
469 Pluginobj::get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const
471 if (nsyms > this->nsyms_)
472 return LDPS_NO_SYMS;
473 for (int i = 0; i < nsyms; i++)
475 ld_plugin_symbol* isym = &syms[i];
476 Symbol* lsym = this->symbols_[i];
477 ld_plugin_symbol_resolution res = LDPR_UNKNOWN;
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)
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;
496 else
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);
510 isym->resolution = res;
512 return LDPS_OK;
515 // Return TRUE if the comdat group with key COMDAT_KEY from this object
516 // should be kept.
518 bool
519 Pluginobj::include_comdat_group(std::string comdat_key, Layout* layout)
521 std::pair<Comdat_map::iterator, bool> ins =
522 this->comdat_map_.insert(std::make_pair(comdat_key, false));
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);
531 return ins.first->second;
534 // Class Sized_pluginobj.
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)
546 // Read the symbols. Not used for plugin objects.
548 template<int size, bool big_endian>
549 void
550 Sized_pluginobj<size, big_endian>::do_read_symbols(Read_symbols_data*)
552 gold_unreachable();
555 // Lay out the input sections. Not used for plugin objects.
557 template<int size, bool big_endian>
558 void
559 Sized_pluginobj<size, big_endian>::do_layout(Symbol_table*, Layout*,
560 Read_symbols_data*)
562 gold_unreachable();
565 // Add the symbols to the symbol table.
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)
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);
578 typedef typename elfcpp::Elf_types<size>::Elf_WXword Elf_size_type;
580 this->symbols_.resize(this->nsyms_);
582 for (int i = 0; i < this->nsyms_; ++i)
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;
591 if (name != NULL && name[0] == '\0')
592 name = NULL;
593 if (ver != NULL && ver[0] == '\0')
594 ver = NULL;
596 switch (isym->def)
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;
610 switch (isym->def)
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;
626 switch (isym->visibility)
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;
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;
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);
655 this->symbols_[i] =
656 symtab->add_from_pluginobj<size, big_endian>(this, name, ver, &sym);
660 // Get the size of a section. Not used for plugin objects.
662 template<int size, bool big_endian>
663 uint64_t
664 Sized_pluginobj<size, big_endian>::do_section_size(unsigned int)
666 gold_unreachable();
667 return 0;
670 // Get the name of a section. Not used for plugin objects.
672 template<int size, bool big_endian>
673 std::string
674 Sized_pluginobj<size, big_endian>::do_section_name(unsigned int)
676 gold_unreachable();
677 return std::string();
680 // Return a view of the contents of a section. Not used for plugin objects.
682 template<int size, bool big_endian>
683 Object::Location
684 Sized_pluginobj<size, big_endian>::do_section_contents(unsigned int)
686 Location loc(0, 0);
688 gold_unreachable();
689 return loc;
692 // Return section flags. Not used for plugin objects.
694 template<int size, bool big_endian>
695 uint64_t
696 Sized_pluginobj<size, big_endian>::do_section_flags(unsigned int)
698 gold_unreachable();
699 return 0;
702 // Return section entsize. Not used for plugin objects.
704 template<int size, bool big_endian>
705 uint64_t
706 Sized_pluginobj<size, big_endian>::do_section_entsize(unsigned int)
708 gold_unreachable();
709 return 0;
712 // Return section address. Not used for plugin objects.
714 template<int size, bool big_endian>
715 uint64_t
716 Sized_pluginobj<size, big_endian>::do_section_address(unsigned int)
718 gold_unreachable();
719 return 0;
722 // Return section type. Not used for plugin objects.
724 template<int size, bool big_endian>
725 unsigned int
726 Sized_pluginobj<size, big_endian>::do_section_type(unsigned int)
728 gold_unreachable();
729 return 0;
732 // Return the section link field. Not used for plugin objects.
734 template<int size, bool big_endian>
735 unsigned int
736 Sized_pluginobj<size, big_endian>::do_section_link(unsigned int)
738 gold_unreachable();
739 return 0;
742 // Return the section link field. Not used for plugin objects.
744 template<int size, bool big_endian>
745 unsigned int
746 Sized_pluginobj<size, big_endian>::do_section_info(unsigned int)
748 gold_unreachable();
749 return 0;
752 // Return the section alignment. Not used for plugin objects.
754 template<int size, bool big_endian>
755 uint64_t
756 Sized_pluginobj<size, big_endian>::do_section_addralign(unsigned int)
758 gold_unreachable();
759 return 0;
762 // Return the Xindex structure to use. Not used for plugin objects.
764 template<int size, bool big_endian>
765 Xindex*
766 Sized_pluginobj<size, big_endian>::do_initialize_xindex()
768 gold_unreachable();
769 return NULL;
772 // Get symbol counts. Not used for plugin objects.
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
779 gold_unreachable();
782 // Class Plugin_finish. This task runs after all replacement files have
783 // been added. It calls each plugin's cleanup handler.
785 class Plugin_finish : public Task
787 public:
788 Plugin_finish(Task_token* this_blocker, Task_token* next_blocker)
789 : this_blocker_(this_blocker), next_blocker_(next_blocker)
792 ~Plugin_finish()
794 if (this->this_blocker_ != NULL)
795 delete this->this_blocker_;
798 Task_token*
799 is_runnable()
801 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
802 return this->this_blocker_;
803 return NULL;
806 void
807 locks(Task_locker* tl)
808 { tl->add(this, this->next_blocker_); }
810 void
811 run(Workqueue*)
813 Plugin_manager* plugins = parameters->options().plugins();
814 gold_assert(plugins != NULL);
815 plugins->cleanup();
818 std::string
819 get_name() const
820 { return "Plugin_finish"; }
822 private:
823 Task_token* this_blocker_;
824 Task_token* next_blocker_;
827 // Class Plugin_hook.
829 Plugin_hook::~Plugin_hook()
833 // Return whether a Plugin_hook task is runnable.
835 Task_token*
836 Plugin_hook::is_runnable()
838 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
839 return this->this_blocker_;
840 return NULL;
843 // Return a Task_locker for a Plugin_hook task. We don't need any
844 // locks here.
846 void
847 Plugin_hook::locks(Task_locker*)
851 // Run the "all symbols read" plugin hook.
853 void
854 Plugin_hook::run(Workqueue* workqueue)
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_));
869 // The C interface routines called by the plugins.
871 #ifdef ENABLE_PLUGINS
873 // Register a claim-file handler.
875 static enum ld_plugin_status
876 register_claim_file(ld_plugin_claim_file_handler handler)
878 gold_assert(parameters->options().has_plugins());
879 parameters->options().plugins()->set_claim_file_handler(handler);
880 return LDPS_OK;
883 // Register an all-symbols-read handler.
885 static enum ld_plugin_status
886 register_all_symbols_read(ld_plugin_all_symbols_read_handler handler)
888 gold_assert(parameters->options().has_plugins());
889 parameters->options().plugins()->set_all_symbols_read_handler(handler);
890 return LDPS_OK;
893 // Register a cleanup handler.
895 static enum ld_plugin_status
896 register_cleanup(ld_plugin_cleanup_handler handler)
898 gold_assert(parameters->options().has_plugins());
899 parameters->options().plugins()->set_cleanup_handler(handler);
900 return LDPS_OK;
903 // Add symbols from a plugin-claimed input file.
905 static enum ld_plugin_status
906 add_symbols(void* handle, int nsyms, const ld_plugin_symbol *syms)
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;
917 // Get the input file information with an open (possibly re-opened)
918 // file descriptor.
920 static enum ld_plugin_status
921 get_input_file(const void *handle, struct ld_plugin_input_file *file)
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);
929 // Release the input file.
931 static enum ld_plugin_status
932 release_input_file(const void *handle)
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);
940 // Get the symbol resolution info for a plugin-claimed input file.
942 static enum ld_plugin_status
943 get_symbols(const void * handle, int nsyms, ld_plugin_symbol* syms)
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);
953 // Add a new (real) input file generated by a plugin.
955 static enum ld_plugin_status
956 add_input_file(char *pathname)
958 gold_assert(parameters->options().has_plugins());
959 return parameters->options().plugins()->add_input_file(pathname, false);
962 // Add a new (real) library required by a plugin.
964 static enum ld_plugin_status
965 add_input_library(char *pathname)
967 gold_assert(parameters->options().has_plugins());
968 return parameters->options().plugins()->add_input_file(pathname, true);
971 // Issue a diagnostic message from a plugin.
973 static enum ld_plugin_status
974 message(int level, const char * format, ...)
976 va_list args;
977 va_start(args, format);
979 switch (level)
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;
996 va_end(args);
997 return LDPS_OK;
1000 #endif // ENABLE_PLUGINS
1002 // Allocate a Pluginobj object of the appropriate size and endianness.
1004 static Pluginobj*
1005 make_sized_plugin_object(Input_file* input_file, off_t offset, off_t filesize)
1007 Pluginobj* obj = NULL;
1009 parameters_force_valid_target();
1010 const Target& target(parameters->target());
1012 if (target.get_size() == 32)
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
1033 else if (target.get_size() == 64)
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
1055 gold_assert(obj != NULL);
1056 return obj;
1059 } // End namespace gold.