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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [plugin.cc] - Blame information for rev 160

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

Line No. Rev Author Line
1 27 khays
// plugin.cc -- 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
#include "gold.h"
24
 
25
#include <cstdio>
26
#include <cstdarg>
27
#include <cstring>
28
#include <string>
29
#include <vector>
30
 
31
#ifdef ENABLE_PLUGINS
32
#include <dlfcn.h>
33
#endif
34
 
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
 
46
namespace gold
47
{
48
 
49
#ifdef ENABLE_PLUGINS
50
 
51
// The linker's exported interfaces.
52
 
53
extern "C"
54
{
55
 
56
static enum ld_plugin_status
57
register_claim_file(ld_plugin_claim_file_handler handler);
58
 
59
static enum ld_plugin_status
60
register_all_symbols_read(ld_plugin_all_symbols_read_handler handler);
61
 
62
static enum ld_plugin_status
63
register_cleanup(ld_plugin_cleanup_handler handler);
64
 
65
static enum ld_plugin_status
66
add_symbols(void *handle, int nsyms, const struct ld_plugin_symbol *syms);
67
 
68
static enum ld_plugin_status
69
get_input_file(const void *handle, struct ld_plugin_input_file *file);
70
 
71
static enum ld_plugin_status
72
get_view(const void *handle, const void **viewp);
73
 
74
static enum ld_plugin_status
75
release_input_file(const void *handle);
76
 
77
static enum ld_plugin_status
78
get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms);
79
 
80
static enum ld_plugin_status
81
add_input_file(const char *pathname);
82
 
83
static enum ld_plugin_status
84
add_input_library(const char *pathname);
85
 
86
static enum ld_plugin_status
87
set_extra_library_path(const char *path);
88
 
89
static enum ld_plugin_status
90
message(int level, const char *format, ...);
91
 
92 159 khays
static enum ld_plugin_status
93
get_input_section_count(const void* handle, unsigned int* count);
94
 
95
static enum ld_plugin_status
96
get_input_section_type(const struct ld_plugin_section section,
97
                       unsigned int* type);
98
 
99
static enum ld_plugin_status
100
get_input_section_name(const struct ld_plugin_section section,
101
                       char** section_name_ptr);
102
 
103
static enum ld_plugin_status
104
get_input_section_contents(const struct ld_plugin_section section,
105
                           const unsigned char** section_contents,
106
                           size_t* len);
107
 
108
static enum ld_plugin_status
109
update_section_order(const struct ld_plugin_section *section_list,
110
                     unsigned int num_sections);
111
 
112
static enum ld_plugin_status
113
allow_section_ordering();
114
 
115 27 khays
};
116
 
117
#endif // ENABLE_PLUGINS
118
 
119
static Pluginobj* make_sized_plugin_object(Input_file* input_file,
120
                                           off_t offset, off_t filesize);
121
 
122
// Plugin methods.
123
 
124
// Load one plugin library.
125
 
