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 303

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