OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [plugin.h] - Blame information for rev 28

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 khays
// plugin.h -- plugin manager for gold      -*- C++ -*-
2
 
3
// Copyright 2008, 2009, 2010, 2011 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
 
33
namespace gold
34
{
35
 
36
class General_options;
37
class Input_file;
38
class Input_objects;
39
class Archive;
40
class Input_group;
41
class Symbol;
42
class Symbol_table;
43
class Layout;
44
class Dirsearch;
45
class Mapfile;
46
class Task;
47
class Task_token;
48
class Pluginobj;
49
class Plugin_rescan;
50
 
51
// This class represents a single plugin library.
52
 
53
class Plugin
54
{
55
 public:
56
  Plugin(const char* filename)
57
    : handle_(NULL),
58
      filename_(filename),
59
      args_(),
60
      claim_file_handler_(NULL),
61
      all_symbols_read_handler_(NULL),
62
      cleanup_handler_(NULL),
63
      cleanup_done_(false)
64
  { }
65
 
66
  ~Plugin()
67
  { }
68
 
69
  // Load the library and call its entry point.
70
  void
71
  load();
72
 
73
  // Call the claim-file handler.
74
  bool
75
  claim_file(struct ld_plugin_input_file* plugin_input_file);
76
 
77
  // Call the all-symbols-read handler.
78
  void
79
  all_symbols_read();
80
 
81
  // Call the cleanup handler.
82
  void
83
  cleanup();
84
 
85
  // Register a claim-file handler.
86
  void
87
  set_claim_file_handler(ld_plugin_claim_file_handler handler)
88
  { this->claim_file_handler_ = handler; }
89
 
90
  // Register an all-symbols-read handler.
91
  void
92
  set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler)
93
  { this->all_symbols_read_handler_ = handler; }
94
 
95
  // Register a claim-file handler.
96
  void
97
  set_cleanup_handler(ld_plugin_cleanup_handler handler)
98
  { this->cleanup_handler_ = handler; }
99
 
100
  // Add an argument
101
  void
102
  add_option(const char* arg)
103
  {
104
    this->args_.push_back(arg);
105
  }
106
 
107
 private:
108
  Plugin(const Plugin&);
109
  Plugin& operator=(const Plugin&);
110
 
111
  // The shared library handle returned by dlopen.
112
  void* handle_;
113
  // The argument string given to --plugin.
114
  std::string filename_;
115
  // The list of argument string given to --plugin-opt.
116
  std::vector<std::string> args_;
117
  // The plugin's event handlers.
118
  ld_plugin_claim_file_handler claim_file_handler_;
119
  ld_plugin_all_symbols_read_handler all_symbols_read_handler_;
120
  ld_plugin_cleanup_handler cleanup_handler_;
121
  // TRUE if the cleanup handlers have been called.
122
  bool cleanup_done_;
123
};
124
 
125
// A manager class for plugins.
126
 
127
class Plugin_manager
128
{
129
 public:
130
  Plugin_manager(const General_options& options)
131
    : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL),
132
      plugin_input_file_(), rescannable_(), undefined_symbols_(),
133
      any_claimed_(false), in_replacement_phase_(false), any_added_(false),
134
      options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL),
135
      symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL),
136
      this_blocker_(NULL), extra_search_path_()
137
  { this->current_ = plugins_.end(); }
138
 
139
  ~Plugin_manager();
140
 
141
  // Add a plugin library.
142
  void
143
  add_plugin(const char* filename)
144
  { this->plugins_.push_back(new Plugin(filename)); }
145
 
146
  // Add an argument to the current plugin.
147
  void
148
  add_plugin_option(const char* opt)
149
  {
150
    Plugin* last = this->plugins_.back();
151
    last->add_option(opt);
152
  }
153
 
154
  // Load all plugin libraries.
155
  void
156
  load_plugins();
157
 
158
  // Call the plugin claim-file handlers in turn to see if any claim the file.
159
  Pluginobj*
160
  claim_file(Input_file* input_file, off_t offset, off_t filesize);
161
 
162
  // Let the plugin manager save an archive for later rescanning.
163
  // This takes ownership of the Archive pointer.
164
  void
165
  save_archive(Archive*);
166
 
167
  // Let the plugin manager save an input group for later rescanning.
168
  // This takes ownership of the Input_group pointer.
169
  void