126
void
127
Plugin::load()
128
{
129
#ifdef ENABLE_PLUGINS
130
  // Load the plugin library.
131
  // FIXME: Look for the library in standard locations.
132
  this->handle_ = dlopen(this->filename_.c_str(), RTLD_NOW);
133
  if (this->handle_ == NULL)
134
    {
135
      gold_error(_("%s: could not load plugin library: %s"),
136
                 this->filename_.c_str(), dlerror());
137
      return;
138
    }
139
 
140
  // Find the plugin's onload entry point.
141
  void* ptr = dlsym(this->handle_, "onload");
142
  if (ptr == NULL)
143
    {
144
      gold_error(_("%s: could not find onload entry point"),
145
                 this->filename_.c_str());
146
      return;
147
    }
148
  ld_plugin_onload onload;
149
  gold_assert(sizeof(onload) == sizeof(ptr));
150
  memcpy(&onload, &ptr, sizeof(ptr));
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.
159 159 khays
  const int tv_fixed_size = 23;
160
 
161 27 khays
  int tv_size = this->args_.size() + tv_fixed_size;
162
  ld_plugin_tv* tv = new ld_plugin_tv[tv_size];
163
 
164
  // Put LDPT_MESSAGE at the front of the list so the plugin can use it
165
  // while processing subsequent entries.
166
  int i = 0;
167
  tv[i].tv_tag = LDPT_MESSAGE;
168
  tv[i].tv_u.tv_message = message;
169
 
170
  ++i;
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
 
187
  ++i;
188
  tv[i].tv_tag = LDPT_OUTPUT_NAME;
189
  tv[i].tv_u.tv_string = parameters->options().output();
190
 
191
  for (unsigned int j = 0; j < this->args_.size(); ++j)
192
    {
193
      ++i;
194
      tv[i].tv_tag = LDPT_OPTION;
195
      tv[i].tv_u.tv_string = this->args_[j].c_str();
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
 
214
  ++i;
215
  tv[i].tv_tag = LDPT_GET_INPUT_FILE;
216
  tv[i].tv_u.tv_get_input_file = get_input_file;
217
 
218
  ++i;
219
  tv[i].tv_tag = LDPT_GET_VIEW;
220
  tv[i].tv_u.tv_get_view = get_view;
221
 
222
  ++i;
223
  tv[i].tv_tag = LDPT_RELEASE_INPUT_FILE;
224
  tv[i].tv_u.tv_release_input_file = release_input_file;
225
 
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
 
234
  ++i;
235
  tv[i].tv_tag = LDPT_ADD_INPUT_LIBRARY;
236
  tv[i].tv_u.tv_add_input_library = add_input_library;
237
 
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
 
242
  ++i;
243 159 khays
  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
 
266
  ++i;
267 27 khays
  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
 
275
  delete[] tv;
276
#endif // ENABLE_PLUGINS
277
}
278
 
279
// Call the plugin claim-file handler.
280
 
281
inline bool
282
Plugin::claim_file(struct ld_plugin_input_file* plugin_input_file)
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
 
297
inline void
298
Plugin::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
 
306
inline void
307
Plugin::cleanup()
308
{
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
    }
317
}
318
 
319
// This task is used to rescan archives as needed.
320
 
321
class 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
 
358
// Plugin_manager methods.
359
 
360
Plugin_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
 
376
void
377 159 khays
Plugin_manager::load_plugins(Layout* layout)
378 27 khays
{
379 159 khays
  this->layout_ = layout;
380 27 khays
  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
 
388
Pluginobj*
389
Plugin_manager::claim_file(Input_file* input_file, off_t offset,
390 159 khays
                           off_t filesize, Object* elf_object)
391 27 khays
{
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);
402 159 khays
  if (elf_object != NULL)
403
    this->objects_.push_back(elf_object);
404
  this->in_claim_file_handler_ = true;
405 27 khays
 
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
        {
412
          this->any_claimed_ = true;
413 159 khays
          this->in_claim_file_handler_ = false;
414 27 khays
 
415 159 khays
          if (this->objects_.size() > handle
416
              && this->objects_[handle]->pluginobj() != NULL)
417
            return this->objects_[handle]->pluginobj();
418 27 khays
 
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;
423
        }
424
    }
425
 
426 159 khays
  this->in_claim_file_handler_ = false;
427 27 khays
  return NULL;
428
}
429
 
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
 
435
void
436
Plugin_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
 
446
void
447
Plugin_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
 
455
// Call the all-symbols-read handlers.
456
 
457
void
458
Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
459
                                 Input_objects* input_objects,
460 159 khays
                                 Symbol_table* symtab,
461 27 khays
                                 Dirsearch* dirpath, Mapfile* mapfile,
462
                                 Task_token** last_blocker)
463
{
464
  this->in_replacement_phase_ = true;
465
  this->workqueue_ = workqueue;
466
  this->task_ = task;
467
  this->input_objects_ = input_objects;
468
  this->symtab_ = symtab;
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
 
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
 
486
  *last_blocker = this->this_blocker_;
487
}
488
 
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
 
493
void
494
Plugin_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
 
504
void
505
Plugin_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
 
599
bool
600
Plugin_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
 
618
// Layout deferred objects.
619
 
620
void
621
Plugin_manager::layout_deferred_objects()
622
{
623
  Deferred_layout_list::iterator obj;
624
 
625
  for (obj = this->deferred_layout_objects_.begin();
626
       obj != this->deferred_layout_objects_.end();
627
       ++obj)
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
    }
636
}
637
 
638
// Call the cleanup handlers.
639
 
