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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [plugin.c] - Blame information for rev 818

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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