170
  save_input_group(Input_group*);
171
 
172
  // Call the all-symbols-read handlers.
173
  void
174
  all_symbols_read(Workqueue* workqueue, Task* task,
175
                   Input_objects* input_objects, Symbol_table* symtab,
176
                   Layout* layout, Dirsearch* dirpath, Mapfile* mapfile,
177
                   Task_token** last_blocker);
178
 
179
  // Tell the plugin manager that we've a new undefined symbol which
180
  // may require rescanning.
181
  void
182
  new_undefined_symbol(Symbol*);
183
 
184
  // Run deferred layout.
185
  void
186
  layout_deferred_objects();
187
 
188
  // Call the cleanup handlers.
189
  void
190
  cleanup();
191
 
192
  // Register a claim-file handler.
193
  void
194
  set_claim_file_handler(ld_plugin_claim_file_handler handler)
195
  {
196
    gold_assert(this->current_ != plugins_.end());
197
    (*this->current_)->set_claim_file_handler(handler);
198
  }
199
 
200
  // Register an all-symbols-read handler.
201
  void
202
  set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler)
203
  {
204
    gold_assert(this->current_ != plugins_.end());
205
    (*this->current_)->set_all_symbols_read_handler(handler);
206
  }
207
 
208
  // Register a claim-file handler.
209
  void
210
  set_cleanup_handler(ld_plugin_cleanup_handler handler)
211
  {
212
    gold_assert(this->current_ != plugins_.end());
213
    (*this->current_)->set_cleanup_handler(handler);
214
  }
215
 
216
  // Make a new Pluginobj object.  This is called when the plugin calls
217
  // the add_symbols API.
218
  Pluginobj*
219
  make_plugin_object(unsigned int handle);
220
 
221
  // Return the Pluginobj associated with the given HANDLE.
222
  Pluginobj*
223
  object(unsigned int handle) const
224
  {
225
    if (handle >= this->objects_.size())
226
      return NULL;
227
    return this->objects_[handle];
228
  }
229
 
230
  // Return TRUE if any input files have been claimed by a plugin
231
  // and we are still in the initial input phase.
232
  bool
233
  should_defer_layout() const
234
  { return !this->objects_.empty() && !this->in_replacement_phase_; }
235
 
236
  // Add a regular object to the deferred layout list.  These are
237
  // objects whose layout has been deferred until after the
238
  // replacement files have arrived.
239
  void
240
  add_deferred_layout_object(Relobj* obj)
241
  { this->deferred_layout_objects_.push_back(obj); }
242
 
243
  // Get input file information with an open (possibly re-opened)
244
  // file descriptor.
245
  ld_plugin_status
246
  get_input_file(unsigned int handle, struct ld_plugin_input_file* file);
247
 
248
  ld_plugin_status
249
  get_view(unsigned int handle, const void **viewp);
250
 
251
  // Release an input file.
252
  ld_plugin_status
253
  release_input_file(unsigned int handle);
254
 
255
  // Add a new input file.
256
  ld_plugin_status
257
  add_input_file(const char* pathname, bool is_lib);
258
 
259
  // Set the extra library path.
260
  ld_plugin_status
261
  set_extra_library_path(const char* path);
262
 
263
  // Return TRUE if we are in the replacement phase.
264
  bool
265
  in_replacement_phase() const
266
  { return this->in_replacement_phase_; }
267
 
268
 private:
269
  Plugin_manager(const Plugin_manager&);
270
  Plugin_manager& operator=(const Plugin_manager&);
271
 
272
  // Plugin_rescan is a Task which calls the private rescan method.
273
  friend class Plugin_rescan;
274
 
275
  // An archive or input group which may have to be rescanned if a
276
  // plugin adds a new file.
277
  struct Rescannable
278
  {
279
    bool is_archive;
280
    union
281
    {
282
      Archive* archive;
283
      Input_group* input_group;
284
    } u;
285
 
286
    Rescannable(Archive* archive)
287
      : is_archive(true)
288
    { this->u.archive = archive; }
289
 
290
    Rescannable(Input_group* input_group)
291
      : is_archive(false)
292
    { this->u.input_group = input_group; }
293
  };
294
 
295
  typedef std::list<Plugin*> Plugin_list;
296
  typedef std::vector<Pluginobj*> Object_list;
297
  typedef std::vector<Relobj*> Deferred_layout_list;