640
void
641
Plugin_manager::cleanup()
642
{
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
 
652
Pluginobj*
653
Plugin_manager::make_plugin_object(unsigned int handle)
654
{
655
  // Make sure we aren't asked to make an object for the same handle twice.
656 159 khays
  if (this->objects_.size() != handle
657
      && this->objects_[handle]->pluginobj() != NULL)
658 27 khays
    return NULL;
659
 
660
  Pluginobj* obj = make_sized_plugin_object(this->input_file_,
661
                                            this->plugin_input_file_.offset,
662
                                            this->plugin_input_file_.filesize);
663 159 khays
 
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
 
670 27 khays
  this->objects_.push_back(obj);
671
  return obj;
672
}
673
 
674
// Get the input file information with an open (possibly re-opened)
675
// file descriptor.
676
 
677
ld_plugin_status
678
Plugin_manager::get_input_file(unsigned int handle,
679
                               struct ld_plugin_input_file* file)
680
{
681 159 khays
  Pluginobj* obj = this->object(handle)->pluginobj();
682 27 khays
  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
 
696
ld_plugin_status
697
Plugin_manager::release_input_file(unsigned int handle)
698
{
699 159 khays
  if (this->object(handle) == NULL)
700
    return LDPS_BAD_HANDLE;
701
 
702
  Pluginobj* obj = this->object(handle)->pluginobj();
703
 
704 27 khays
  if (obj == NULL)
705
    return LDPS_BAD_HANDLE;
706
 
707
  obj->unlock(this->task_);
708
  return LDPS_OK;
709
}
710
 
711 159 khays
// Get the elf object corresponding to the handle. Return NULL if we
712
// found a Pluginobj instead.
713
 
714
Object*
715
Plugin_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
 
728 27 khays
ld_plugin_status
729
Plugin_manager::get_view(unsigned int handle, const void **viewp)
730
{
731
  off_t offset;
732
  size_t filesize;
733
  Input_file *input_file;
734 159 khays
  if (this->in_claim_file_handler_)
735 27 khays
    {
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.
745 159 khays
      if (this->object(handle) == NULL)
746
        return LDPS_BAD_HANDLE;
747
      Pluginobj* obj = this->object(handle)->pluginobj();
748 27 khays
      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
 
759
// Add a new library path.
760
 
761
ld_plugin_status
762
Plugin_manager::set_extra_library_path(const char* path)
763
{
764
  this->extra_search_path_ = std::string(path);
765
  return LDPS_OK;
766
}
767
 
768
// Add a new input file.
769
 
770
ld_plugin_status
771
Plugin_manager::add_input_file(const char* pathname, bool is_lib)
772
{
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),
777
                           (is_lib
778
                            ? this->extra_search_path_.c_str()
779
                            : ""),
780
                           false,
781
                           this->options_);
782
  Input_argument* input_argument = new Input_argument(file);
783
  Task_token* next_blocker = new Task_token(true);
784
  next_blocker->add_blocker();
785
  if (parameters->incremental())
786
    gold_error(_("input files added by plug-ins in --incremental mode not "
787
                 "supported yet"));
788
  this->workqueue_->queue_soon(new Read_symbols(this->input_objects_,
789
                                                this->symtab_,
790
                                                this->layout_,
791
                                                this->dirpath_,
792
                                                0,
793
                                                this->mapfile_,
794
                                                input_argument,
795
                                                NULL,
796
                                                NULL,
797
                                                this->this_blocker_,
798
                                                next_blocker));
799
  this->this_blocker_ = next_blocker;
800
  this->any_added_ = true;
801
  return LDPS_OK;
802
}
803
 
804
// Class Pluginobj.
805
 
806
Pluginobj::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_()
810
{
811
}
812
 
813
// Return TRUE if a defined symbol might be reachable from outside the
814
// universe of claimed objects.
815
 
816
static inline bool
817
is_visible_from_outside(Symbol* lsym)
818
{
819
  if (lsym->in_real_elf())
820
    return true;
821
  if (parameters->options().relocatable())
822
    return true;
823
  if (parameters->options().is_undefined(lsym->name()))
824
    return true;
825
  if (parameters->options().export_dynamic() || parameters->options().shared())
826
    return lsym->is_externally_visible();
827
  return false;
828
}
829
 
830
// Get symbol resolution info.
831
 
832
ld_plugin_status
833
Pluginobj::get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const
834
{
835
  if (nsyms > this->nsyms_)
836
    return LDPS_NO_SYMS;
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.
842
      gold_assert(this->symbols_.size() == 0);
843
      for (int i = 0; i < nsyms; i++)
844
        syms[i].resolution = LDPR_PREEMPTED_REG;
845
      return LDPS_OK;
846
    }
847
 
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;
864
          else if (lsym->object()->pluginobj() == this)
865
            res = (is_visible_from_outside(lsym)
866
                   ? LDPR_PREVAILING_DEF
867
                   : LDPR_PREVAILING_DEF_IRONLY);
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))
881
            res = (is_visible_from_outside(lsym)
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
 
897
bool
898
Pluginobj::include_comdat_group(std::string comdat_key, Layout* layout)
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)
906
    ins.first->second = layout->find_or_add_kept_section(comdat_key,
907
                                                         NULL, 0, true,
908
                                                         true, NULL);
