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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [plugin.c] - Blame information for rev 287

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

Line No. Rev Author Line
1 14 khays
/* Plugin support for BFD.
2 148 khays
   Copyright 2009, 2010, 2011
3 14 khays
   Free Software Foundation, Inc.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "config.h"
23
#include "bfd.h"
24
 
25
#if BFD_SUPPORTS_PLUGINS
26
 
27
#include <assert.h>
28
#include <dlfcn.h>
29
#include <stdarg.h>
30
#include "plugin-api.h"
31
#include "sysdep.h"
32
#include "plugin.h"
33
#include "libbfd.h"
34
#include "libiberty.h"
35
#include <dirent.h>
36
 
37
#define bfd_plugin_close_and_cleanup                  _bfd_generic_close_and_cleanup
38
#define bfd_plugin_bfd_free_cached_info               _bfd_generic_bfd_free_cached_info
39
#define bfd_plugin_new_section_hook                   _bfd_generic_new_section_hook
40
#define bfd_plugin_get_section_contents               _bfd_generic_get_section_contents
41
#define bfd_plugin_get_section_contents_in_window     _bfd_generic_get_section_contents_in_window
42
#define bfd_plugin_bfd_copy_private_header_data       _bfd_generic_bfd_copy_private_header_data
43
#define bfd_plugin_bfd_merge_private_bfd_data         _bfd_generic_bfd_merge_private_bfd_data
44
#define bfd_plugin_bfd_copy_private_header_data       _bfd_generic_bfd_copy_private_header_data
45
#define bfd_plugin_bfd_set_private_flags              _bfd_generic_bfd_set_private_flags
46
#define bfd_plugin_core_file_matches_executable_p     generic_core_file_matches_executable_p
47
#define bfd_plugin_bfd_is_local_label_name            _bfd_nosymbols_bfd_is_local_label_name
48
#define bfd_plugin_bfd_is_target_special_symbol       ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
49
#define bfd_plugin_get_lineno                         _bfd_nosymbols_get_lineno
50
#define bfd_plugin_find_nearest_line                  _bfd_nosymbols_find_nearest_line
51
#define bfd_plugin_find_inliner_info                  _bfd_nosymbols_find_inliner_info
52
#define bfd_plugin_bfd_make_debug_symbol              _bfd_nosymbols_bfd_make_debug_symbol
53
#define bfd_plugin_read_minisymbols                   _bfd_generic_read_minisymbols
54
#define bfd_plugin_minisymbol_to_symbol               _bfd_generic_minisymbol_to_symbol
55
#define bfd_plugin_set_arch_mach                      bfd_default_set_arch_mach
56
#define bfd_plugin_set_section_contents               _bfd_generic_set_section_contents
57
#define bfd_plugin_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
58
#define bfd_plugin_bfd_relax_section                  bfd_generic_relax_section
59
#define bfd_plugin_bfd_link_hash_table_create         _bfd_generic_link_hash_table_create
60
#define bfd_plugin_bfd_link_hash_table_free           _bfd_generic_link_hash_table_free
61
#define bfd_plugin_bfd_link_add_symbols               _bfd_generic_link_add_symbols
62
#define bfd_plugin_bfd_link_just_syms                 _bfd_generic_link_just_syms
63
#define bfd_plugin_bfd_final_link                     _bfd_generic_final_link
64
#define bfd_plugin_bfd_link_split_section             _bfd_generic_link_split_section
65
#define bfd_plugin_bfd_gc_sections                    bfd_generic_gc_sections
66 161 khays
#define bfd_plugin_bfd_lookup_section_flags           bfd_generic_lookup_section_flags
67 14 khays
#define bfd_plugin_bfd_merge_sections                 bfd_generic_merge_sections
68
#define bfd_plugin_bfd_is_group_section               bfd_generic_is_group_section
69
#define bfd_plugin_bfd_discard_group                  bfd_generic_discard_group
70
#define bfd_plugin_section_already_linked             _bfd_generic_section_already_linked
71
#define bfd_plugin_bfd_define_common_symbol           bfd_generic_define_common_symbol
72
#define bfd_plugin_bfd_copy_link_hash_symbol_type     _bfd_generic_copy_link_hash_symbol_type
73
 
74
static enum ld_plugin_status
75
message (int level ATTRIBUTE_UNUSED,
76
         const char * format, ...)
77
{
78
  va_list args;
79
  va_start (args, format);
80
  printf ("bfd plugin: ");
81
  vprintf (format, args);
82
  putchar ('\n');
83
  va_end (args);
84
  return LDPS_OK;
85
}
86
 
87
/* Register a claim-file handler. */
88
static ld_plugin_claim_file_handler claim_file;
89
 