298
  typedef std::vector<Rescannable> Rescannable_list;
299
  typedef std::vector<Symbol*> Undefined_symbol_list;
300
 
301
  // Rescan archives for undefined symbols.
302
  void
303
  rescan(Task*);
304
 
305
  // See whether the rescannable at index I defines SYM.
306
  bool
307
  rescannable_defines(size_t i, Symbol* sym);
308
 
309
  // The list of plugin libraries.
310
  Plugin_list plugins_;
311
  // A pointer to the current plugin.  Used while loading plugins.
312
  Plugin_list::iterator current_;
313
 
314
  // The list of plugin objects.  The index of an item in this list
315
  // serves as the "handle" that we pass to the plugins.
316
  Object_list objects_;
317
 
318
  // The list of regular objects whose layout has been deferred.
319
  Deferred_layout_list deferred_layout_objects_;
320
 
321
  // The file currently up for claim by the plugins.
322
  Input_file* input_file_;
323
  struct ld_plugin_input_file plugin_input_file_;
324
 
325
  // A list of archives and input groups being saved for possible
326
  // later rescanning.
327
  Rescannable_list rescannable_;
328
 
329
  // A list of undefined symbols found in added files.
330
  Undefined_symbol_list undefined_symbols_;
331
 
332
  // Whether any input files have been claimed by a plugin.
333
  bool any_claimed_;
334
 
335
  // Set to true after the all symbols read event; indicates that we
336
  // are processing replacement files whose symbols should replace the
337
  // placeholder symbols from the Pluginobj objects.
338
  bool in_replacement_phase_;
339
 
340
  // Whether any input files or libraries were added by a plugin.
341
  bool any_added_;
342
 
343
  const General_options& options_;
344
  Workqueue* workqueue_;
345
  Task* task_;
346
  Input_objects* input_objects_;
347
  Symbol_table* symtab_;
348
  Layout* layout_;
349
  Dirsearch* dirpath_;
350
  Mapfile* mapfile_;
351
  Task_token* this_blocker_;
352
 
353
  // An extra directory to seach for the libraries passed by
354
  // add_input_library.
355
  std::string extra_search_path_;
356
};
357
 
358
 
359
// An object file claimed by a plugin.  This is an abstract base class.
360
// The implementation is the template class Sized_pluginobj.
361
 
362
class Pluginobj : public Object
363
{
364
 public:
365
 
366
  typedef std::vector<Symbol*> Symbols;
367
 
368
  Pluginobj(const std::string& name, Input_file* input_file, off_t offset,
369
            off_t filesize);
370
 
371
  // Fill in the symbol resolution status for the given plugin symbols.
372
  ld_plugin_status
373
  get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const;
374
 
375
  // Store the incoming symbols from the plugin for later processing.
376
  void
377
  store_incoming_symbols(int nsyms, const struct ld_plugin_symbol* syms)
378
  {
379
    this->nsyms_ = nsyms;
380
    this->syms_ = syms;
381
  }
382
 
383
  // Return TRUE if the comdat group with key COMDAT_KEY from this object
384
  // should be kept.
385
  bool
386
  include_comdat_group(std::string comdat_key, Layout* layout);
387
 
388
  // Return the filename.
389
  const std::string&
390
  filename() const
391
  { return this->input_file()->filename(); }
392
 
393
  // Return the file descriptor.
394
  int
395
  descriptor()
396
  { return this->input_file()->file().descriptor(); }
397
 
398
  // Return the size of the file or archive member.
399
  off_t
400
  filesize()
401
  { return this->filesize_; }
402
 
403
 protected:
404
  // Return TRUE if this is an object claimed by a plugin.
405
  virtual Pluginobj*
406
  do_pluginobj()
407
  { return this; }
408
 
409
  // The number of symbols provided by the plugin.
410
  int nsyms_;
411
 
412
  // The symbols provided by the plugin.
413
  const struct ld_plugin_symbol* syms_;
414
 
415
  // The entries in the symbol table for the external symbols.
416
  Symbols symbols_;
417
 
418
 private:
419
  // Size of the file (or archive member).
420
  off_t filesize_;
421
  // Map a comdat key symbol to a boolean indicating whether the comdat
422
  // group in this object with that key should be kept.
423
  typedef Unordered_map<std::string, bool> Comdat_map;
424
  Comdat_map comdat_map_;
425
};
426
 
