Add sparc integer multiply-add instructions.
[deliverable/binutils-gdb.git] / gold / plugin.cc
CommitLineData
6d03d481 1// plugin.cc -- plugin manager for gold -*- C++ -*-
89fc3421 2
0f3b89d8 3// Copyright 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
89fc3421
CC
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
1c7814ed
ILT
23#include "gold.h"
24
89fc3421
CC
25#include <cstdio>
26#include <cstdarg>
27#include <cstring>
28#include <string>
29#include <vector>
bc06c745
ILT
30
31#ifdef ENABLE_PLUGINS
89fc3421 32#include <dlfcn.h>
bc06c745 33#endif
89fc3421 34
89fc3421
CC
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
46namespace gold
47{
48
49#ifdef ENABLE_PLUGINS
50
51// The linker's exported interfaces.
52
53extern "C"
54{
55
56static enum ld_plugin_status
57register_claim_file(ld_plugin_claim_file_handler handler);
58
59static enum ld_plugin_status
60register_all_symbols_read(ld_plugin_all_symbols_read_handler handler);
61
62static enum ld_plugin_status
63register_cleanup(ld_plugin_cleanup_handler handler);
64
65static enum ld_plugin_status
66add_symbols(void *handle, int nsyms, const struct ld_plugin_symbol *syms);
67
0f7c0701
CC
68static enum ld_plugin_status
69get_input_file(const void *handle, struct ld_plugin_input_file *file);
70
9c793f14
RÁE
71static enum ld_plugin_status
72get_view(const void *handle, const void **viewp);
73
0f7c0701
CC
74static enum ld_plugin_status
75release_input_file(const void *handle);
76
89fc3421
CC
77static enum ld_plugin_status
78get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms);
79
80static enum ld_plugin_status
6508b958 81add_input_file(const char *pathname);
89fc3421 82
e99daf92 83static enum ld_plugin_status
6508b958 84add_input_library(const char *pathname);
e99daf92 85
42218b9f
RÁE
86static enum ld_plugin_status
87set_extra_library_path(const char *path);
88
89fc3421 89static enum ld_plugin_status
6c52134c 90message(int level, const char *format, ...);
89fc3421 91
e9552f7e
ST
92static enum ld_plugin_status
93get_input_section_count(const void* handle, unsigned int* count);
94
95static enum ld_plugin_status
96get_input_section_type(const struct ld_plugin_section section,
97 unsigned int* type);
98
99static enum ld_plugin_status
100get_input_section_name(const struct ld_plugin_section section,
101 char** section_name_ptr);
102
103static enum ld_plugin_status
104get_input_section_contents(const struct ld_plugin_section section,
105 const unsigned char** section_contents,
106 size_t* len);
107
108static enum ld_plugin_status
109update_section_order(const struct ld_plugin_section *section_list,
110 unsigned int num_sections);
111
112static enum ld_plugin_status
113allow_section_ordering();
114
89fc3421
CC
115};
116
117#endif // ENABLE_PLUGINS
118
119static Pluginobj* make_sized_plugin_object(Input_file* input_file,
0f7c0701 120 off_t offset, off_t filesize);
89fc3421
CC
121
122// Plugin methods.
123
124// Load one plugin library.
125
126void
127Plugin::load()
128{
129#ifdef ENABLE_PLUGINS
89fc3421
CC
130 // Load the plugin library.
131 // FIXME: Look for the library in standard locations.
4674ecfc 132 this->handle_ = dlopen(this->filename_.c_str(), RTLD_NOW);
89fc3421
CC
133 if (this->handle_ == NULL)
134 {
4802450a
RÁE
135 gold_error(_("%s: could not load plugin library: %s"),
136 this->filename_.c_str(), dlerror());
89fc3421
CC
137 return;
138 }
139
140 // Find the plugin's onload entry point.
b59befec
ILT
141 void* ptr = dlsym(this->handle_, "onload");
142 if (ptr == NULL)
89fc3421 143 {
4674ecfc
CC
144 gold_error(_("%s: could not find onload entry point"),
145 this->filename_.c_str());
89fc3421
CC
146 return;
147 }
b59befec
ILT
148 ld_plugin_onload onload;
149 gold_assert(sizeof(onload) == sizeof(ptr));
150 memcpy(&onload, &ptr, sizeof(ptr));
89fc3421
CC
151
152 // Get the linker's version number.
153 const char* ver = get_version_string();
154 int major = 0;
155 int minor = 0;
156 sscanf(ver, "%d.%d", &major, &minor);
157
158 // Allocate and populate a transfer vector.
e9552f7e
ST
159 const int tv_fixed_size = 23;
160
4674ecfc 161 int tv_size = this->args_.size() + tv_fixed_size;
ca09d69a 162 ld_plugin_tv* tv = new ld_plugin_tv[tv_size];
89fc3421 163
abc8dcba
CC
164 // Put LDPT_MESSAGE at the front of the list so the plugin can use it
165 // while processing subsequent entries.
89fc3421 166 int i = 0;
abc8dcba
CC
167 tv[i].tv_tag = LDPT_MESSAGE;
168 tv[i].tv_u.tv_message = message;
169
170 ++i;
89fc3421
CC
171 tv[i].tv_tag = LDPT_API_VERSION;
172 tv[i].tv_u.tv_val = LD_PLUGIN_API_VERSION;
173
174 ++i;
175 tv[i].tv_tag = LDPT_GOLD_VERSION;
176 tv[i].tv_u.tv_val = major * 100 + minor;
177
178 ++i;
179 tv[i].tv_tag = LDPT_LINKER_OUTPUT;
180 if (parameters->options().relocatable())
181 tv[i].tv_u.tv_val = LDPO_REL;
182 else if (parameters->options().shared())
183 tv[i].tv_u.tv_val = LDPO_DYN;
184 else
185 tv[i].tv_u.tv_val = LDPO_EXEC;
186
3537c84b
RÁE
187 ++i;
188 tv[i].tv_tag = LDPT_OUTPUT_NAME;
189 tv[i].tv_u.tv_string = parameters->options().output();
190
4674ecfc 191 for (unsigned int j = 0; j < this->args_.size(); ++j)
89fc3421
CC
192 {
193 ++i;
194 tv[i].tv_tag = LDPT_OPTION;
4674ecfc 195 tv[i].tv_u.tv_string = this->args_[j].c_str();
89fc3421
CC
196 }
197
198 ++i;
199 tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK;
200 tv[i].tv_u.tv_register_claim_file = register_claim_file;
201
202 ++i;
203 tv[i].tv_tag = LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK;
204 tv[i].tv_u.tv_register_all_symbols_read = register_all_symbols_read;
205
206 ++i;
207 tv[i].tv_tag = LDPT_REGISTER_CLEANUP_HOOK;
208 tv[i].tv_u.tv_register_cleanup = register_cleanup;
209
210 ++i;
211 tv[i].tv_tag = LDPT_ADD_SYMBOLS;
212 tv[i].tv_u.tv_add_symbols = add_symbols;
213
0f7c0701
CC
214 ++i;
215 tv[i].tv_tag = LDPT_GET_INPUT_FILE;
216 tv[i].tv_u.tv_get_input_file = get_input_file;
217
9c793f14
RÁE
218 ++i;
219 tv[i].tv_tag = LDPT_GET_VIEW;
220 tv[i].tv_u.tv_get_view = get_view;
221
0f7c0701
CC
222 ++i;
223 tv[i].tv_tag = LDPT_RELEASE_INPUT_FILE;
224 tv[i].tv_u.tv_release_input_file = release_input_file;
225
89fc3421
CC
226 ++i;
227 tv[i].tv_tag = LDPT_GET_SYMBOLS;
228 tv[i].tv_u.tv_get_symbols = get_symbols;
229
230 ++i;
231 tv[i].tv_tag = LDPT_ADD_INPUT_FILE;
232 tv[i].tv_u.tv_add_input_file = add_input_file;
233
e99daf92
ILT
234 ++i;
235 tv[i].tv_tag = LDPT_ADD_INPUT_LIBRARY;
236 tv[i].tv_u.tv_add_input_library = add_input_library;
237
42218b9f
RÁE
238 ++i;
239 tv[i].tv_tag = LDPT_SET_EXTRA_LIBRARY_PATH;
240 tv[i].tv_u.tv_set_extra_library_path = set_extra_library_path;
241
e9552f7e
ST
242 ++i;
243 tv[i].tv_tag = LDPT_GET_INPUT_SECTION_COUNT;
244 tv[i].tv_u.tv_get_input_section_count = get_input_section_count;
245
246 ++i;
247 tv[i].tv_tag = LDPT_GET_INPUT_SECTION_TYPE;
248 tv[i].tv_u.tv_get_input_section_type = get_input_section_type;
249
250 ++i;
251 tv[i].tv_tag = LDPT_GET_INPUT_SECTION_NAME;
252 tv[i].tv_u.tv_get_input_section_name = get_input_section_name;
253
254 ++i;
255 tv[i].tv_tag = LDPT_GET_INPUT_SECTION_CONTENTS;
256 tv[i].tv_u.tv_get_input_section_contents = get_input_section_contents;
257
258 ++i;
259 tv[i].tv_tag = LDPT_UPDATE_SECTION_ORDER;
260 tv[i].tv_u.tv_update_section_order = update_section_order;
261
262 ++i;
263 tv[i].tv_tag = LDPT_ALLOW_SECTION_ORDERING;
264 tv[i].tv_u.tv_allow_section_ordering = allow_section_ordering;
265
89fc3421
CC
266 ++i;
267 tv[i].tv_tag = LDPT_NULL;
268 tv[i].tv_u.tv_val = 0;
269
270 gold_assert(i == tv_size - 1);
271
272 // Call the onload entry point.
273 (*onload)(tv);
274
6c52134c 275 delete[] tv;
89fc3421
CC
276#endif // ENABLE_PLUGINS
277}
278
279// Call the plugin claim-file handler.
280
281inline bool
ca09d69a 282Plugin::claim_file(struct ld_plugin_input_file* plugin_input_file)
89fc3421
CC
283{
284 int claimed = 0;
285
286 if (this->claim_file_handler_ != NULL)
287 {
288 (*this->claim_file_handler_)(plugin_input_file, &claimed);
289 if (claimed)
290 return true;
291 }
292 return false;
293}
294
295// Call the all-symbols-read handler.
296
297inline void
298Plugin::all_symbols_read()
299{
300 if (this->all_symbols_read_handler_ != NULL)
301 (*this->all_symbols_read_handler_)();
302}
303
304// Call the cleanup handler.
305
306inline void
307Plugin::cleanup()
308{
40f36857
CC
309 if (this->cleanup_handler_ != NULL && !this->cleanup_done_)
310 {
311 // Set this flag before calling to prevent a recursive plunge
312 // in the event that a plugin's cleanup handler issues a
313 // fatal error.
314 this->cleanup_done_ = true;
315 (*this->cleanup_handler_)();
316 }
89fc3421
CC
317}
318
0f3b89d8
ILT
319// This task is used to rescan archives as needed.
320
321class Plugin_rescan : public Task
322{
323 public:
324 Plugin_rescan(Task_token* this_blocker, Task_token* next_blocker)
325 : this_blocker_(this_blocker), next_blocker_(next_blocker)
326 { }
327
328 ~Plugin_rescan()
329 {
330 delete this->this_blocker_;
331 }
332
333 Task_token*
334 is_runnable()
335 {
336 if (this->this_blocker_->is_blocked())
337 return this->this_blocker_;
338 return NULL;
339 }
340
341 void
342 locks(Task_locker* tl)
343 { tl->add(this, this->next_blocker_); }
344
345 void
346 run(Workqueue*)
347 { parameters->options().plugins()->rescan(this); }
348
349 std::string
350 get_name() const
351 { return "Plugin_rescan"; }
352
353 private:
354 Task_token* this_blocker_;
355 Task_token* next_blocker_;
356};
357
89fc3421
CC
358// Plugin_manager methods.
359
360Plugin_manager::~Plugin_manager()
361{
362 for (Plugin_list::iterator p = this->plugins_.begin();
363 p != this->plugins_.end();
364 ++p)
365 delete *p;
366 this->plugins_.clear();
367 for (Object_list::iterator obj = this->objects_.begin();
368 obj != this->objects_.end();
369 ++obj)
370 delete *obj;
371 this->objects_.clear();
372}
373
374// Load all plugin libraries.
375
376void
e9552f7e 377Plugin_manager::load_plugins(Layout* layout)
89fc3421 378{
e9552f7e 379 this->layout_ = layout;
89fc3421
CC
380 for (this->current_ = this->plugins_.begin();
381 this->current_ != this->plugins_.end();
382 ++this->current_)
383 (*this->current_)->load();
384}
385
386// Call the plugin claim-file handlers in turn to see if any claim the file.
387
388Pluginobj*
389Plugin_manager::claim_file(Input_file* input_file, off_t offset,
e9552f7e 390 off_t filesize, Object* elf_object)
89fc3421
CC
391{
392 if (this->in_replacement_phase_)
393 return NULL;
394
395 unsigned int handle = this->objects_.size();
396 this->input_file_ = input_file;
397 this->plugin_input_file_.name = input_file->filename().c_str();
398 this->plugin_input_file_.fd = input_file->file().descriptor();
399 this->plugin_input_file_.offset = offset;
400 this->plugin_input_file_.filesize = filesize;
401 this->plugin_input_file_.handle = reinterpret_cast<void*>(handle);
e9552f7e
ST
402 if (elf_object != NULL)
403 this->objects_.push_back(elf_object);
404 this->in_claim_file_handler_ = true;
89fc3421
CC
405
406 for (this->current_ = this->plugins_.begin();
407 this->current_ != this->plugins_.end();
408 ++this->current_)
409 {
410 if ((*this->current_)->claim_file(&this->plugin_input_file_))
411 {
0f3b89d8 412 this->any_claimed_ = true;
e9552f7e 413 this->in_claim_file_handler_ = false;
0f3b89d8 414
e9552f7e
ST
415 if (this->objects_.size() > handle
416 && this->objects_[handle]->pluginobj() != NULL)
417 return this->objects_[handle]->pluginobj();
abc8dcba
CC
418
419 // If the plugin claimed the file but did not call the
420 // add_symbols callback, we need to create the Pluginobj now.
421 Pluginobj* obj = this->make_plugin_object(handle);
422 return obj;
89fc3421
CC
423 }
424 }
425
e9552f7e 426 this->in_claim_file_handler_ = false;
89fc3421
CC
427 return NULL;
428}
429
0f3b89d8
ILT
430// Save an archive. This is used so that a plugin can add a file
431// which refers to a symbol which was not previously referenced. In
432// that case we want to pretend that the symbol was referenced before,
433// and pull in the archive object.
434
435void
436Plugin_manager::save_archive(Archive* archive)
437{
438 if (this->in_replacement_phase_ || !this->any_claimed_)
439 delete archive;
440 else
441 this->rescannable_.push_back(Rescannable(archive));
442}
443
444// Save an Input_group. This is like save_archive.
445
446void
447Plugin_manager::save_input_group(Input_group* input_group)
448{
449 if (this->in_replacement_phase_ || !this->any_claimed_)
450 delete input_group;
451 else
452 this->rescannable_.push_back(Rescannable(input_group));
453}
454
89fc3421
CC
455// Call the all-symbols-read handlers.
456
457void
0f7c0701 458Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
89fc3421 459 Input_objects* input_objects,
e9552f7e 460 Symbol_table* symtab,
89fc3421
CC
461 Dirsearch* dirpath, Mapfile* mapfile,
462 Task_token** last_blocker)
463{
464 this->in_replacement_phase_ = true;
465 this->workqueue_ = workqueue;
0f7c0701 466 this->task_ = task;
89fc3421
CC
467 this->input_objects_ = input_objects;
468 this->symtab_ = symtab;
89fc3421
CC
469 this->dirpath_ = dirpath;
470 this->mapfile_ = mapfile;
471 this->this_blocker_ = NULL;
472
473 for (this->current_ = this->plugins_.begin();
474 this->current_ != this->plugins_.end();
475 ++this->current_)
476 (*this->current_)->all_symbols_read();
477
0f3b89d8
ILT
478 if (this->any_added_)
479 {
480 Task_token* next_blocker = new Task_token(true);
481 next_blocker->add_blocker();
482 workqueue->queue(new Plugin_rescan(this->this_blocker_, next_blocker));
483 this->this_blocker_ = next_blocker;
484 }
485
89fc3421
CC
486 *last_blocker = this->this_blocker_;
487}
488
0f3b89d8
ILT
489// This is called when we see a new undefined symbol. If we are in
490// the replacement phase, this means that we may need to rescan some
491// archives we have previously seen.
492
493void
494Plugin_manager::new_undefined_symbol(Symbol* sym)
495{
496 if (this->in_replacement_phase_)
497 this->undefined_symbols_.push_back(sym);
498}
499
500// Rescan archives as needed. This handles the case where a new
501// object file added by a plugin has an undefined reference to some
502// symbol defined in an archive.
503
504void
505Plugin_manager::rescan(Task* task)
506{
507 size_t rescan_pos = 0;
508 size_t rescan_size = this->rescannable_.size();
509 while (!this->undefined_symbols_.empty())
510 {
511 if (rescan_pos >= rescan_size)
512 {
513 this->undefined_symbols_.clear();
514 return;
515 }
516
517 Undefined_symbol_list undefs;
518 undefs.reserve(this->undefined_symbols_.size());
519 this->undefined_symbols_.swap(undefs);
520
521 size_t min_rescan_pos = rescan_size;
522
523 for (Undefined_symbol_list::const_iterator p = undefs.begin();
524 p != undefs.end();
525 ++p)
526 {
527 if (!(*p)->is_undefined())
528 continue;
529
530 this->undefined_symbols_.push_back(*p);
531
532 // Find the first rescan archive which defines this symbol,
533 // starting at the current rescan position. The rescan position
534 // exists so that given -la -lb -lc we don't look for undefined
535 // symbols in -lb back in -la, but instead get the definition
536 // from -lc. Don't bother to look past the current minimum
537 // rescan position.
538 for (size_t i = rescan_pos; i < min_rescan_pos; ++i)
539 {
540 if (this->rescannable_defines(i, *p))
541 {
542 min_rescan_pos = i;
543 break;
544 }
545 }
546 }
547
548 if (min_rescan_pos >= rescan_size)
549 {
550 // We didn't find any rescannable archives which define any
551 // undefined symbols.
552 return;
553 }
554
555 const Rescannable& r(this->rescannable_[min_rescan_pos]);
556 if (r.is_archive)
557 {
558 Task_lock_obj<Archive> tl(task, r.u.archive);
559 r.u.archive->add_symbols(this->symtab_, this->layout_,
560 this->input_objects_, this->mapfile_);
561 }
562 else
563 {
564 size_t next_saw_undefined = this->symtab_->saw_undefined();
565 size_t saw_undefined;
566 do
567 {
568 saw_undefined = next_saw_undefined;
569
570 for (Input_group::const_iterator p = r.u.input_group->begin();
571 p != r.u.input_group->end();
572 ++p)
573 {
574 Task_lock_obj<Archive> tl(task, *p);
575
576 (*p)->add_symbols(this->symtab_, this->layout_,
577 this->input_objects_, this->mapfile_);
578 }
579
580 next_saw_undefined = this->symtab_->saw_undefined();
581 }
582 while (saw_undefined != next_saw_undefined);
583 }
584
585 for (size_t i = rescan_pos; i < min_rescan_pos + 1; ++i)
586 {
587 if (this->rescannable_[i].is_archive)
588 delete this->rescannable_[i].u.archive;
589 else
590 delete this->rescannable_[i].u.input_group;
591 }
592
593 rescan_pos = min_rescan_pos + 1;
594 }
595}
596
597// Return whether the rescannable at index I defines SYM.
598
599bool
600Plugin_manager::rescannable_defines(size_t i, Symbol* sym)
601{
602 const Rescannable& r(this->rescannable_[i]);
603 if (r.is_archive)
604 return r.u.archive->defines_symbol(sym);
605 else
606 {
607 for (Input_group::const_iterator p = r.u.input_group->begin();
608 p != r.u.input_group->end();
609 ++p)
610 {
611 if ((*p)->defines_symbol(sym))
612 return true;
613 }
614 return false;
615 }
616}
617
483620e8 618// Layout deferred objects.
89fc3421
CC
619
620void
483620e8 621Plugin_manager::layout_deferred_objects()
89fc3421 622{
5995b570
CC
623 Deferred_layout_list::iterator obj;
624
625 for (obj = this->deferred_layout_objects_.begin();
626 obj != this->deferred_layout_objects_.end();
627 ++obj)
5f9bcf58
CC
628 {
629 // Lock the object so we can read from it. This is only called
630 // single-threaded from queue_middle_tasks, so it is OK to lock.
631 // Unfortunately we have no way to pass in a Task token.
632 const Task* dummy_task = reinterpret_cast<const Task*>(-1);
633 Task_lock_obj<Object> tl(dummy_task, *obj);
634 (*obj)->layout_deferred_sections(this->layout_);
635 }
483620e8
CC
636}
637
638// Call the cleanup handlers.
5995b570 639
483620e8
CC
640void
641Plugin_manager::cleanup()
642{
89fc3421
CC
643 for (this->current_ = this->plugins_.begin();
644 this->current_ != this->plugins_.end();
645 ++this->current_)
646 (*this->current_)->cleanup();
647}
648
649// Make a new Pluginobj object. This is called when the plugin calls
650// the add_symbols API.
651
652Pluginobj*
653Plugin_manager::make_plugin_object(unsigned int handle)
654{
655 // Make sure we aren't asked to make an object for the same handle twice.
e9552f7e
ST
656 if (this->objects_.size() != handle
657 && this->objects_[handle]->pluginobj() != NULL)
89fc3421
CC
658 return NULL;
659
660 Pluginobj* obj = make_sized_plugin_object(this->input_file_,
0f7c0701
CC
661 this->plugin_input_file_.offset,
662 this->plugin_input_file_.filesize);
e9552f7e
ST
663
664
665 // If the elf object for this file was pushed into the objects_ vector, delete
666 // it to make room for the Pluginobj as this file is claimed.
667 if (this->objects_.size() != handle)
668 this->objects_.pop_back();
669
89fc3421
CC
670 this->objects_.push_back(obj);
671 return obj;
672}
673
0f7c0701
CC
674// Get the input file information with an open (possibly re-opened)
675// file descriptor.
676
677ld_plugin_status
678Plugin_manager::get_input_file(unsigned int handle,
ca09d69a 679 struct ld_plugin_input_file* file)
0f7c0701 680{
e9552f7e 681 Pluginobj* obj = this->object(handle)->pluginobj();
0f7c0701
CC
682 if (obj == NULL)
683 return LDPS_BAD_HANDLE;
684
685 obj->lock(this->task_);
686 file->name = obj->filename().c_str();
687 file->fd = obj->descriptor();
688 file->offset = obj->offset();
689 file->filesize = obj->filesize();
690 file->handle = reinterpret_cast<void*>(handle);
691 return LDPS_OK;
692}
693
694// Release the input file.
695
696ld_plugin_status
697Plugin_manager::release_input_file(unsigned int handle)
698{
e9552f7e
ST
699 if (this->object(handle) == NULL)
700 return LDPS_BAD_HANDLE;
701
702 Pluginobj* obj = this->object(handle)->pluginobj();
703
0f7c0701
CC
704 if (obj == NULL)
705 return LDPS_BAD_HANDLE;
706
707 obj->unlock(this->task_);
708 return LDPS_OK;
709}
710
e9552f7e
ST
711// Get the elf object corresponding to the handle. Return NULL if we
712// found a Pluginobj instead.
713
714Object*
715Plugin_manager::get_elf_object(const void* handle)
716{
717 Object* obj = this->object(
718 static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
719
720 // The object should not be a Pluginobj.
721 if (obj == NULL
722 || obj->pluginobj() != NULL)
723 return NULL;
724
725 return obj;
726}
727
9c793f14
RÁE
728ld_plugin_status
729Plugin_manager::get_view(unsigned int handle, const void **viewp)
730{
731 off_t offset;
732 size_t filesize;
733 Input_file *input_file;
e9552f7e 734 if (this->in_claim_file_handler_)
9c793f14
RÁE
735 {
736 // We are being called from the claim_file hook.
737 const struct ld_plugin_input_file &f = this->plugin_input_file_;
738 offset = f.offset;
739 filesize = f.filesize;
740 input_file = this->input_file_;
741 }
742 else
743 {
744 // An already claimed file.
e9552f7e
ST
745 if (this->object(handle) == NULL)
746 return LDPS_BAD_HANDLE;
747 Pluginobj* obj = this->object(handle)->pluginobj();
9c793f14
RÁE
748 if (obj == NULL)
749 return LDPS_BAD_HANDLE;
750 offset = obj->offset();
751 filesize = obj->filesize();
752 input_file = obj->input_file();
753 }
754 *viewp = (void*) input_file->file().get_view(offset, 0, filesize, false,
755 false);
756 return LDPS_OK;
757}
758
42218b9f
RÁE
759// Add a new library path.
760
761ld_plugin_status
ca09d69a 762Plugin_manager::set_extra_library_path(const char* path)
42218b9f
RÁE
763{
764 this->extra_search_path_ = std::string(path);
765 return LDPS_OK;
766}
767
89fc3421
CC
768// Add a new input file.
769
770ld_plugin_status
ca09d69a 771Plugin_manager::add_input_file(const char* pathname, bool is_lib)
89fc3421 772{
ae3b5189
CD
773 Input_file_argument file(pathname,
774 (is_lib
775 ? Input_file_argument::INPUT_FILE_TYPE_LIBRARY
776 : Input_file_argument::INPUT_FILE_TYPE_FILE),
42218b9f
RÁE
777 (is_lib
778 ? this->extra_search_path_.c_str()
779 : ""),
780 false,
781 this->options_);
89fc3421
CC
782 Input_argument* input_argument = new Input_argument(file);
783 Task_token* next_blocker = new Task_token(true);
784 next_blocker->add_blocker();
8c21d9d3 785 if (parameters->incremental())
40f36857
CC
786 gold_error(_("input files added by plug-ins in --incremental mode not "
787 "supported yet"));
f1ed28fb 788 this->workqueue_->queue_soon(new Read_symbols(this->input_objects_,
89fc3421
CC
789 this->symtab_,
790 this->layout_,
791 this->dirpath_,
15f8229b 792 0,
89fc3421
CC
793 this->mapfile_,
794 input_argument,
795 NULL,
b0193076 796 NULL,
89fc3421
CC
797 this->this_blocker_,
798 next_blocker));
799 this->this_blocker_ = next_blocker;
0f3b89d8 800 this->any_added_ = true;
89fc3421
CC
801 return LDPS_OK;
802}
803
804// Class Pluginobj.
805
2ea97941
ILT
806Pluginobj::Pluginobj(const std::string& name, Input_file* input_file,
807 off_t offset, off_t filesize)
808 : Object(name, input_file, false, offset),
809 nsyms_(0), syms_(NULL), symbols_(), filesize_(filesize), comdat_map_()
89fc3421
CC
810{
811}
812
d66a9eb3
CC
813// Return TRUE if a defined symbol might be reachable from outside the
814// universe of claimed objects.
815
816static inline bool
817is_visible_from_outside(Symbol* lsym)
818{
819 if (lsym->in_real_elf())
820 return true;
821 if (parameters->options().relocatable())
822 return true;
84ced98a
RÁE
823 if (parameters->options().is_undefined(lsym->name()))
824 return true;
d66a9eb3
CC
825 if (parameters->options().export_dynamic() || parameters->options().shared())
826 return lsym->is_externally_visible();
827 return false;
828}
829
89fc3421
CC
830// Get symbol resolution info.
831
832ld_plugin_status
833Pluginobj::get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const
834{
abc8dcba 835 if (nsyms > this->nsyms_)
89fc3421 836 return LDPS_NO_SYMS;
b0193076
RÁE
837
838 if (static_cast<size_t>(nsyms) > this->symbols_.size())
839 {
840 // We never decided to include this object. We mark all symbols as
841 // preempted.
ca09d69a 842 gold_assert(this->symbols_.size() == 0);
b0193076
RÁE
843 for (int i = 0; i < nsyms; i++)
844 syms[i].resolution = LDPR_PREEMPTED_REG;
845 return LDPS_OK;
846 }
847
89fc3421
CC
848 for (int i = 0; i < nsyms; i++)
849 {
850 ld_plugin_symbol* isym = &syms[i];
851 Symbol* lsym = this->symbols_[i];
852 ld_plugin_symbol_resolution res = LDPR_UNKNOWN;
853
854 if (lsym->is_undefined())
855 // The symbol remains undefined.
856 res = LDPR_UNDEF;
857 else if (isym->def == LDPK_UNDEF
858 || isym->def == LDPK_WEAKUNDEF
859 || isym->def == LDPK_COMMON)
860 {
861 // The original symbol was undefined or common.
862 if (lsym->source() != Symbol::FROM_OBJECT)
863 res = LDPR_RESOLVED_EXEC;
be234d88
CC
864 else if (lsym->object()->pluginobj() == this)
865 res = (is_visible_from_outside(lsym)
866 ? LDPR_PREVAILING_DEF
867 : LDPR_PREVAILING_DEF_IRONLY);
89fc3421
CC
868 else if (lsym->object()->pluginobj() != NULL)
869 res = LDPR_RESOLVED_IR;
870 else if (lsym->object()->is_dynamic())
871 res = LDPR_RESOLVED_DYN;
872 else
873 res = LDPR_RESOLVED_EXEC;
874 }
875 else
876 {
877 // The original symbol was a definition.
878 if (lsym->source() != Symbol::FROM_OBJECT)
879 res = LDPR_PREEMPTED_REG;
880 else if (lsym->object() == static_cast<const Object*>(this))
d66a9eb3 881 res = (is_visible_from_outside(lsym)
89fc3421
CC
882 ? LDPR_PREVAILING_DEF
883 : LDPR_PREVAILING_DEF_IRONLY);
884 else
885 res = (lsym->object()->pluginobj() != NULL
886 ? LDPR_PREEMPTED_IR
887 : LDPR_PREEMPTED_REG);
888 }
889 isym->resolution = res;
890 }
891 return LDPS_OK;
892}
893
894// Return TRUE if the comdat group with key COMDAT_KEY from this object
895// should be kept.
896
897bool
2ea97941 898Pluginobj::include_comdat_group(std::string comdat_key, Layout* layout)
89fc3421
CC
899{
900 std::pair<Comdat_map::iterator, bool> ins =
901 this->comdat_map_.insert(std::make_pair(comdat_key, false));
902
903 // If this is the first time we've seen this comdat key, ask the
904 // layout object whether it should be included.
905 if (ins.second)
2ea97941
ILT
906 ins.first->second = layout->find_or_add_kept_section(comdat_key,
907 NULL, 0, true,
908 true, NULL);
89fc3421
CC
909
910 return ins.first->second;
911}
912
913// Class Sized_pluginobj.
914
915template<int size, bool big_endian>
916Sized_pluginobj<size, big_endian>::Sized_pluginobj(
2ea97941
ILT
917 const std::string& name,
918 Input_file* input_file,
919 off_t offset,
920 off_t filesize)
921 : Pluginobj(name, input_file, offset, filesize)
89fc3421
CC
922{
923}
924
925// Read the symbols. Not used for plugin objects.
926
927template<int size, bool big_endian>
928void
929Sized_pluginobj<size, big_endian>::do_read_symbols(Read_symbols_data*)
930{
931 gold_unreachable();
932}
933
934// Lay out the input sections. Not used for plugin objects.
935
936template<int size, bool big_endian>
937void
938Sized_pluginobj<size, big_endian>::do_layout(Symbol_table*, Layout*,
939 Read_symbols_data*)
940{
941 gold_unreachable();
942}
943
944// Add the symbols to the symbol table.
945
89fc3421
CC
946template<int size, bool big_endian>
947void
948Sized_pluginobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
f488e4b0 949 Read_symbols_data*,
2ea97941 950 Layout* layout)
89fc3421
CC
951{
952 const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
953 unsigned char symbuf[sym_size];
954 elfcpp::Sym<size, big_endian> sym(symbuf);
955 elfcpp::Sym_write<size, big_endian> osym(symbuf);
956
957 typedef typename elfcpp::Elf_types<size>::Elf_WXword Elf_size_type;
958
959 this->symbols_.resize(this->nsyms_);
960
961 for (int i = 0; i < this->nsyms_; ++i)
962 {
ca09d69a 963 const struct ld_plugin_symbol* isym = &this->syms_[i];
2ea97941 964 const char* name = isym->name;
89fc3421
CC
965 const char* ver = isym->version;
966 elfcpp::Elf_Half shndx;
967 elfcpp::STB bind;
968 elfcpp::STV vis;
969
2ea97941
ILT
970 if (name != NULL && name[0] == '\0')
971 name = NULL;
89fc3421
CC
972 if (ver != NULL && ver[0] == '\0')
973 ver = NULL;
974
975 switch (isym->def)
976 {
977 case LDPK_WEAKDEF:
978 case LDPK_WEAKUNDEF:
979 bind = elfcpp::STB_WEAK;
980 break;
981 case LDPK_DEF:
982 case LDPK_UNDEF:
983 case LDPK_COMMON:
984 default:
985 bind = elfcpp::STB_GLOBAL;
986 break;
987 }
988
989 switch (isym->def)
990 {
991 case LDPK_DEF:
992 case LDPK_WEAKDEF:
993 shndx = elfcpp::SHN_ABS;
994 break;
995 case LDPK_COMMON:
996 shndx = elfcpp::SHN_COMMON;
997 break;
998 case LDPK_UNDEF:
999 case LDPK_WEAKUNDEF:
1000 default:
1001 shndx = elfcpp::SHN_UNDEF;
1002 break;
1003 }
1004
1005 switch (isym->visibility)
1006 {
1007 case LDPV_PROTECTED:
105b6afd 1008 vis = elfcpp::STV_PROTECTED;
89fc3421
CC
1009 break;
1010 case LDPV_INTERNAL:
105b6afd 1011 vis = elfcpp::STV_INTERNAL;
89fc3421
CC
1012 break;
1013 case LDPV_HIDDEN:
105b6afd 1014 vis = elfcpp::STV_HIDDEN;
89fc3421
CC
1015 break;
1016 case LDPV_DEFAULT:
1017 default:
1018 vis = elfcpp::STV_DEFAULT;
1019 break;
1020 }
1021
1022 if (isym->comdat_key != NULL
1023 && isym->comdat_key[0] != '\0'
2ea97941 1024 && !this->include_comdat_group(isym->comdat_key, layout))
89fc3421
CC
1025 shndx = elfcpp::SHN_UNDEF;
1026
1027 osym.put_st_name(0);
1028 osym.put_st_value(0);
1029 osym.put_st_size(static_cast<Elf_size_type>(isym->size));
1030 osym.put_st_info(bind, elfcpp::STT_NOTYPE);
1031 osym.put_st_other(vis, 0);
1032 osym.put_st_shndx(shndx);
1033
1034 this->symbols_[i] =
2ea97941 1035 symtab->add_from_pluginobj<size, big_endian>(this, name, ver, &sym);
89fc3421
CC
1036 }
1037}
1038
b0193076
RÁE
1039template<int size, bool big_endian>
1040Archive::Should_include
1041Sized_pluginobj<size, big_endian>::do_should_include_member(
88a4108b
ILT
1042 Symbol_table* symtab,
1043 Layout* layout,
1044 Read_symbols_data*,
1045 std::string* why)
b0193076
RÁE
1046{
1047 char* tmpbuf = NULL;
1048 size_t tmpbuflen = 0;
1049
88a4108b
ILT
1050 for (int i = 0; i < this->nsyms_; ++i)
1051 {
1052 const struct ld_plugin_symbol& sym = this->syms_[i];
1053 const char* name = sym.name;
1054 Symbol* symbol;
1055 Archive::Should_include t = Archive::should_include_member(symtab,
1056 layout,
1057 name,
1058 &symbol, why,
1059 &tmpbuf,
1060 &tmpbuflen);
b0193076
RÁE
1061 if (t == Archive::SHOULD_INCLUDE_YES)
1062 {
1063 if (tmpbuf != NULL)
1064 free(tmpbuf);
1065 return t;
1066 }
88a4108b 1067 }
b0193076
RÁE
1068 if (tmpbuf != NULL)
1069 free(tmpbuf);
1070 return Archive::SHOULD_INCLUDE_UNKNOWN;
1071}
1072
e0c52780
CC
1073// Iterate over global symbols, calling a visitor class V for each.
1074
1075template<int size, bool big_endian>
1076void
1077Sized_pluginobj<size, big_endian>::do_for_all_global_symbols(
1078 Read_symbols_data*,
1079 Library_base::Symbol_visitor_base* v)
1080{
1081 for (int i = 0; i < this->nsyms_; ++i)
1082 {
1083 const struct ld_plugin_symbol& sym = this->syms_[i];
1084 if (sym.def != LDPK_UNDEF)
1085 v->visit(sym.name);
1086 }
1087}
1088
cdc29364
CC
1089// Iterate over local symbols, calling a visitor class V for each GOT offset
1090// associated with a local symbol.
1091template<int size, bool big_endian>
1092void
1093Sized_pluginobj<size, big_endian>::do_for_all_local_got_entries(
1094 Got_offset_list::Visitor*) const
1095{
1096 gold_unreachable();
1097}
1098
89fc3421
CC
1099// Get the size of a section. Not used for plugin objects.
1100
1101template<int size, bool big_endian>
1102uint64_t
1103Sized_pluginobj<size, big_endian>::do_section_size(unsigned int)
1104{
1105 gold_unreachable();
1106 return 0;
1107}
1108
1109// Get the name of a section. Not used for plugin objects.
1110
1111template<int size, bool big_endian>
1112std::string
1113Sized_pluginobj<size, big_endian>::do_section_name(unsigned int)
1114{
1115 gold_unreachable();
1116 return std::string();
1117}
1118
1119// Return a view of the contents of a section. Not used for plugin objects.
1120
1121template<int size, bool big_endian>
1122Object::Location
1123Sized_pluginobj<size, big_endian>::do_section_contents(unsigned int)
1124{
1125 Location loc(0, 0);
1126
1127 gold_unreachable();
1128 return loc;
1129}
1130
1131// Return section flags. Not used for plugin objects.
1132
1133template<int size, bool big_endian>
1134uint64_t
1135Sized_pluginobj<size, big_endian>::do_section_flags(unsigned int)
1136{
1137 gold_unreachable();
1138 return 0;
1139}
1140
ef15dade
ST
1141// Return section entsize. Not used for plugin objects.
1142
1143template<int size, bool big_endian>
1144uint64_t
1145Sized_pluginobj<size, big_endian>::do_section_entsize(unsigned int)
1146{
1147 gold_unreachable();
1148 return 0;
1149}
1150
89fc3421
CC
1151// Return section address. Not used for plugin objects.
1152
1153template<int size, bool big_endian>
1154uint64_t
1155Sized_pluginobj<size, big_endian>::do_section_address(unsigned int)
1156{
1157 gold_unreachable();
1158 return 0;
1159}
1160
1161// Return section type. Not used for plugin objects.
1162
1163template<int size, bool big_endian>
1164unsigned int
1165Sized_pluginobj<size, big_endian>::do_section_type(unsigned int)
1166{
1167 gold_unreachable();
1168 return 0;
1169}
1170
1171// Return the section link field. Not used for plugin objects.
1172
1173template<int size, bool big_endian>
1174unsigned int
1175Sized_pluginobj<size, big_endian>::do_section_link(unsigned int)
1176{
1177 gold_unreachable();
1178 return 0;
1179}
1180
1181// Return the section link field. Not used for plugin objects.
1182
1183template<int size, bool big_endian>
1184unsigned int
1185Sized_pluginobj<size, big_endian>::do_section_info(unsigned int)
1186{
1187 gold_unreachable();
1188 return 0;
1189}
1190
1191// Return the section alignment. Not used for plugin objects.
1192
1193template<int size, bool big_endian>
1194uint64_t
1195Sized_pluginobj<size, big_endian>::do_section_addralign(unsigned int)
1196{
1197 gold_unreachable();
1198 return 0;
1199}
1200
1201// Return the Xindex structure to use. Not used for plugin objects.
1202
1203template<int size, bool big_endian>
1204Xindex*
1205Sized_pluginobj<size, big_endian>::do_initialize_xindex()
1206{
1207 gold_unreachable();
1208 return NULL;
1209}
1210
1211// Get symbol counts. Not used for plugin objects.
1212
1213template<int size, bool big_endian>
1214void
1215Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(const Symbol_table*,
1216 size_t*, size_t*) const
1217{
1218 gold_unreachable();
1219}
1220
dde3f402
ILT
1221// Get symbols. Not used for plugin objects.
1222
1223template<int size, bool big_endian>
1224const Object::Symbols*
1225Sized_pluginobj<size, big_endian>::do_get_global_symbols() const
1226{
1227 gold_unreachable();
1228}
1229
5995b570 1230// Class Plugin_finish. This task runs after all replacement files have
78384e8f
CC
1231// been added. For now, it's a placeholder for a possible plugin API
1232// to allow the plugin to release most of its resources. The cleanup
1233// handlers must be called later, because they can remove the temporary
1234// object files that are needed until the end of the link.
89fc3421 1235
5995b570 1236class Plugin_finish : public Task
89fc3421
CC
1237{
1238 public:
5995b570 1239 Plugin_finish(Task_token* this_blocker, Task_token* next_blocker)
89fc3421
CC
1240 : this_blocker_(this_blocker), next_blocker_(next_blocker)
1241 { }
1242
5995b570 1243 ~Plugin_finish()
89fc3421
CC
1244 {
1245 if (this->this_blocker_ != NULL)
1246 delete this->this_blocker_;
1247 }
1248
1249 Task_token*
1250 is_runnable()
1251 {
1252 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
1253 return this->this_blocker_;
1254 return NULL;
1255 }
1256
1257 void
1258 locks(Task_locker* tl)
1259 { tl->add(this, this->next_blocker_); }
1260
1261 void
1262 run(Workqueue*)
483620e8 1263 {
78384e8f 1264 // We could call early cleanup handlers here.
483620e8 1265 }
89fc3421
CC
1266
1267 std::string
1268 get_name() const
5995b570 1269 { return "Plugin_finish"; }
89fc3421
CC
1270
1271 private:
1272 Task_token* this_blocker_;
1273 Task_token* next_blocker_;
1274};
1275
1276// Class Plugin_hook.
1277
1278Plugin_hook::~Plugin_hook()
1279{
1280}
1281
1282// Return whether a Plugin_hook task is runnable.
1283
1284Task_token*
1285Plugin_hook::is_runnable()
1286{
1287 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
1288 return this->this_blocker_;
1289 return NULL;
1290}
1291
1292// Return a Task_locker for a Plugin_hook task. We don't need any
1293// locks here.
1294
1295void
1296Plugin_hook::locks(Task_locker*)
1297{
1298}
1299
89fc3421
CC
1300// Run the "all symbols read" plugin hook.
1301
1302void
5995b570 1303Plugin_hook::run(Workqueue* workqueue)
89fc3421
CC
1304{
1305 gold_assert(this->options_.has_plugins());
a10ae760 1306 Symbol* start_sym = this->symtab_->lookup(parameters->entry());
91ff43fe
RÁE
1307 if (start_sym != NULL)
1308 start_sym->set_in_real_elf();
1309
89fc3421 1310 this->options_.plugins()->all_symbols_read(workqueue,
0f7c0701 1311 this,
89fc3421
CC
1312 this->input_objects_,
1313 this->symtab_,
89fc3421
CC
1314 this->dirpath_,
1315 this->mapfile_,
1316 &this->this_blocker_);
5995b570
CC
1317 workqueue->queue_soon(new Plugin_finish(this->this_blocker_,
1318 this->next_blocker_));
89fc3421
CC
1319}
1320
1321// The C interface routines called by the plugins.
1322
1323#ifdef ENABLE_PLUGINS
1324
1325// Register a claim-file handler.
1326
1327static enum ld_plugin_status
1328register_claim_file(ld_plugin_claim_file_handler handler)
1329{
1330 gold_assert(parameters->options().has_plugins());
1331 parameters->options().plugins()->set_claim_file_handler(handler);
1332 return LDPS_OK;
1333}
1334
1335// Register an all-symbols-read handler.
1336
1337static enum ld_plugin_status
1338register_all_symbols_read(ld_plugin_all_symbols_read_handler handler)
1339{
1340 gold_assert(parameters->options().has_plugins());
1341 parameters->options().plugins()->set_all_symbols_read_handler(handler);
1342 return LDPS_OK;
1343}
1344
1345// Register a cleanup handler.
1346
1347static enum ld_plugin_status
1348register_cleanup(ld_plugin_cleanup_handler handler)
1349{
1350 gold_assert(parameters->options().has_plugins());
1351 parameters->options().plugins()->set_cleanup_handler(handler);
1352 return LDPS_OK;
1353}
1354
1355// Add symbols from a plugin-claimed input file.
1356
1357static enum ld_plugin_status
ca09d69a 1358add_symbols(void* handle, int nsyms, const ld_plugin_symbol* syms)
89fc3421
CC
1359{
1360 gold_assert(parameters->options().has_plugins());
1361 Pluginobj* obj = parameters->options().plugins()->make_plugin_object(
1362 static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
1363 if (obj == NULL)
1364 return LDPS_ERR;
1365 obj->store_incoming_symbols(nsyms, syms);
1366 return LDPS_OK;
1367}
1368
0f7c0701
CC
1369// Get the input file information with an open (possibly re-opened)
1370// file descriptor.
1371
1372static enum ld_plugin_status
ca09d69a 1373get_input_file(const void* handle, struct ld_plugin_input_file* file)
0f7c0701
CC
1374{
1375 gold_assert(parameters->options().has_plugins());
1376 unsigned int obj_index =
1377 static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
1378 return parameters->options().plugins()->get_input_file(obj_index, file);
1379}
1380
1381// Release the input file.
1382
1383static enum ld_plugin_status
ca09d69a 1384release_input_file(const void* handle)
0f7c0701
CC
1385{
1386 gold_assert(parameters->options().has_plugins());
1387 unsigned int obj_index =
1388 static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
1389 return parameters->options().plugins()->release_input_file(obj_index);
1390}
1391
9c793f14
RÁE
1392static enum ld_plugin_status
1393get_view(const void *handle, const void **viewp)
1394{
1395 gold_assert(parameters->options().has_plugins());
1396 unsigned int obj_index =
1397 static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
1398 return parameters->options().plugins()->get_view(obj_index, viewp);
1399}
1400
89fc3421
CC
1401// Get the symbol resolution info for a plugin-claimed input file.
1402
1403static enum ld_plugin_status
ca09d69a 1404get_symbols(const void* handle, int nsyms, ld_plugin_symbol* syms)
89fc3421
CC
1405{
1406 gold_assert(parameters->options().has_plugins());
e9552f7e
ST
1407 Object* obj = parameters->options().plugins()->object(
1408 static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
89fc3421
CC
1409 if (obj == NULL)
1410 return LDPS_ERR;
e9552f7e
ST
1411 Pluginobj* plugin_obj = obj->pluginobj();
1412 if (plugin_obj == NULL)
1413 return LDPS_ERR;
1414 return plugin_obj->get_symbol_resolution_info(nsyms, syms);
89fc3421
CC
1415}
1416
1417// Add a new (real) input file generated by a plugin.
1418
1419static enum ld_plugin_status
ca09d69a 1420add_input_file(const char* pathname)
89fc3421
CC
1421{
1422 gold_assert(parameters->options().has_plugins());
e99daf92
ILT
1423 return parameters->options().plugins()->add_input_file(pathname, false);
1424}
1425
1426// Add a new (real) library required by a plugin.
1427
1428static enum ld_plugin_status
ca09d69a 1429add_input_library(const char* pathname)
e99daf92
ILT
1430{
1431 gold_assert(parameters->options().has_plugins());
1432 return parameters->options().plugins()->add_input_file(pathname, true);
89fc3421
CC
1433}
1434
42218b9f
RÁE
1435// Set the extra library path to be used by libraries added via
1436// add_input_library
1437
1438static enum ld_plugin_status
ca09d69a 1439set_extra_library_path(const char* path)
42218b9f
RÁE
1440{
1441 gold_assert(parameters->options().has_plugins());
1442 return parameters->options().plugins()->set_extra_library_path(path);
1443}
1444
89fc3421
CC
1445// Issue a diagnostic message from a plugin.
1446
1447static enum ld_plugin_status
ca09d69a 1448message(int level, const char* format, ...)
89fc3421
CC
1449{
1450 va_list args;
1451 va_start(args, format);
1452
1453 switch (level)
1454 {
1455 case LDPL_INFO:
1456 parameters->errors()->info(format, args);
1457 break;
1458 case LDPL_WARNING:
1459 parameters->errors()->warning(format, args);
1460 break;
1461 case LDPL_ERROR:
1462 default:
1463 parameters->errors()->error(format, args);
1464 break;
1465 case LDPL_FATAL:
1466 parameters->errors()->fatal(format, args);
1467 break;
1468 }
1469
1470 va_end(args);
1471 return LDPS_OK;
1472}
1473
e9552f7e
ST
1474// Get the section count of the object corresponding to the handle. This
1475// plugin interface can only be called in the claim_file handler of the plugin.
1476
1477static enum ld_plugin_status
1478get_input_section_count(const void* handle, unsigned int* count)
1479{
1480 gold_assert(parameters->options().has_plugins());
1481
1482 if (!parameters->options().plugins()->in_claim_file_handler())
1483 return LDPS_ERR;
1484
1485 Object* obj = parameters->options().plugins()->get_elf_object(handle);
1486
1487 if (obj == NULL)
1488 return LDPS_ERR;
1489
1490 *count = obj->shnum();
1491 return LDPS_OK;
1492}
1493
1494// Get the type of the specified section in the object corresponding
1495// to the handle. This plugin interface can only be called in the
1496// claim_file handler of the plugin.
1497
1498static enum ld_plugin_status
1499get_input_section_type(const struct ld_plugin_section section,
1500 unsigned int* type)
1501{
1502 gold_assert(parameters->options().has_plugins());
1503
1504 if (!parameters->options().plugins()->in_claim_file_handler())
1505 return LDPS_ERR;
1506
1507 Object* obj
1508 = parameters->options().plugins()->get_elf_object(section.handle);
1509
1510 if (obj == NULL)
1511 return LDPS_BAD_HANDLE;
1512
1513 *type = obj->section_type(section.shndx);
1514 return LDPS_OK;
1515}
1516
1517// Get the name of the specified section in the object corresponding
1518// to the handle. This plugin interface can only be called in the
1519// claim_file handler of the plugin.
1520
1521static enum ld_plugin_status
1522get_input_section_name(const struct ld_plugin_section section,
1523 char** section_name_ptr)
1524{
1525 gold_assert(parameters->options().has_plugins());
1526
1527 if (!parameters->options().plugins()->in_claim_file_handler())
1528 return LDPS_ERR;
1529
1530 Object* obj
1531 = parameters->options().plugins()->get_elf_object(section.handle);
1532
1533 if (obj == NULL)
1534 return LDPS_BAD_HANDLE;
1535
1536 // Check if the object is locked before getting the section name.
1537 gold_assert(obj->is_locked());
1538
1539 const std::string section_name = obj->section_name(section.shndx);
1540 *section_name_ptr = static_cast<char*>(malloc(section_name.length() + 1));
1541 memcpy(*section_name_ptr, section_name.c_str(), section_name.length() + 1);
1542 return LDPS_OK;
1543}
1544
1545// Get the contents of the specified section in the object corresponding
1546// to the handle. This plugin interface can only be called in the
1547// claim_file handler of the plugin.
1548
1549static enum ld_plugin_status
1550get_input_section_contents(const struct ld_plugin_section section,
1551 const unsigned char** section_contents_ptr,
1552 size_t* len)
1553{
1554 gold_assert(parameters->options().has_plugins());
1555
1556 if (!parameters->options().plugins()->in_claim_file_handler())
1557 return LDPS_ERR;
1558
1559 Object* obj
1560 = parameters->options().plugins()->get_elf_object(section.handle);
1561
1562 if (obj == NULL)
1563 return LDPS_BAD_HANDLE;
1564
1565 // Check if the object is locked before getting the section contents.
1566 gold_assert(obj->is_locked());
1567
1568 section_size_type plen;
1569 *section_contents_ptr
1570 = obj->section_contents(section.shndx, &plen, false);
1571 *len = plen;
1572 return LDPS_OK;
1573}
1574
1575// Specify the ordering of sections in the final layout. The sections are
1576// specified as (handle,shndx) pairs in the two arrays in the order in
1577// which they should appear in the final layout.
1578
1579static enum ld_plugin_status
1580update_section_order(const struct ld_plugin_section *section_list,
1581 unsigned int num_sections)
1582{
1583 gold_assert(parameters->options().has_plugins());
1584
1585 if (num_sections == 0)
1586 return LDPS_OK;
1587
1588 if (section_list == NULL)
1589 return LDPS_ERR;
1590
1591 std::map<Section_id, unsigned int> order_map;
1592
1593 for (unsigned int i = 0; i < num_sections; ++i)
1594 {
1595 Object* obj = parameters->options().plugins()->get_elf_object(
1596 section_list[i].handle);
1597 if (obj == NULL)
1598 return LDPS_BAD_HANDLE;
1599 unsigned int shndx = section_list[i].shndx;
1600 Section_id secn_id(obj, shndx);
1601 order_map[secn_id] = i + 1;
1602 }
1603
1604 Layout* layout = parameters->options().plugins()->layout();
1605 gold_assert (layout != NULL);
1606
1607 for (Layout::Section_list::const_iterator p = layout->section_list().begin();
1608 p != layout->section_list().end();
1609 ++p)
1610 (*p)->update_section_layout(order_map);
1611
1612 return LDPS_OK;
1613}
1614
1615// Let the linker know that the sections could be reordered.
1616
1617static enum ld_plugin_status
1618allow_section_ordering()
1619{
1620 gold_assert(parameters->options().has_plugins());
1621 Layout* layout = parameters->options().plugins()->layout();
1622 layout->set_section_ordering_specified();
1623 return LDPS_OK;
1624}
1625
89fc3421
CC
1626#endif // ENABLE_PLUGINS
1627
1628// Allocate a Pluginobj object of the appropriate size and endianness.
1629
1630static Pluginobj*
0f7c0701 1631make_sized_plugin_object(Input_file* input_file, off_t offset, off_t filesize)
89fc3421 1632{
89fc3421
CC
1633 Pluginobj* obj = NULL;
1634
029ba973
ILT
1635 parameters_force_valid_target();
1636 const Target& target(parameters->target());
89fc3421 1637
029ba973 1638 if (target.get_size() == 32)
89fc3421 1639 {
029ba973 1640 if (target.is_big_endian())
92f03fcb 1641#ifdef HAVE_TARGET_32_BIG
89fc3421 1642 obj = new Sized_pluginobj<32, true>(input_file->filename(),
0f7c0701 1643 input_file, offset, filesize);
92f03fcb
CC
1644#else
1645 gold_error(_("%s: not configured to support "
1646 "32-bit big-endian object"),
1647 input_file->filename().c_str());
89fc3421 1648#endif
89fc3421 1649 else
92f03fcb 1650#ifdef HAVE_TARGET_32_LITTLE
89fc3421 1651 obj = new Sized_pluginobj<32, false>(input_file->filename(),
0f7c0701 1652 input_file, offset, filesize);
92f03fcb
CC
1653#else
1654 gold_error(_("%s: not configured to support "
1655 "32-bit little-endian object"),
1656 input_file->filename().c_str());
89fc3421
CC
1657#endif
1658 }
029ba973 1659 else if (target.get_size() == 64)
89fc3421 1660 {
029ba973 1661 if (target.is_big_endian())
92f03fcb 1662#ifdef HAVE_TARGET_64_BIG
89fc3421 1663 obj = new Sized_pluginobj<64, true>(input_file->filename(),
0f7c0701 1664 input_file, offset, filesize);
92f03fcb
CC
1665#else
1666 gold_error(_("%s: not configured to support "
1667 "64-bit big-endian object"),
1668 input_file->filename().c_str());
89fc3421 1669#endif
89fc3421 1670 else
92f03fcb 1671#ifdef HAVE_TARGET_64_LITTLE
89fc3421 1672 obj = new Sized_pluginobj<64, false>(input_file->filename(),
0f7c0701 1673 input_file, offset, filesize);
92f03fcb
CC
1674#else
1675 gold_error(_("%s: not configured to support "
1676 "64-bit little-endian object"),
1677 input_file->filename().c_str());
89fc3421
CC
1678#endif
1679 }
1680
1681 gold_assert(obj != NULL);
89fc3421
CC
1682 return obj;
1683}
1684
1685} // End namespace gold.
This page took 0.223357 seconds and 4 git commands to generate.