90
static enum ld_plugin_status
91
register_claim_file (ld_plugin_claim_file_handler handler)
92
{
93
  claim_file = handler;
94
  return LDPS_OK;
95
}
96
 
97
static enum ld_plugin_status
98
add_symbols (void * handle,
99
             int nsyms,
100
             const struct ld_plugin_symbol * syms)
101
{
102
  bfd *abfd = handle;
103
  struct plugin_data_struct *plugin_data =
104
    bfd_alloc (abfd, sizeof (plugin_data_struct));;
105
 
106
  plugin_data->nsyms = nsyms;
107
  plugin_data->syms = syms;
108
 
109
  if (nsyms != 0)
110
    abfd->flags |= HAS_SYMS;
111
 
112
  abfd->tdata.plugin_data = plugin_data;
113
  return LDPS_OK;
114
}
115
 
116
static const char *plugin_program_name;
117
 
118
void
119
bfd_plugin_set_program_name (const char *program_name)
120
{
121
  plugin_program_name = program_name;
122
}
123
 
124
static int
125
try_load_plugin (const char *pname)
126
{
127
  static void *plugin_handle;
128
  int tv_size = 4;
129
  struct ld_plugin_tv tv[tv_size];
130
  int i;
131
  ld_plugin_onload onload;
132
  enum ld_plugin_status status;
133
 
134
  plugin_handle = dlopen (pname, RTLD_NOW);
135
  if (!plugin_handle)
136
    {
137
      (*_bfd_error_handler)("%s\n", dlerror ());
138
      return 0;
139
    }
140
 
141
  onload = dlsym (plugin_handle, "onload");
142
  if (!onload)
143
    goto err;
144
 
145
  i = 0;
146
  tv[i].tv_tag = LDPT_MESSAGE;
147
  tv[i].tv_u.tv_message = message;
148
 
149
  ++i;
150
  tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK;
151
  tv[i].tv_u.tv_register_claim_file = register_claim_file;
152
 
153
  ++i;
154
  tv[i].tv_tag = LDPT_ADD_SYMBOLS;
155
  tv[i].tv_u.tv_add_symbols = add_symbols;
156
 
157
  ++i;
158
  tv[i].tv_tag = LDPT_NULL;
159
  tv[i].tv_u.tv_val = 0;
160
 
161
  status = (*onload)(tv);
162
 
163
  if (status != LDPS_OK)
164
    goto err;
165
 
166
  if (!claim_file)
167
    goto err;
168
 
169
  return 1;
170
 
171
 err:
172
  plugin_handle = NULL;
173
  return 0;
174
}
175
 
176
static const char *plugin_name;
177
 
178
void
179
bfd_plugin_set_plugin (const char *p)
180
{
181
  plugin_name = p;
182
}
183
 
184
static int
185
load_plugin (void)
186
{
187
  char *plugin_dir;
188
  char *p;
189
  DIR *d;
190
  struct dirent *ent;
191
  int found = 0;
192
 
193
  if (plugin_name)
194
    return try_load_plugin (plugin_name);
195
 
196
  if (plugin_program_name == NULL)
197
    return 0;
198
 
199
  plugin_dir = concat (BINDIR, "/../lib/bfd-plugins", NULL);
200
  p = make_relative_prefix (plugin_program_name,
201
                            BINDIR,
202
                            plugin_dir);
203
  free (plugin_dir);
204
  plugin_dir = NULL;
205
 
206
  d = opendir (p);
207
  if (!d)
208
    goto out;
209
 
210
  while ((ent = readdir (d)))
211
    {
212
      char *full_name;
213
      struct stat s;
214
 
215
      full_name = concat (p, "/", ent->d_name, NULL);
216
      if (stat(full_name, &s) == 0 && S_ISREG (s.st_mode))
217
        found = try_load_plugin (full_name);
218
      free (full_name);
219
      if (found)
220
        break;
221
    }
222
 
223
 out:
224
  free (p);
225
  if (d)
226
    closedir (d);
227
 
228
  return found;
229
}
230
 
231
 