909
 
910
  return ins.first->second;
911
}
912
 
913
// Class Sized_pluginobj.
914
 
915
template<int size, bool big_endian>
916
Sized_pluginobj<size, big_endian>::Sized_pluginobj(
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)
922
{
923
}
924
 
925
// Read the symbols.  Not used for plugin objects.
926
 
927
template<int size, bool big_endian>
928
void
929
Sized_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
 
936
template<int size, bool big_endian>
937
void
938
Sized_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
 
946
template<int size, bool big_endian>
947
void
948
Sized_pluginobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
949
                                                  Read_symbols_data*,
950
                                                  Layout* layout)
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
    {
963
      const struct ld_plugin_symbol* isym = &this->syms_[i];
964
      const char* name = isym->name;
965
      const char* ver = isym->version;
966
      elfcpp::Elf_Half shndx;
967
      elfcpp::STB bind;
968
      elfcpp::STV vis;
969
 
970
      if (name != NULL && name[0] == '\0')
971
        name = NULL;
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:
1008
          vis = elfcpp::STV_PROTECTED;
1009
          break;
1010
        case LDPV_INTERNAL:
1011
          vis = elfcpp::STV_INTERNAL;
1012
          break;
1013
        case LDPV_HIDDEN:
1014
          vis = elfcpp::STV_HIDDEN;
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'
1024
          && !this->include_comdat_group(isym->comdat_key, layout))
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] =
1035
        symtab->add_from_pluginobj<size, big_endian>(this, name, ver, &sym);
1036
    }
1037
}
1038
 
1039
template<int size, bool big_endian>
1040
Archive::Should_include
1041
Sized_pluginobj<size, big_endian>::do_should_include_member(
1042
    Symbol_table* symtab,
1043
    Layout* layout,
1044
    Read_symbols_data*,
1045
    std::string* why)
1046
{
1047
  char* tmpbuf = NULL;
1048
  size_t tmpbuflen = 0;
1049
 
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);
1061
      if (t == Archive::SHOULD_INCLUDE_YES)
1062
        {
1063
          if (tmpbuf != NULL)
1064
            free(tmpbuf);
1065
          return t;
1066
        }
1067
    }
1068
  if (tmpbuf != NULL)
1069
    free(tmpbuf);
1070
  return Archive::SHOULD_INCLUDE_UNKNOWN;
1071
}
1072
 
1073
// Iterate over global symbols, calling a visitor class V for each.
1074
 
1075
template<int size, bool big_endian>
1076
void
1077
Sized_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
 
1089
// Iterate over local symbols, calling a visitor class V for each GOT offset
1090
// associated with a local symbol.
1091
template<int size, bool big_endian>
1092
void
1093
Sized_pluginobj<size, big_endian>::do_for_all_local_got_entries(
1094
    Got_offset_list::Visitor*) const
1095
{
1096
  gold_unreachable();
1097
}
1098
 
1099
// Get the size of a section.  Not used for plugin objects.
1100
 
1101
template<int size, bool big_endian>
1102
uint64_t
1103
Sized_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
 
1111
template<int size, bool big_endian>
1112
std::string
1113
Sized_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
 
1121
template<int size, bool big_endian>
1122
Object::Location
1123
Sized_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
 
1133
template<int size, bool big_endian>
1134
uint64_t
1135
Sized_pluginobj<size, big_endian>::do_section_flags(unsigned int)
1136
{
1137
  gold_unreachable();
1138
  return 0;
1139
}
1140
 
1141
// Return section entsize.  Not used for plugin objects.
1142
 
