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 90

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

Line No. Rev Author Line
1 14 khays
/* Plugin support for BFD.
2
   Copyright 2009
3
   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
#define bfd_plugin_bfd_merge_sections                 bfd_generic_merge_sections
67
#define bfd_plugin_bfd_is_group_section               bfd_generic_is_group_section
68
#define bfd_plugin_bfd_discard_group                  bfd_generic_discard_group
69
#define bfd_plugin_section_already_linked             _bfd_generic_section_already_linked
70
#define bfd_plugin_bfd_define_common_symbol           bfd_generic_define_common_symbol
71
#define bfd_plugin_bfd_copy_link_hash_symbol_type     _bfd_generic_copy_link_hash_symbol_type
72
 
73
static enum ld_plugin_status
74
message (int level ATTRIBUTE_UNUSED,
75
         const char * format, ...)
76
{
77
  va_list args;
78
  va_start (args, format);
79
  printf ("bfd plugin: ");
80
  vprintf (format, args);
81
  putchar ('\n');
82
  va_end (args);
83
  return LDPS_OK;
84
}
85
 
86
/* Register a claim-file handler. */
87
static ld_plugin_claim_file_handler claim_file;
88
 
89
static enum ld_plugin_status
90
register_claim_file (ld_plugin_claim_file_handler handler)
91
{
92
  claim_file = handler;
93
  return LDPS_OK;
94
}
95
 
96
static enum ld_plugin_status
97
add_symbols (void * handle,
98
             int nsyms,
99
             const struct ld_plugin_symbol * syms)
100
{
101
  bfd *abfd = handle;
102
  struct plugin_data_struct *plugin_data =
103
    bfd_alloc (abfd, sizeof (plugin_data_struct));;
104
 
105
  plugin_data->nsyms = nsyms;
106
  plugin_data->syms = syms;
107
 
108
  if (nsyms != 0)
109
    abfd->flags |= HAS_SYMS;
110
 
111
  abfd->tdata.plugin_data = plugin_data;
112
  return LDPS_OK;
113
}
114
 
115
static const char *plugin_program_name;
116
 
117
void
118
bfd_plugin_set_program_name (const char *program_name)
119
{
120
  plugin_program_name = program_name;
121
}
122
 
123
static int
124
try_load_plugin (const char *pname)
125
{
126
  static void *plugin_handle;
127
  int tv_size = 4;
128
  struct ld_plugin_tv tv[tv_size];
129
  int i;
130
  ld_plugin_onload onload;
131
  enum ld_plugin_status status;
132
 
133
  plugin_handle = dlopen (pname, RTLD_NOW);
134
  if (!plugin_handle)
135
    {
136
      (*_bfd_error_handler)("%s\n", dlerror ());
137
      return 0;
138
    }
139
 
140
  onload = dlsym (plugin_handle, "onload");
141
  if (!onload)
142
    goto err;
143
 
144
  i = 0;
145
  tv[i].tv_tag = LDPT_MESSAGE;
146
  tv[i].tv_u.tv_message = message;
147
 
148
  ++i;
149
  tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK;
150
  tv[i].tv_u.tv_register_claim_file = register_claim_file;
151
 
152
  ++i;
153
  tv[i].tv_tag = LDPT_ADD_SYMBOLS;
154
  tv[i].tv_u.tv_add_symbols = add_symbols;
155
 
156
  ++i;
157
  tv[i].tv_tag = LDPT_NULL;
158
  tv[i].tv_u.tv_val = 0;
159
 
160
  status = (*onload)(tv);
161
 
162
  if (status != LDPS_OK)
163
    goto err;
164
 
165
  if (!claim_file)
166
    goto err;
167
 
168
  return 1;
169
 
170
 err:
171
  plugin_handle = NULL;
172
  return 0;
173
}
174
 
175
static const char *plugin_name;
176
 
177
void
178
bfd_plugin_set_plugin (const char *p)
179
{
180
  plugin_name = p;
181
}
182
 
183
static int
184
load_plugin (void)
185
{
186
  char *plugin_dir;
187
  char *p;
188
  DIR *d;
189
  struct dirent *ent;
190
  int found = 0;
191
 
192
  if (plugin_name)
193
    return try_load_plugin (plugin_name);
194
 
195
  if (plugin_program_name == NULL)
196
    return 0;
197
 
198
  plugin_dir = concat (BINDIR, "/../lib/bfd-plugins", NULL);
199
  p = make_relative_prefix (plugin_program_name,
200
                            BINDIR,
201
                            plugin_dir);
202
  free (plugin_dir);
203
  plugin_dir = NULL;
204
 
205
  d = opendir (p);
206
  if (!d)
207
    goto out;
208
 
209
  while ((ent = readdir (d)))
210
    {
211
      char *full_name;
212
      struct stat s;
213
 
214
      full_name = concat (p, "/", ent->d_name, NULL);
215
      if (stat(full_name, &s) == 0 && S_ISREG (s.st_mode))
216
        found = try_load_plugin (full_name);
217
      free (full_name);
218
      if (found)
219
        break;
220
    }
221
 
222
 out:
223
  free (p);
224
  if (d)
225
    closedir (d);
226
 
227
  return found;
228
}
229
 