232
static const bfd_target *
233
bfd_plugin_object_p (bfd *abfd)
234
{
235
  int claimed = 0;
236
  struct ld_plugin_input_file file;
237
  bfd *iobfd;
238
  static int have_loaded = 0;
239
  static int have_plugin = 0;
240
 
241
  if (!have_loaded)
242
    {
243
      have_loaded = 1;
244
      have_plugin = load_plugin ();
245
    }
246
  if (!have_plugin)
247
    return NULL;
248
 
249
  file.name = abfd->filename;
250
 
251
  if (abfd->my_archive)
252
    {
253
      iobfd = abfd->my_archive;
254
      file.offset = abfd->origin;
255
      file.filesize = arelt_size (abfd);
256
    }
257
  else
258
    {
259
      iobfd = abfd;
260
      file.offset = 0;
261
      file.filesize = 0;
262
    }
263
 
264
  if (!iobfd->iostream && !bfd_open_file (iobfd))
265
    return NULL;
266
 
267
  file.fd = fileno ((FILE *) iobfd->iostream);
268
 
269
  if (!abfd->my_archive)
270
    {
271
      struct stat stat_buf;
272
      if (fstat (file.fd, &stat_buf))
273
        return NULL;
274
      file.filesize = stat_buf.st_size;
275
    }
276
 
277
  file.handle = abfd;
278
  off_t cur_offset = lseek(file.fd, 0, SEEK_CUR);
279
  claim_file (&file, &claimed);
280
  lseek(file.fd, cur_offset, SEEK_SET);
281
  if (!claimed)
282
    return NULL;
283
 
284
  return abfd->xvec;
285
}
286
 
287
/* Copy any private info we understand from the input bfd
288
   to the output bfd.  */
289
 
290
static bfd_boolean
291
bfd_plugin_bfd_copy_private_bfd_data (bfd *ibfd ATTRIBUTE_UNUSED,
292
                                      bfd *obfd ATTRIBUTE_UNUSED)
293
{
294
  BFD_ASSERT (0);
295
  return TRUE;
296
}
297
 
298
/* Copy any private info we understand from the input section
299
   to the output section.  */
300
 
301
static bfd_boolean
302
bfd_plugin_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
303
                                          asection *isection ATTRIBUTE_UNUSED,
304
                                          bfd *obfd ATTRIBUTE_UNUSED,
305
                                          asection *osection ATTRIBUTE_UNUSED)
306
{
307
  BFD_ASSERT (0);
308
  return TRUE;
309
}
310
 
311
/* Copy any private info we understand from the input symbol
312
   to the output symbol.  */
313
 
314
static bfd_boolean
315
bfd_plugin_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
316
                                         asymbol *isymbol ATTRIBUTE_UNUSED,
317
                                         bfd *obfd ATTRIBUTE_UNUSED,
318
                                         asymbol *osymbol ATTRIBUTE_UNUSED)
319
{
320
  BFD_ASSERT (0);
321
  return TRUE;
322
}
323
 
324
static bfd_boolean
325
bfd_plugin_bfd_print_private_bfd_data (bfd *abfd ATTRIBUTE_UNUSED, PTR ptr ATTRIBUTE_UNUSED)
326
{
327
  BFD_ASSERT (0);
328
  return TRUE;
329
}
330
 
331
static char *
332
bfd_plugin_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED)
333
{
334
  BFD_ASSERT (0);
335
  return NULL;
336
}
337
 
338
static int
339
bfd_plugin_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
340
{
341
  BFD_ASSERT (0);
342
  return 0;
343
}
344
 
345
static int
346
bfd_plugin_core_file_pid (bfd *abfd ATTRIBUTE_UNUSED)
347
{
348
  BFD_ASSERT (0);
349
  return 0;
350
}
351
 
352
static long
353
bfd_plugin_get_symtab_upper_bound (bfd *abfd)
354
{
355
  struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data;
356
  long nsyms = plugin_data->nsyms;
357
 
358
  BFD_ASSERT (nsyms >= 0);
359
 
360
  return ((nsyms + 1) * sizeof (asymbol *));
361
}
362
 
363
static flagword
364
convert_flags (const struct ld_plugin_symbol *sym)
365
{
366
 switch (sym->def)
367
   {
368
   case LDPK_DEF:
369
   case LDPK_COMMON:
370
   case LDPK_UNDEF:
371
     return BSF_GLOBAL;
372
 
373
   case LDPK_WEAKUNDEF:
374
   case LDPK_WEAKDEF:
375
     return BSF_GLOBAL | BSF_WEAK;
376
 
377
   default:
378
     BFD_ASSERT (0);
379
     return 0;
380
   }
381
}
382
 
383
static long
384
bfd_plugin_canonicalize_symtab (bfd *abfd,
385
                                asymbol **alocation)