427
// A plugin object, size-specific version.
428
 
429
template<int size, bool big_endian>
430
class Sized_pluginobj : public Pluginobj
431
{
432
 public:
433
  Sized_pluginobj(const std::string& name, Input_file* input_file,
434
                  off_t offset, off_t filesize);
435
 
436
  // Read the symbols.
437
  void
438
  do_read_symbols(Read_symbols_data*);
439
 
440
  // Lay out the input sections.
441
  void
442
  do_layout(Symbol_table*, Layout*, Read_symbols_data*);
443
 
444
  // Add the symbols to the symbol table.
445
  void
446
  do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);
447
 
448
  Archive::Should_include
449
  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
450
                           std::string* why);
451
 
452
  // Iterate over global symbols, calling a visitor class V for each.
453
  void
454
  do_for_all_global_symbols(Read_symbols_data* sd,
455
                            Library_base::Symbol_visitor_base* v);
456
 
457
  // Iterate over local symbols, calling a visitor class V for each GOT offset
458
  // associated with a local symbol.
459
  void
460
  do_for_all_local_got_entries(Got_offset_list::Visitor* v) const;
461
 
462
  // Get the size of a section.
463
  uint64_t
464
  do_section_size(unsigned int shndx);
465
 
466
  // Get the name of a section.
467
  std::string
468
  do_section_name(unsigned int shndx);
469
 
470
  // Return a view of the contents of a section.
471
  Object::Location
472
  do_section_contents(unsigned int shndx);
473
 
474
  // Return section flags.
475
  uint64_t
476
  do_section_flags(unsigned int shndx);
477
 
478
  // Return section entsize.
479
  uint64_t
480
  do_section_entsize(unsigned int shndx);
481
 
482
  // Return section address.
483
  uint64_t
484
  do_section_address(unsigned int shndx);
485
 
486
  // Return section type.
487
  unsigned int
488
  do_section_type(unsigned int shndx);
489
 
490
  // Return the section link field.
491
  unsigned int
492
  do_section_link(unsigned int shndx);
493
 
494
  // Return the section link field.
495
  unsigned int
496
  do_section_info(unsigned int shndx);
497
 
498
  // Return the section alignment.
499
  uint64_t
500
  do_section_addralign(unsigned int shndx);
501
 
502
  // Return the Xindex structure to use.
503
  Xindex*
504
  do_initialize_xindex();
505
 
506
  // Get symbol counts.
507
  void
508
  do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
509
 
510
  // Get global symbols.
511
  const Symbols*
512
  do_get_global_symbols() const;
513
 
514
  // Add placeholder symbols from a claimed file.
515
  ld_plugin_status
516
  add_symbols_from_plugin(int nsyms, const ld_plugin_symbol* syms);
517
 
518
 protected:
519
 
520
 private:
521
};
522
 
523
// This Task handles handles the "all symbols read" event hook.
524
// The plugin may add additional input files at this time, which must
525
// be queued for reading.
526
 
527
class Plugin_hook : public Task
528
{
529
 public:
530
  Plugin_hook(const General_options& options, Input_objects* input_objects,
531
              Symbol_table* symtab, Layout* layout, Dirsearch* dirpath,
532
              Mapfile* mapfile, Task_token* this_blocker,
533
              Task_token* next_blocker)
534
    : options_(options), input_objects_(input_objects), symtab_(symtab),
535
      layout_(layout), dirpath_(dirpath), mapfile_(mapfile),
536
      this_blocker_(this_blocker), next_blocker_(next_blocker)
537
  { }
538
 
539
  ~Plugin_hook();
540
 
541
  // The standard Task methods.
542
 
543
  Task_token*
544
  is_runnable();
545
 
546
  void
547
  locks(Task_locker*);
548
 
549
  void
550
  run(Workqueue*);
551
 
552
  std::string
553
  get_name() const
554
  { return "Plugin_hook"; }
555
 
556
 private:
557
  const General_options& options_;
558
  Input_objects* input_objects_;
559
  Symbol_table* symtab_;
560
  Layout* layout_;
561
  Dirsearch* dirpath_;
562
  Mapfile* mapfile_;
563
  Task_token* this_blocker_;
564
  Task_token* next_blocker_;
565
};
566
 
567
} // End namespace gold.
568
 
569
#endif // !defined(GOLD_PLUGIN_H)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.