230
 
231
static const bfd_target *
232
bfd_plugin_object_p (bfd *abfd)
233
{
234
  int claimed = 0;
235
  struct ld_plugin_input_file file;
236
  bfd *iobfd;
237
  static int have_loaded = 0;
238
  static int have_plugin = 0;
239
 
240
  if (!have_loaded)
241
    {
242
      have_loaded = 1;
243
      have_plugin = load_plugin ();
244
    }
245
  if (!have_plugin)
246
    return NULL;
247
 
248
  file.name = abfd->filename;
249
 
250
  if (abfd->my_archive)
251
    {
252
      iobfd = abfd->my_archive;
253
      file.offset = abfd->origin;
254
      file.filesize = arelt_size (abfd);
255
    }
256
  else
257
    {
258
      iobfd = abfd;
259
      file.offset = 0;
260
      file.filesize = 0;
261
    }
262
 
263
  if (!iobfd->iostream && !bfd_open_file (iobfd))
264
    return NULL;
265
 
266
  file.fd = fileno ((FILE *) iobfd->iostream);
267
 
268
  if (!abfd->my_archive)
269
    {
270
      struct stat stat_buf;
271
      if (fstat (file.fd, &stat_buf))
272
        return NULL;
273
      file.filesize = stat_buf.st_size;
274
    }
275
 
276
  file.handle = abfd;
277
  off_t cur_offset = lseek(file.fd, 0, SEEK_CUR);
278
  claim_file (&file, &claimed);
279
  lseek(file.fd, cur_offset, SEEK_SET);
280
  if (!claimed)
281
    return NULL;
282
 
283
  return abfd->xvec;
284
}
285
 
286
/* Copy any private info we understand from the input bfd
287
   to the output bfd.  */
288
 
289
static bfd_boolean
290
bfd_plugin_bfd_copy_private_bfd_data (bfd *ibfd ATTRIBUTE_UNUSED,
291
                                      bfd *obfd ATTRIBUTE_UNUSED)
292
{
293
  BFD_ASSERT (0);
294
  return TRUE;
295
}
296
 
297
/* Copy any private info we understand from the input section
298
   to the output section.  */
299
 
300
static bfd_boolean
301
bfd_plugin_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
302
                                          asection *isection ATTRIBUTE_UNUSED,
303
                                          bfd *obfd ATTRIBUTE_UNUSED,
304
                                          asection *osection ATTRIBUTE_UNUSED)
305
{
306
  BFD_ASSERT (0);
307
  return TRUE;
308
}
309
 
310
/* Copy any private info we understand from the input symbol
311
   to the output symbol.  */
312
 
313
static bfd_boolean
314
bfd_plugin_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
315
                                         asymbol *isymbol ATTRIBUTE_UNUSED,
316
                                         bfd *obfd ATTRIBUTE_UNUSED,
317
                                         asymbol *osymbol ATTRIBUTE_UNUSED)
318
{
319
  BFD_ASSERT (0);
320
  return TRUE;
321
}
322
 
323
static bfd_boolean
324
bfd_plugin_bfd_print_private_bfd_data (bfd *abfd ATTRIBUTE_UNUSED, PTR ptr ATTRIBUTE_UNUSED)
325
{
326
  BFD_ASSERT (0);
327
  return TRUE;
328
}
329
 
330
static char *
331
bfd_plugin_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED)
332
{
333
  BFD_ASSERT (0);
334
  return NULL;
335
}
336
 
337
static int
338
bfd_plugin_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
339
{
340
  BFD_ASSERT (0);
341
  return 0;
342
}
343
 
344
static int
345
bfd_plugin_core_file_pid (bfd *abfd ATTRIBUTE_UNUSED)
346
{
347
  BFD_ASSERT (0);
348
  return 0;
349
}
350
 
351
static long
352
bfd_plugin_get_symtab_upper_bound (bfd *abfd)
353
{
354
  struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data;
355
  long nsyms = plugin_data->nsyms;
356
 
357
  BFD_ASSERT (nsyms >= 0);
358
 
359
  return ((nsyms + 1) * sizeof (asymbol *));
360
}
361
 
362
static flagword
363
convert_flags (const struct ld_plugin_symbol *sym)
364
{
365
 switch (sym->def)
366
   {
367
   case LDPK_DEF:
368
   case LDPK_COMMON:
369
   case LDPK_UNDEF:
370
     return BSF_GLOBAL;
371
 
372
   case LDPK_WEAKUNDEF:
373
   case LDPK_WEAKDEF:
374
     return BSF_GLOBAL | BSF_WEAK;
375
 
376
   default:
377
     BFD_ASSERT (0);
378
     return 0;
379
   }
380
}
381
 