1143
template<int size, bool big_endian>
1144
uint64_t
1145
Sized_pluginobj<size, big_endian>::do_section_entsize(unsigned int)
1146
{
1147
  gold_unreachable();
1148
  return 0;
1149
}
1150
 
1151
// Return section address.  Not used for plugin objects.
1152
 
1153
template<int size, bool big_endian>
1154
uint64_t
1155
Sized_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
 
1163
template<int size, bool big_endian>
1164
unsigned int
1165
Sized_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
 
1173
template<int size, bool big_endian>
1174
unsigned int
1175
Sized_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
 
1183
template<int size, bool big_endian>
1184
unsigned int
1185
Sized_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
 
1193
template<int size, bool big_endian>
1194
uint64_t
1195
Sized_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
 
1203
template<int size, bool big_endian>
1204
Xindex*
1205
Sized_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
 
1213
template<int size, bool big_endian>
1214
void
1215
Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(const Symbol_table*,
1216
                                                   size_t*, size_t*) const
1217
{
1218
  gold_unreachable();
1219
}
1220
 
1221
// Get symbols.  Not used for plugin objects.
1222
 
1223
template<int size, bool big_endian>
1224
const Object::Symbols*
1225
Sized_pluginobj<size, big_endian>::do_get_global_symbols() const
1226
{
1227
  gold_unreachable();
1228
}
1229
 
1230
// Class Plugin_finish.  This task runs after all replacement files have
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.
1235
 
1236
class Plugin_finish : public Task
1237
{
1238
 public:
1239
  Plugin_finish(Task_token* this_blocker, Task_token* next_blocker)
1240
    : this_blocker_(this_blocker), next_blocker_(next_blocker)
1241
  { }
1242
 
1243
  ~Plugin_finish()
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*)
1263
  {
1264
    // We could call early cleanup handlers here.
1265
  }
1266
 
1267
  std::string
1268
  get_name() const
1269
  { return "Plugin_finish"; }
1270
 
1271
 private:
1272
  Task_token* this_blocker_;
1273
  Task_token* next_blocker_;
1274
};
1275
 
1276
// Class Plugin_hook.
1277
 
1278
Plugin_hook::~Plugin_hook()
1279
{
1280
}
1281
 
1282
// Return whether a Plugin_hook task is runnable.
1283
 
1284
Task_token*
1285
Plugin_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
 
1295
void
1296
Plugin_hook::locks(Task_locker*)
1297
{
1298
}
1299
 
1300
// Run the "all symbols read" plugin hook.
1301
 
1302
void
1303
Plugin_hook::run(Workqueue* workqueue)
1304
{
1305
  gold_assert(this->options_.has_plugins());
1306
  Symbol* start_sym = this->symtab_->lookup(parameters->entry());
1307
  if (start_sym != NULL)
1308
    start_sym->set_in_real_elf();
1309
 
1310
  this->options_.plugins()->all_symbols_read(workqueue,
1311
                                             this,
1312
                                             this->input_objects_,
1313
                                             this->symtab_,
1314
                                             this->dirpath_,
1315
                                             this->mapfile_,
1316
                                             &this->this_blocker_);
1317
  workqueue->queue_soon(new Plugin_finish(this->this_blocker_,
1318
                                          this->next_blocker_));
1319
}
1320
 
1321
// The C interface routines called by the plugins.
1322
 
1323
#ifdef ENABLE_PLUGINS
1324
 
1325
// Register a claim-file handler.
1326
 
1327
static enum ld_plugin_status
1328
register_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
 
1337
static enum ld_plugin_status
1338
register_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
 
1347
static enum ld_plugin_status
1348
register_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
 
1357
static enum ld_plugin_status
1358
add_symbols(void* handle, int nsyms, const ld_plugin_symbol* syms)
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
 
1369
// Get the input file information with an open (possibly re-opened)
1370
// file descriptor.
1371
 
1372
static enum ld_plugin_status
1373
get_input_file(const void* handle, struct ld_plugin_input_file* file)
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
 
1383
static enum ld_plugin_status
1384
release_input_file(const void* handle)
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
 
1392
static enum ld_plugin_status
1393
get_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
 
1401
// Get the symbol resolution info for a plugin-claimed input file.
1402
 