386
{
387
  struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data;
388
  long nsyms = plugin_data->nsyms;
389
  const struct ld_plugin_symbol *syms = plugin_data->syms;
390
  static asection fake_section;
391
  static asection fake_common_section;
392
  int i;
393
 
394
  fake_section.name = ".text";
395
  fake_common_section.flags = SEC_IS_COMMON;
396
 
397
  for (i = 0; i < nsyms; i++)
398
    {
399
      asymbol *s = bfd_alloc (abfd, sizeof (asymbol));
400
 
401
      BFD_ASSERT (s);
402
      alocation[i] = s;
403
 
404
      s->the_bfd = abfd;
405
      s->name = syms[i].name;
406
      s->value = 0;
407
      s->flags = convert_flags (&syms[i]);
408
      switch (syms[i].def)
409
        {
410
        case LDPK_COMMON:
411
          s->section = &fake_common_section;
412
          break;
413
        case LDPK_UNDEF:
414
        case LDPK_WEAKUNDEF:
415
          s->section = bfd_und_section_ptr;
416
          break;
417
        case LDPK_DEF:
418
        case LDPK_WEAKDEF:
419
          s->section = &fake_section;
420
          break;
421
        default:
422
          BFD_ASSERT (0);
423
        }
424
 
425
      s->udata.p = (void *) &syms[i];
426
    }
427
 
428
  return nsyms;
429
}
430
 
431
static void
432
bfd_plugin_print_symbol (bfd *abfd ATTRIBUTE_UNUSED,
433
                         PTR afile ATTRIBUTE_UNUSED,
434
                         asymbol *symbol ATTRIBUTE_UNUSED,
435
                         bfd_print_symbol_type how ATTRIBUTE_UNUSED)
436
{
437
  BFD_ASSERT (0);
438
}
439
 
440
static void
441
bfd_plugin_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
442
                            asymbol *symbol,
443
                            symbol_info *ret)
444
{
445
  bfd_symbol_info (symbol, ret);
446
}
447
 
448
/* Make an empty symbol. */
449
 
450
static asymbol *
451
bfd_plugin_make_empty_symbol (bfd *abfd)
452
{
453
  asymbol *new_symbol = bfd_zalloc (abfd, sizeof (asymbol));
454
  if (new_symbol == NULL)
455
    return new_symbol;
456
  new_symbol->the_bfd = abfd;
457
  return new_symbol;
458
}
459
 
460
static int
461
bfd_plugin_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
462
                           struct bfd_link_info *info ATTRIBUTE_UNUSED)
463
{
464
  BFD_ASSERT (0);
465
  return 0;
466
}
467
 
468
const bfd_target plugin_vec =
469
{
470
  "plugin",                     /* Name.  */
471
  bfd_target_unknown_flavour,
472
  BFD_ENDIAN_LITTLE,            /* Target byte order.  */
473
  BFD_ENDIAN_LITTLE,            /* Target headers byte order.  */
474
  (HAS_RELOC | EXEC_P |         /* Object flags.  */
475
   HAS_LINENO | HAS_DEBUG |
476
   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
477
  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
478
   | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags.  */
479
  0,                             /* symbol_leading_char.  */
480
  '/',                          /* ar_pad_char.  */
481
  15,                           /* ar_max_namelen.  */
482 148 khays
  0,                             /* match priority.  */
483 14 khays
 
484
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
485
  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
486
  bfd_getl16, bfd_getl_signed_16, bfd_putl16,   /* data */
487
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
488
  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
489
  bfd_getl16, bfd_getl_signed_16, bfd_putl16,   /* hdrs */
490
 
491
  {                             /* bfd_check_format.  */
492
    _bfd_dummy_target,
493
    bfd_plugin_object_p,
494
    bfd_generic_archive_p,
495
    _bfd_dummy_target
496
  },
497
  {                             /* bfd_set_format.  */
498
    bfd_false,
499
    bfd_false,
500
    _bfd_generic_mkarchive,
501
    bfd_false,
502
  },
503
  {                             /* bfd_write_contents.  */
504
    bfd_false,
505
    bfd_false,
506
    _bfd_write_archive_contents,
507
    bfd_false,
508
  },
509
 
510
  BFD_JUMP_TABLE_GENERIC (bfd_plugin),
511
  BFD_JUMP_TABLE_COPY (bfd_plugin),
512
  BFD_JUMP_TABLE_CORE (bfd_plugin),
513
  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
514
  BFD_JUMP_TABLE_SYMBOLS (bfd_plugin),
515
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
516
  BFD_JUMP_TABLE_WRITE (bfd_plugin),
517
  BFD_JUMP_TABLE_LINK (bfd_plugin),
518
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
519
 
520
  NULL,
521
 
522
  NULL                          /* backend_data.  */
523
};
524
#endif /* BFD_SUPPORTS_PLUGIN */

powered by: WebSVN 2.1.0

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