* plugin-api.h (LDPS_BAD_HANDLE): New constant.
[deliverable/binutils-gdb.git] / gold / plugin.h
CommitLineData
89fc3421
CC
1// plugin.h -- plugin manager for gold -*- C++ -*-
2
3// Copyright 2008 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#ifndef GOLD_PLUGIN_H
24#define GOLD_PLUGIN_H
25
26#include <list>
27#include <string>
28
29#include "object.h"
30#include "plugin-api.h"
31#include "workqueue.h"
32
33namespace gold
34{
35
36class General_options;
37class Input_file;
38class Input_objects;
39class Symbol_table;
40class Layout;
41class Dirsearch;
42class Mapfile;
43class Task_token;
44class Pluginobj;
45
46// This class represents a single plugin library.
47
48class Plugin
49{
50 public:
4674ecfc 51 Plugin(const char* filename)
89fc3421 52 : handle_(NULL),
4674ecfc
CC
53 filename_(filename),
54 args_(),
89fc3421
CC
55 claim_file_handler_(NULL),
56 all_symbols_read_handler_(NULL),
57 cleanup_handler_(NULL)
58 { }
59
60 ~Plugin()
61 { }
62
63 // Load the library and call its entry point.
64 void
65 load();
66
67 // Call the claim-file handler.
68 bool
69 claim_file(struct ld_plugin_input_file *plugin_input_file);
70
71 // Call the all-symbols-read handler.
72 void
73 all_symbols_read();
74
75 // Call the cleanup handler.
76 void
77 cleanup();
78
79 // Register a claim-file handler.
80 void
81 set_claim_file_handler(ld_plugin_claim_file_handler handler)
82 { this->claim_file_handler_ = handler; }
83
84 // Register an all-symbols-read handler.
85 void
86 set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler)
87 { this->all_symbols_read_handler_ = handler; }
88
89 // Register a claim-file handler.
90 void
91 set_cleanup_handler(ld_plugin_cleanup_handler handler)
92 { this->cleanup_handler_ = handler; }
93
4674ecfc
CC
94 // Add an argument
95 void
96 add_option(const char *arg)
97 {
98 this->args_.push_back(arg);
99 }
100
89fc3421
CC
101 private:
102 Plugin(const Plugin&);
103 Plugin& operator=(const Plugin&);
104
105 // The shared library handle returned by dlopen.
106 void* handle_;
107 // The argument string given to --plugin.
4674ecfc
CC
108 std::string filename_;
109 // The list of argument string given to --plugin-opt.
110 std::vector<std::string> args_;
89fc3421
CC
111 // The plugin's event handlers.
112 ld_plugin_claim_file_handler claim_file_handler_;
113 ld_plugin_all_symbols_read_handler all_symbols_read_handler_;
114 ld_plugin_cleanup_handler cleanup_handler_;
115};
116
117// A manager class for plugins.
118
119class Plugin_manager
120{
121 public:
122 Plugin_manager(const General_options& options)
5995b570 123 : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL),
483620e8
CC
124 plugin_input_file_(), in_replacement_phase_(false), cleanup_done_(false),
125 options_(options), workqueue_(NULL), input_objects_(NULL), symtab_(NULL),
126 layout_(NULL), dirpath_(NULL), mapfile_(NULL), this_blocker_(NULL)
89fc3421
CC
127 { this->current_ = plugins_.end(); }
128
129 ~Plugin_manager();
130
131 // Add a plugin library.
132 void
4674ecfc
CC
133 add_plugin(const char* filename)
134 { this->plugins_.push_back(new Plugin(filename)); }
135
136 // Add an argument to the current plugin.
137 void
138 add_plugin_option(const char* opt)
139 {
140 Plugin* last = this->plugins_.back();
141 last->add_option(opt);
142 }
89fc3421
CC
143
144 // Load all plugin libraries.
145 void
146 load_plugins();
147
148 // Call the plugin claim-file handlers in turn to see if any claim the file.
149 Pluginobj*
150 claim_file(Input_file *input_file, off_t offset, off_t filesize);
151
152 // Call the all-symbols-read handlers.
153 void
154 all_symbols_read(Workqueue* workqueue, Input_objects* input_objects,
155 Symbol_table* symtab, Layout* layout, Dirsearch* dirpath,
156 Mapfile* mapfile, Task_token** last_blocker);
157
483620e8 158 // Run deferred layout.
89fc3421 159 void
483620e8
CC
160 layout_deferred_objects();
161
162 // Call the cleanup handlers.
163 void
164 cleanup();
89fc3421
CC
165
166 // Register a claim-file handler.
167 void
168 set_claim_file_handler(ld_plugin_claim_file_handler handler)
169 {
170 gold_assert(this->current_ != plugins_.end());
171 (*this->current_)->set_claim_file_handler(handler);
172 }
173
174 // Register an all-symbols-read handler.
175 void
176 set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler)
177 {
178 gold_assert(this->current_ != plugins_.end());
179 (*this->current_)->set_all_symbols_read_handler(handler);
180 }
181
182 // Register a claim-file handler.
183 void
184 set_cleanup_handler(ld_plugin_cleanup_handler handler)
185 {
186 gold_assert(this->current_ != plugins_.end());
187 (*this->current_)->set_cleanup_handler(handler);
188 }
189
190 // Make a new Pluginobj object. This is called when the plugin calls
191 // the add_symbols API.
192 Pluginobj*
193 make_plugin_object(unsigned int handle);
194
195 // Return the Pluginobj associated with the given HANDLE.
196 Pluginobj*
197 object(unsigned int handle) const
198 {
199 if (handle >= this->objects_.size())
200 return NULL;
201 return this->objects_[handle];
202 }
203
5995b570
CC
204 // Return TRUE if any input files have been claimed by a plugin
205 // and we are still in the initial input phase.
206 bool
207 should_defer_layout() const
208 { return !this->objects_.empty() && !this->in_replacement_phase_; }
209
210 // Add a regular object to the deferred layout list. These are
211 // objects whose layout has been deferred until after the
212 // replacement files have arrived.
213 void
214 add_deferred_layout_object(Relobj* obj)
215 { this->deferred_layout_objects_.push_back(obj); }
216
89fc3421
CC
217 // Add a new input file.
218 ld_plugin_status
219 add_input_file(char *pathname);
220
221 // Return TRUE if we are in the replacement phase.
222 bool
223 in_replacement_phase() const
224 { return this->in_replacement_phase_; }
225
226 private:
227 Plugin_manager(const Plugin_manager&);
228 Plugin_manager& operator=(const Plugin_manager&);
229
230 typedef std::list<Plugin*> Plugin_list;
231 typedef std::vector<Pluginobj*> Object_list;
5995b570 232 typedef std::vector<Relobj*> Deferred_layout_list;
89fc3421
CC
233
234 // The list of plugin libraries.
235 Plugin_list plugins_;
236 // A pointer to the current plugin. Used while loading plugins.
237 Plugin_list::iterator current_;
238
239 // The list of plugin objects. The index of an item in this list
240 // serves as the "handle" that we pass to the plugins.
241 Object_list objects_;
242
5995b570
CC
243 // The list of regular objects whose layout has been deferred.
244 Deferred_layout_list deferred_layout_objects_;
245
89fc3421
CC
246 // The file currently up for claim by the plugins.
247 Input_file* input_file_;
248 struct ld_plugin_input_file plugin_input_file_;
249
250 // TRUE after the all symbols read event; indicates that we are
251 // processing replacement files whose symbols should replace the
252 // placeholder symbols from the Pluginobj objects.
253 bool in_replacement_phase_;
254
483620e8
CC
255 // TRUE if the cleanup handlers have been called.
256 bool cleanup_done_;
257
89fc3421
CC
258 const General_options& options_;
259 Workqueue* workqueue_;
260 Input_objects* input_objects_;
261 Symbol_table* symtab_;
262 Layout* layout_;
263 Dirsearch* dirpath_;
264 Mapfile* mapfile_;
265 Task_token* this_blocker_;
266};
267
268
269// An object file claimed by a plugin. This is an abstract base class.
270// The implementation is the template class Sized_pluginobj.
271
272class Pluginobj : public Object
273{
274 public:
275
276 typedef std::vector<Symbol*> Symbols;
277
278 Pluginobj(const std::string& name, Input_file* input_file, off_t offset);
279
280 // Fill in the symbol resolution status for the given plugin symbols.
281 ld_plugin_status
282 get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const;
283
284 // Add symbol information to the global symbol table.
285 void
286 add_symbols(Symbol_table* symtab, Layout* layout)
287 { this->do_add_symbols(symtab, layout); }
288
289 // Store the incoming symbols from the plugin for later processing.
290 void
291 store_incoming_symbols(int nsyms, const struct ld_plugin_symbol* syms)
292 {
293 this->nsyms_ = nsyms;
294 this->syms_ = syms;
295 }
296
297 // Return TRUE if the comdat group with key COMDAT_KEY from this object
298 // should be kept.
299 bool
300 include_comdat_group(std::string comdat_key, Layout* layout);
301
302 protected:
303 // Return TRUE if this is an object claimed by a plugin.
304 virtual Pluginobj*
305 do_pluginobj()
306 { return this; }
307
308 // Add symbol information to the global symbol table--implemented by
309 // child class.
310 virtual void
311 do_add_symbols(Symbol_table*, Layout*) = 0;
312
313 // The number of symbols provided by the plugin.
314 int nsyms_;
315
316 // The symbols provided by the plugin.
317 const struct ld_plugin_symbol* syms_;
318
319 // The entries in the symbol table for the external symbols.
320 Symbols symbols_;
321
322 private:
323 // Map a comdat key symbol to a boolean indicating whether the comdat
324 // group in this object with that key should be kept.
325 typedef Unordered_map<std::string, bool> Comdat_map;
326 Comdat_map comdat_map_;
327};
328
329// A plugin object, size-specific version.
330
331template<int size, bool big_endian>
332class Sized_pluginobj : public Pluginobj
333{
334 public:
335 Sized_pluginobj(const std::string& name, Input_file* input_file,
336 off_t offset);
337
338 // Read the symbols.
339 void
340 do_read_symbols(Read_symbols_data*);
341
342 // Lay out the input sections.
343 void
344 do_layout(Symbol_table*, Layout*, Read_symbols_data*);
345
346 // Add the symbols to the symbol table.
347 void
348 do_add_symbols(Symbol_table*, Read_symbols_data*);
349
350 void
351 do_add_symbols(Symbol_table*, Layout*);
352
353 // Get the size of a section.
354 uint64_t
355 do_section_size(unsigned int shndx);
356
357 // Get the name of a section.
358 std::string
359 do_section_name(unsigned int shndx);
360
361 // Return a view of the contents of a section.
362 Object::Location
363 do_section_contents(unsigned int shndx);
364
365 // Return section flags.
366 uint64_t
367 do_section_flags(unsigned int shndx);
368
369 // Return section address.
370 uint64_t
371 do_section_address(unsigned int shndx);
372
373 // Return section type.
374 unsigned int
375 do_section_type(unsigned int shndx);
376
377 // Return the section link field.
378 unsigned int
379 do_section_link(unsigned int shndx);
380
381 // Return the section link field.
382 unsigned int
383 do_section_info(unsigned int shndx);
384
385 // Return the section alignment.
386 uint64_t
387 do_section_addralign(unsigned int shndx);
388
389 // Return the Xindex structure to use.
390 Xindex*
391 do_initialize_xindex();
392
393 // Get symbol counts.
394 void
395 do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
396
397 // Add placeholder symbols from a claimed file.
398 ld_plugin_status
399 add_symbols_from_plugin(int nsyms, const ld_plugin_symbol* syms);
400
401 protected:
402
403 private:
404};
405
406// This Task handles adding the symbols to the symbol table. These
407// tasks must be run in the same order as the arguments appear on the
408// command line.
409
410class Add_plugin_symbols : public Task
411{
412 public:
413 // THIS_BLOCKER is used to prevent this task from running before the
414 // one for the previous input file. NEXT_BLOCKER is used to prevent
415 // the next task from running.
416 Add_plugin_symbols(Symbol_table* symtab,
417 Layout* layout,
418 Pluginobj* obj,
419 Task_token* this_blocker,
420 Task_token* next_blocker)
421 : symtab_(symtab), layout_(layout), obj_(obj),
422 this_blocker_(this_blocker), next_blocker_(next_blocker)
423 { }
424
425 ~Add_plugin_symbols();
426
427 // The standard Task methods.
428
429 Task_token*
430 is_runnable();
431
432 void
433 locks(Task_locker*);
434
435 void
436 run(Workqueue*);
437
438 std::string
439 get_name() const
440 { return "Add_plugin_symbols " + this->obj_->name(); }
441
442private:
443 Symbol_table* symtab_;
444 Layout* layout_;
445 Pluginobj* obj_;
446 Task_token* this_blocker_;
447 Task_token* next_blocker_;
448};
449
450// This Task handles handles the "all symbols read" event hook.
451// The plugin may add additional input files at this time, which must
452// be queued for reading.
453
454class Plugin_hook : public Task
455{
456 public:
457 Plugin_hook(const General_options& options, Input_objects* input_objects,
458 Symbol_table* symtab, Layout* layout, Dirsearch* dirpath,
459 Mapfile* mapfile, Task_token* this_blocker,
460 Task_token* next_blocker)
461 : options_(options), input_objects_(input_objects), symtab_(symtab),
462 layout_(layout), dirpath_(dirpath), mapfile_(mapfile),
463 this_blocker_(this_blocker), next_blocker_(next_blocker)
464 { }
465
466 ~Plugin_hook();
467
468 // The standard Task methods.
469
470 Task_token*
471 is_runnable();
472
473 void
474 locks(Task_locker*);
475
476 void
477 run(Workqueue*);
478
479 std::string
480 get_name() const
481 { return "Plugin_hook"; }
482
483 private:
89fc3421
CC
484 const General_options& options_;
485 Input_objects* input_objects_;
486 Symbol_table* symtab_;
487 Layout* layout_;
488 Dirsearch* dirpath_;
489 Mapfile* mapfile_;
490 Task_token* this_blocker_;
491 Task_token* next_blocker_;
492};
493
494} // End namespace gold.
495
496#endif // !defined(GOLD_PLUGIN_H)
This page took 0.050724 seconds and 4 git commands to generate.