1403
static enum ld_plugin_status
1404
get_symbols(const void* handle, int nsyms, ld_plugin_symbol* syms)
1405
{
1406
  gold_assert(parameters->options().has_plugins());
1407 159 khays
  Object* obj = parameters->options().plugins()->object(
1408
    static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
1409 27 khays
  if (obj == NULL)
1410
    return LDPS_ERR;
1411 159 khays
  Pluginobj* plugin_obj = obj->pluginobj();
1412
  if (plugin_obj == NULL)
1413
    return LDPS_ERR;
1414
  return plugin_obj->get_symbol_resolution_info(nsyms, syms);
1415 27 khays
}
1416
 
1417
// Add a new (real) input file generated by a plugin.
1418
 
1419
static enum ld_plugin_status
1420
add_input_file(const char* pathname)
1421
{
1422
  gold_assert(parameters->options().has_plugins());
1423
  return parameters->options().plugins()->add_input_file(pathname, false);
1424
}
1425
 
1426
// Add a new (real) library required by a plugin.
1427
 
1428
static enum ld_plugin_status
1429
add_input_library(const char* pathname)
1430
{
1431
  gold_assert(parameters->options().has_plugins());
1432
  return parameters->options().plugins()->add_input_file(pathname, true);
1433
}
1434
 
1435
// Set the extra library path to be used by libraries added via
1436
// add_input_library
1437
 
1438
static enum ld_plugin_status
1439
set_extra_library_path(const char* path)
1440
{
1441
  gold_assert(parameters->options().has_plugins());
1442
  return parameters->options().plugins()->set_extra_library_path(path);
1443
}
1444
 
1445
// Issue a diagnostic message from a plugin.
1446
 
1447
static enum ld_plugin_status
1448
message(int level, const char* format, ...)
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
 
1474 159 khays
// 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
 
1477
static enum ld_plugin_status
1478
get_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
 
1498
static enum ld_plugin_status
1499
get_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
 
1521
static enum ld_plugin_status
1522
get_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
 
1549
static enum ld_plugin_status
1550
get_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
 
1579
static enum ld_plugin_status
1580
update_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
 
1617
static enum ld_plugin_status
1618
allow_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
 
1626 27 khays
#endif // ENABLE_PLUGINS
1627
 
1628
// Allocate a Pluginobj object of the appropriate size and endianness.
1629
 
1630
static Pluginobj*
1631
make_sized_plugin_object(Input_file* input_file, off_t offset, off_t filesize)
1632
{
1633
  Pluginobj* obj = NULL;
1634
 
1635
  parameters_force_valid_target();
1636
  const Target& target(parameters->target());
1637
 
1638
  if (target.get_size() == 32)
1639
    {
1640
      if (target.is_big_endian())
1641
#ifdef HAVE_TARGET_32_BIG
1642
        obj = new Sized_pluginobj<32, true>(input_file->filename(),
1643
                                            input_file, offset, filesize);
1644
#else
1645
        gold_error(_("%s: not configured to support "
1646
                     "32-bit big-endian object"),
1647
                   input_file->filename().c_str());
1648
#endif
1649
      else
1650
#ifdef HAVE_TARGET_32_LITTLE
1651
        obj = new Sized_pluginobj<32, false>(input_file->filename(),
1652
                                             input_file, offset, filesize);
1653
#else
1654
        gold_error(_("%s: not configured to support "
1655
                     "32-bit little-endian object"),
1656
                   input_file->filename().c_str());
1657
#endif
1658
    }
1659
  else if (target.get_size() == 64)
1660
    {
1661
      if (target.is_big_endian())
1662
#ifdef HAVE_TARGET_64_BIG
1663
        obj = new Sized_pluginobj<64, true>(input_file->filename(),
1664
                                            input_file, offset, filesize);
1665
#else
1666
        gold_error(_("%s: not configured to support "
1667
                     "64-bit big-endian object"),
1668
                   input_file->filename().c_str());
1669
#endif
1670
      else
1671
#ifdef HAVE_TARGET_64_LITTLE
1672
        obj = new Sized_pluginobj<64, false>(input_file->filename(),
1673
                                             input_file, offset, filesize);
1674
#else
1675
        gold_error(_("%s: not configured to support "
1676
                     "64-bit little-endian object"),
1677
                   input_file->filename().c_str());
1678
#endif
1679
    }
1680
 
1681
  gold_assert(obj != NULL);
1682
  return obj;
1683
}
1684
 
1685
} // End namespace gold.

powered by: WebSVN 2.1.0

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