382
static long
383
bfd_plugin_canonicalize_symtab (bfd *abfd,
384
                                asymbol **alocation)
385
{
386
  struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data;
387
  long nsyms = plugin_data->nsyms;
388
  const struct ld_plugin_symbol *syms = plugin_data->syms;
389
  static asection fake_section;
390
  static asection fake_common_section;
391
  int i;
392
 
393
  fake_section.name = ".text";
394
  fake_common_section.flags = SEC_IS_COMMON;
395
 
396
  for (i = 0; i < nsyms; i++)
397
    {
398
      asymbol *s = bfd_alloc (abfd, sizeof (asymbol));
399
 
400
      BFD_ASSERT (s);
401
      alocation[i] = s;
402
 
403
      s->the_bfd = abfd;
404
      s->name = syms[i].name;
405
      s->value = 0;
406
      s->flags = convert_flags (&syms[i]);
407
      switch (syms[i].def)
408
        {
409
        case LDPK_COMMON:
410
          s->section = &fake_common_section;
411
          break;
412
        case LDPK_UNDEF:
413
        case LDPK_WEAKUNDEF:
414
          s->section = bfd_und_section_ptr;
415
          break;
416
        case LDPK_DEF:
417
        case LDPK_WEAKDEF:
418
          s->section = &fake_section;
419
          break;
420
        default:
421
          BFD_ASSERT (0);
422
        }
423
 
424
      s->udata.p = (void *) &syms[i];
425
    }
426
 
427
  return nsyms;
428
}
429
 
430
static void
431
bfd_plugin_print_symbol (bfd *abfd ATTRIBUTE_UNUSED,
432
                         PTR afile ATTRIBUTE_UNUSED,
433
                         asymbol *symbol ATTRIBUTE_UNUSED,
434
                         bfd_print_symbol_type how ATTRIBUTE_UNUSED)
435
{
436
  BFD_ASSERT (0);
437
}
438
 
439
static void
440
bfd_plugin_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
441
                            asymbol *symbol,
442
                            symbol_info *ret)
443
{
444
  bfd_symbol_info (symbol, ret);
445
}
446
 
447
/* Make an empty symbol. */
448
 
449
static asymbol *
450
bfd_plugin_make_empty_symbol (bfd *abfd)
451
{
452
  asymbol *new_symbol = bfd_zalloc (abfd, sizeof (asymbol));
453
  if (new_symbol == NULL)
454
    return new_symbol;
455
  new_symbol->the_bfd = abfd;
456
  return new_symbol;
457
}
458
 
459
static int
460
bfd_plugin_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
461
                           struct bfd_link_info *info ATTRIBUTE_UNUSED)
462
{
463
  BFD_ASSERT (0);
464
  return 0;
465
}
466
 
467
const bfd_target plugin_vec =
468
{
469
  "plugin",                     /* Name.  */
470
  bfd_target_unknown_flavour,
471
  BFD_ENDIAN_LITTLE,            /* Target byte order.  */
472
  BFD_ENDIAN_LITTLE,            /* Target headers byte order.  */
473
  (HAS_RELOC | EXEC_P |         /* Object flags.  */
474
   HAS_LINENO | HAS_DEBUG |
475
   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
476
  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
477
   | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags.  */
478
  0,                             /* symbol_leading_char.  */
479
  '/',                          /* ar_pad_char.  */
480
  15,                           /* ar_max_namelen.  */
481
 
482
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
483
  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
484
  bfd_getl16, bfd_getl_signed_16, bfd_putl16,   /* data */
485
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
486
  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
487
  bfd_getl16, bfd_getl_signed_16, bfd_putl16,   /* hdrs */
488
 
489
  {                             /* bfd_check_format.  */
490
    _bfd_dummy_target,
491
    bfd_plugin_object_p,
492
    bfd_generic_archive_p,
493
    _bfd_dummy_target
494
  },
495
  {                             /* bfd_set_format.  */
496
    bfd_false,
497
    bfd_false,
498
    _bfd_generic_mkarchive,
499
    bfd_false,
500
  },
501
  {                             /* bfd_write_contents.  */
502
    bfd_false,
503
    bfd_false,
504
    _bfd_write_archive_contents,
505
    bfd_false,
506
  },
507
 
508
  BFD_JUMP_TABLE_GENERIC (bfd_plugin),
509
  BFD_JUMP_TABLE_COPY (bfd_plugin),
510
  BFD_JUMP_TABLE_CORE (bfd_plugin),
511
  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
512
  BFD_JUMP_TABLE_SYMBOLS (bfd_plugin),
513
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
514
  BFD_JUMP_TABLE_WRITE (bfd_plugin),
515
  BFD_JUMP_TABLE_LINK (bfd_plugin),
516
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
517
 
518
  NULL,
519
 
520
  NULL                          /* backend_data.  */
521
};
522
#endif /* BFD_SUPPORTS_PLUGIN */

powered by: WebSVN 2.1.0

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