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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [ld/] [testplug.c] - Blame information for rev 145

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

Line No. Rev Author Line
1 145 khays
/* Test plugin for the GNU linker.
2
   Copyright 2010 Free Software Foundation, Inc.
3
 
4
   This file is part of the GNU Binutils.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
 
21
#include "sysdep.h"
22
#include "bfd.h"
23
#include "plugin-api.h"
24
/* For ARRAY_SIZE macro only - we don't link the library itself.  */
25
#include "libiberty.h"
26
 
27
extern enum ld_plugin_status onload (struct ld_plugin_tv *tv);
28
static enum ld_plugin_status onclaim_file (const struct ld_plugin_input_file *file,
29
                                int *claimed);
30
static enum ld_plugin_status onall_symbols_read (void);
31
static enum ld_plugin_status oncleanup (void);
32
 
33
/* Helper for calling plugin api message function.  */
34
#define TV_MESSAGE if (tv_message) (*tv_message)
35
 
36
/* Struct for recording files to claim / files claimed.  */
37
typedef struct claim_file
38
{
39
  struct claim_file *next;
40
  struct ld_plugin_input_file file;
41
  bfd_boolean claimed;
42
  struct ld_plugin_symbol *symbols;
43
  int n_syms_allocated;
44
  int n_syms_used;
45
} claim_file_t;
46
 
47
/* Types of things that can be added at all symbols read time.  */
48
typedef enum addfile_enum
49
{
50
  ADD_FILE,
51
  ADD_LIB,
52
  ADD_DIR
53
} addfile_enum_t;
54
 
55
/* Struct for recording files to add to final link.  */
56
typedef struct add_file
57
{
58
  struct add_file *next;
59
  const char *name;
60
  addfile_enum_t type;
61
} add_file_t;
62
 
63
/* Helper macro for defining array of transfer vector tags and names.  */
64
#define ADDENTRY(tag) { tag, #tag }
65
 
66
/* Struct for looking up human-readable versions of tag names.  */
67
typedef struct tag_name
68
{
69
  enum ld_plugin_tag tag;
70
  const char *name;
71
} tag_name_t;
72
 
73
/* Array of all known tags and their names.  */
74
static const tag_name_t tag_names[] =
75
{
76
  ADDENTRY(LDPT_NULL),
77
  ADDENTRY(LDPT_API_VERSION),
78
  ADDENTRY(LDPT_GOLD_VERSION),
79
  ADDENTRY(LDPT_LINKER_OUTPUT),
80
  ADDENTRY(LDPT_OPTION),
81
  ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK),
82
  ADDENTRY(LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK),
83
  ADDENTRY(LDPT_REGISTER_CLEANUP_HOOK),
84
  ADDENTRY(LDPT_ADD_SYMBOLS),
85
  ADDENTRY(LDPT_GET_SYMBOLS),
86
  ADDENTRY(LDPT_ADD_INPUT_FILE),
87
  ADDENTRY(LDPT_MESSAGE),
88
  ADDENTRY(LDPT_GET_INPUT_FILE),
89
  ADDENTRY(LDPT_RELEASE_INPUT_FILE),
90
  ADDENTRY(LDPT_ADD_INPUT_LIBRARY),
91
  ADDENTRY(LDPT_OUTPUT_NAME),
92
  ADDENTRY(LDPT_SET_EXTRA_LIBRARY_PATH),
93
  ADDENTRY(LDPT_GNU_LD_VERSION)
94
};
95
 
96
/* Function pointers to cache hooks passed at onload time.  */
97
static ld_plugin_register_claim_file tv_register_claim_file = 0;
98
static ld_plugin_register_all_symbols_read tv_register_all_symbols_read = 0;
99
static ld_plugin_register_cleanup tv_register_cleanup = 0;
100
static ld_plugin_add_symbols tv_add_symbols = 0;
101
static ld_plugin_get_symbols tv_get_symbols = 0;
102
static ld_plugin_add_input_file tv_add_input_file = 0;
103
static ld_plugin_message tv_message = 0;
104
static ld_plugin_get_input_file tv_get_input_file = 0;
105
static ld_plugin_release_input_file tv_release_input_file = 0;
106
static ld_plugin_add_input_library tv_add_input_library = 0;
107
static ld_plugin_set_extra_library_path tv_set_extra_library_path = 0;
108
 
109
/* Other cached info from the transfer vector.  */
110
static enum ld_plugin_output_file_type linker_output;
111
static const char *output_name;
112
 
113
/* Behaviour control flags set by plugin options.  */
114
static enum ld_plugin_status onload_ret = LDPS_OK;
115
static enum ld_plugin_status claim_file_ret = LDPS_OK;
116
static enum ld_plugin_status all_symbols_read_ret = LDPS_OK;
117
static enum ld_plugin_status cleanup_ret = LDPS_OK;
118
static bfd_boolean register_claimfile_hook = FALSE;
119
static bfd_boolean register_allsymbolsread_hook = FALSE;
120
static bfd_boolean register_cleanup_hook = FALSE;
121
static bfd_boolean dumpresolutions = FALSE;
122
 
123
/* The master list of all claimable/claimed files.  */
124
static claim_file_t *claimfiles_list = NULL;
125
 
126
/* We keep a tail pointer for easy linking on the end.  */
127
static claim_file_t **claimfiles_tail_chain_ptr = &claimfiles_list;
128
 
129
/* The last claimed file added to the list, for receiving syms.  */
130
static claim_file_t *last_claimfile = NULL;
131
 
132
/* The master list of all files to add to the final link.  */
133
static add_file_t *addfiles_list = NULL;
134
 
135
/* We keep a tail pointer for easy linking on the end.  */
136
static add_file_t **addfiles_tail_chain_ptr = &addfiles_list;
137
 
138
/* Add a new claimfile on the end of the chain.  */
139
static enum ld_plugin_status
140
record_claim_file (const char *file)
141
{
142
  claim_file_t *newfile;
143
 
144
  newfile = malloc (sizeof *newfile);
145
  if (!newfile)
146
    return LDPS_ERR;
147
  memset (newfile, 0, sizeof *newfile);
148
  /* Only setup for now is remembering the name to look for.  */
149
  newfile->file.name = file;
150
  /* Chain it on the end of the list.  */
151
  *claimfiles_tail_chain_ptr = newfile;
152
  claimfiles_tail_chain_ptr = &newfile->next;
153
  /* Record it as active for receiving symbols to register.  */
154
  last_claimfile = newfile;
155
  return LDPS_OK;
156
}
157
 
158
/* Add a new addfile on the end of the chain.  */
159
static enum ld_plugin_status
160
record_add_file (const char *file, addfile_enum_t type)
161
{
162
  add_file_t *newfile;
163
 
164
  newfile = malloc (sizeof *newfile);
165
  if (!newfile)
166
    return LDPS_ERR;
167
  newfile->next = NULL;
168
  newfile->name = file;
169
  newfile->type = type;;
170
  /* Chain it on the end of the list.  */
171
  *addfiles_tail_chain_ptr = newfile;
172
  addfiles_tail_chain_ptr = &newfile->next;
173
  return LDPS_OK;
174
}
175
 
176
/* Parse a command-line argument string into a symbol definition.
177
   Symbol-strings follow the colon-separated format:
178
        NAME:VERSION:def:vis:size:COMDATKEY
179
   where the fields in capitals are strings and those in lower
180
   case are integers.  We don't allow to specify a resolution as
181
   doing so is not meaningful when calling the add symbols hook.  */
182
static enum ld_plugin_status
183
parse_symdefstr (const char *str, struct ld_plugin_symbol *sym)
184
{
185
  int n;
186
  long long size;
187
  const char *colon1, *colon2, *colon5;
188
 
189
  /* Locate the colons separating the first two strings.  */
190
  colon1 = strchr (str, ':');
191
  if (!colon1)
192
    return LDPS_ERR;
193
  colon2 = strchr (colon1+1, ':');
194
  if (!colon2)
195
    return LDPS_ERR;
196
  /* Name must not be empty (version may be).  */
197
  if (colon1 == str)
198
    return LDPS_ERR;
199
 
200
  /* The fifth colon and trailing comdat key string are optional,
201
     but the intermediate ones must all be present.  */
202
  colon5 = strchr (colon2+1, ':');      /* Actually only third so far.  */
203
  if (!colon5)
204
    return LDPS_ERR;
205
  colon5 = strchr (colon5+1, ':');      /* Hopefully fourth now.  */
206
  if (!colon5)
207
    return LDPS_ERR;
208
  colon5 = strchr (colon5+1, ':');      /* Optional fifth now.  */
209
 
210
  /* Finally we'll use sscanf to parse the numeric fields, then
211
     we'll split out the strings which we need to allocate separate
212
     storage for anyway so that we can add nul termination.  */
213
  n = sscanf (colon2 + 1, "%i:%i:%lli", &sym->def, &sym->visibility, &size);
214
  if (n != 3)
215
    return LDPS_ERR;
216
 
217
  /* Parsed successfully, so allocate strings and fill out fields.  */
218
  sym->size = size;
219
  sym->resolution = LDPR_UNKNOWN;
220
  sym->name = malloc (colon1 - str + 1);
221
  if (!sym->name)
222
    return LDPS_ERR;
223
  memcpy (sym->name, str, colon1 - str);
224
  sym->name[colon1 - str] = '\0';
225
  if (colon2 > (colon1 + 1))
226
    {
227
      sym->version = malloc (colon2 - colon1);
228
      if (!sym->version)
229
        return LDPS_ERR;
230
      memcpy (sym->version, colon1 + 1, colon2 - (colon1 + 1));
231
      sym->version[colon2 - (colon1 + 1)] = '\0';
232
    }
233
  else
234
    sym->version = NULL;
235
  if (colon5 && colon5[1])
236
    {
237
      sym->comdat_key = malloc (strlen (colon5 + 1) + 1);
238
      if (!sym->comdat_key)
239
        return LDPS_ERR;
240
      strcpy (sym->comdat_key, colon5 + 1);
241
    }
242
  else
243
    sym->comdat_key = 0;
244
  return LDPS_OK;
245
}
246
 
247
/* Record a symbol to be added for the last-added claimfile.  */
248
static enum ld_plugin_status
249
record_claimed_file_symbol (const char *symdefstr)
250
{
251
  struct ld_plugin_symbol sym;
252
 
253
  /* Can't add symbols except as belonging to claimed files.  */
254
  if (!last_claimfile)
255
    return LDPS_ERR;
256
 
257
  /* If string doesn't parse correctly, give an error.  */
258
  if (parse_symdefstr (symdefstr, &sym) != LDPS_OK)
259
    return LDPS_ERR;
260
 
261
  /* Check for enough space, resize array if needed, and add it.  */
262
  if (last_claimfile->n_syms_allocated == last_claimfile->n_syms_used)
263
    {
264
      int new_n_syms = last_claimfile->n_syms_allocated
265
                        ? 2 * last_claimfile->n_syms_allocated
266
                        : 10;
267
      last_claimfile->symbols = realloc (last_claimfile->symbols,
268
                        new_n_syms * sizeof *last_claimfile->symbols);
269
      if (!last_claimfile->symbols)
270
        return LDPS_ERR;
271
      last_claimfile->n_syms_allocated = new_n_syms;
272
    }
273
  last_claimfile->symbols[last_claimfile->n_syms_used++] = sym;
274
 
275
  return LDPS_OK;
276
}
277
 
278
/* Records the status to return from one of the registered hooks.  */
279
static enum ld_plugin_status
280
set_ret_val (const char *whichval, enum ld_plugin_status retval)
281
{
282
  if (!strcmp ("onload", whichval))
283
    onload_ret = retval;
284
  else if (!strcmp ("claimfile", whichval))
285
    claim_file_ret = retval;
286
  else if (!strcmp ("allsymbolsread", whichval))
287
    all_symbols_read_ret = retval;
288
  else if (!strcmp ("cleanup", whichval))
289
    cleanup_ret = retval;
290
  else
291
    return LDPS_ERR;
292
  return LDPS_OK;
293
}
294
 
295
/* Records hooks which should be registered.  */
296
static enum ld_plugin_status
297
set_register_hook (const char *whichhook, bfd_boolean yesno)
298
{
299
  if (!strcmp ("claimfile", whichhook))
300
    register_claimfile_hook = yesno;
301
  else if (!strcmp ("allsymbolsread", whichhook))
302
    register_allsymbolsread_hook = yesno;
303
  else if (!strcmp ("cleanup", whichhook))
304
    register_cleanup_hook = yesno;
305
  else
306
    return LDPS_ERR;
307
  return LDPS_OK;
308
}
309
 
310
/* Determine type of plugin option and pass to individual parsers.  */
311
static enum ld_plugin_status
312
parse_option (const char *opt)
313
{
314
  if (!strncmp ("fail", opt, 4))
315
    return set_ret_val (opt + 4, LDPS_ERR);
316
  else if (!strncmp ("pass", opt, 4))
317
    return set_ret_val (opt + 4, LDPS_OK);
318
  else if (!strncmp ("register", opt, 8))
319
    return set_register_hook (opt + 8, TRUE);
320
  else if (!strncmp ("noregister", opt, 10))
321
    return set_register_hook (opt + 10, FALSE);
322
  else if (!strncmp ("claim:", opt, 6))
323
    return record_claim_file (opt + 6);
324
  else if (!strncmp ("sym:", opt, 4))
325
    return record_claimed_file_symbol (opt + 4);
326
  else if (!strncmp ("add:", opt, 4))
327
    return record_add_file (opt + 4, ADD_FILE);
328
  else if (!strncmp ("lib:", opt, 4))
329
    return record_add_file (opt + 4, ADD_LIB);
330
  else if (!strncmp ("dir:", opt, 4))
331
    return record_add_file (opt + 4, ADD_DIR);
332
  else if (!strcmp ("dumpresolutions", opt))
333
    dumpresolutions = TRUE;
334
  else
335
    return LDPS_ERR;
336
  return LDPS_OK;
337
}
338
 
339
/* Output contents of transfer vector array entry in human-readable form.  */
340
static void
341
dump_tv_tag (size_t n, struct ld_plugin_tv *tv)
342
{
343
  size_t tag;
344
  char unknownbuf[40];
345
  const char *name;
346
 
347
  for (tag = 0; tag < ARRAY_SIZE (tag_names); tag++)
348
    if (tag_names[tag].tag == tv->tv_tag)
349
      break;
350
  sprintf (unknownbuf, "unknown tag #%d", tv->tv_tag);
351
  name = (tag < ARRAY_SIZE (tag_names)) ? tag_names[tag].name : unknownbuf;
352
  switch (tv->tv_tag)
353
    {
354
      case LDPT_OPTION:
355
      case LDPT_OUTPUT_NAME:
356
        TV_MESSAGE (LDPL_INFO, "tv[%d]: %s '%s'", n, name,
357
                    tv->tv_u.tv_string);
358
        break;
359
      case LDPT_REGISTER_CLAIM_FILE_HOOK:
360
      case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
361
      case LDPT_REGISTER_CLEANUP_HOOK:
362
      case LDPT_ADD_SYMBOLS:
363
      case LDPT_GET_SYMBOLS:
364
      case LDPT_ADD_INPUT_FILE:
365
      case LDPT_MESSAGE:
366
      case LDPT_GET_INPUT_FILE:
367
      case LDPT_RELEASE_INPUT_FILE:
368
      case LDPT_ADD_INPUT_LIBRARY:
369
      case LDPT_SET_EXTRA_LIBRARY_PATH:
370
        TV_MESSAGE (LDPL_INFO, "tv[%d]: %s func@0x%p", n, name,
371
                    (void *)(tv->tv_u.tv_message));
372
        break;
373
      case LDPT_NULL:
374
      case LDPT_API_VERSION:
375
      case LDPT_GOLD_VERSION:
376
      case LDPT_LINKER_OUTPUT:
377
      case LDPT_GNU_LD_VERSION:
378
      default:
379
        TV_MESSAGE (LDPL_INFO, "tv[%d]: %s value %W (%d)", n, name,
380
                    (bfd_vma)tv->tv_u.tv_val, tv->tv_u.tv_val);
381
        break;
382
    }
383
}
384
 
385
/* Handle/record information received in a transfer vector entry.  */
386
static enum ld_plugin_status
387
parse_tv_tag (struct ld_plugin_tv *tv)
388
{
389
#define SETVAR(x) x = tv->tv_u.x
390
  switch (tv->tv_tag)
391
    {
392
      case LDPT_OPTION:
393
        return parse_option (tv->tv_u.tv_string);
394
      case LDPT_NULL:
395
      case LDPT_GOLD_VERSION:
396
      case LDPT_GNU_LD_VERSION:
397
      case LDPT_API_VERSION:
398
      default:
399
        break;
400
      case LDPT_OUTPUT_NAME:
401
        output_name = tv->tv_u.tv_string;
402
        break;
403
      case LDPT_LINKER_OUTPUT:
404
        linker_output = tv->tv_u.tv_val;
405
        break;
406
      case LDPT_REGISTER_CLAIM_FILE_HOOK:
407
        SETVAR(tv_register_claim_file);
408
        break;
409
      case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
410
        SETVAR(tv_register_all_symbols_read);
411
        break;
412
      case LDPT_REGISTER_CLEANUP_HOOK:
413
        SETVAR(tv_register_cleanup);
414
        break;
415
      case LDPT_ADD_SYMBOLS:
416
        SETVAR(tv_add_symbols);
417
        break;
418
      case LDPT_GET_SYMBOLS:
419
        SETVAR(tv_get_symbols);
420
        break;
421
      case LDPT_ADD_INPUT_FILE:
422
        SETVAR(tv_add_input_file);
423
        break;
424
      case LDPT_MESSAGE:
425
        SETVAR(tv_message);
426
        break;
427
      case LDPT_GET_INPUT_FILE:
428
        SETVAR(tv_get_input_file);
429
        break;
430
      case LDPT_RELEASE_INPUT_FILE:
431
        SETVAR(tv_release_input_file);
432
        break;
433
      case LDPT_ADD_INPUT_LIBRARY:
434
        SETVAR(tv_add_input_library);
435
        break;
436
      case LDPT_SET_EXTRA_LIBRARY_PATH:
437
        SETVAR(tv_set_extra_library_path);
438
        break;
439
    }
440
#undef SETVAR
441
  return LDPS_OK;
442
}
443
 
444
/* Record any useful information in transfer vector entry and display
445
   it in human-readable form using the plugin API message() callback.  */
446
enum ld_plugin_status
447
parse_and_dump_tv_tag (size_t n, struct ld_plugin_tv *tv)
448
{
449
  enum ld_plugin_status rv = parse_tv_tag (tv);
450
  dump_tv_tag (n, tv);
451
  return rv;
452
}
453
 
454
/* Standard plugin API entry point.  */
455
enum ld_plugin_status
456
onload (struct ld_plugin_tv *tv)
457
{
458
  size_t n = 0;
459
  enum ld_plugin_status rv;
460
 
461
  /* This plugin does nothing but dump the tv array.  It would
462
     be an error if this function was called without one.  */
463
  if (!tv)
464
    return LDPS_ERR;
465
 
466
  /* First entry should always be LDPT_MESSAGE, letting us get
467
     hold of it easily so we can send output straight away.  */
468
  if (tv[0].tv_tag == LDPT_MESSAGE)
469
    tv_message = tv[0].tv_u.tv_message;
470
 
471
  fflush (NULL);
472
  TV_MESSAGE (LDPL_INFO, "Hello from testplugin.");
473
 
474
  do
475
    if ((rv = parse_and_dump_tv_tag (n++, tv)) != LDPS_OK)
476
      return rv;
477
  while ((tv++)->tv_tag != LDPT_NULL);
478
 
479
  /* Register hooks only if instructed by options.  */
480
  if (register_claimfile_hook)
481
    {
482
      if (!tv_register_claim_file)
483
        {
484
          TV_MESSAGE (LDPL_FATAL, "No register_claim_file hook");
485
          fflush (NULL);
486
          return LDPS_ERR;
487
        }
488
      (*tv_register_claim_file) (onclaim_file);
489
    }
490
  if (register_allsymbolsread_hook)
491
    {
492
      if (!tv_register_all_symbols_read)
493
        {
494
          TV_MESSAGE (LDPL_FATAL, "No register_all_symbols_read hook");
495
          fflush (NULL);
496
          return LDPS_ERR;
497
        }
498
      (*tv_register_all_symbols_read) (onall_symbols_read);
499
    }
500
  if (register_cleanup_hook)
501
    {
502
      if (!tv_register_cleanup)
503
        {
504
          TV_MESSAGE (LDPL_FATAL, "No register_cleanup hook");
505
          fflush (NULL);
506
          return LDPS_ERR;
507
        }
508
      (*tv_register_cleanup) (oncleanup);
509
    }
510
  fflush (NULL);
511
  return onload_ret;
512
}
513
 
514
/* Standard plugin API registerable hook.  */
515
static enum ld_plugin_status
516
onclaim_file (const struct ld_plugin_input_file *file, int *claimed)
517
{
518
  /* Let's see if we want to claim this file.  */
519
  claim_file_t *claimfile = claimfiles_list;
520
  while (claimfile)
521
    {
522
      if (!strcmp (file->name, claimfile->file.name))
523
        break;
524
      claimfile = claimfile->next;
525
    }
526
 
527
  /* Inform the user/testsuite.  */
528
  TV_MESSAGE (LDPL_INFO, "hook called: claim_file %s [@%ld/%ld] %s",
529
              file->name, (long)file->offset, (long)file->filesize,
530
              claimfile ? "CLAIMED" : "not claimed");
531
  fflush (NULL);
532
 
533
  /* If we decided to claim it, record that fact, and add any symbols
534
     that were defined for it by plugin options.  */
535
  *claimed = (claimfile != 0);
536
  if (claimfile)
537
    {
538
      claimfile->claimed = TRUE;
539
      claimfile->file = *file;
540
      if (claimfile->n_syms_used && !tv_add_symbols)
541
        return LDPS_ERR;
542
      else if (claimfile->n_syms_used)
543
        return (*tv_add_symbols) (claimfile->file.handle,
544
                                claimfile->n_syms_used, claimfile->symbols);
545
    }
546
 
547
  return claim_file_ret;
548
}
549
 
550
/* Standard plugin API registerable hook.  */
551
static enum ld_plugin_status
552
onall_symbols_read (void)
553
{
554
  static const char *resolutions[] =
555
    {
556
      "LDPR_UNKNOWN",
557
      "LDPR_UNDEF",
558
      "LDPR_PREVAILING_DEF",
559
      "LDPR_PREVAILING_DEF_IRONLY",
560
      "LDPR_PREEMPTED_REG",
561
      "LDPR_PREEMPTED_IR",
562
      "LDPR_RESOLVED_IR",
563
      "LDPR_RESOLVED_EXEC",
564
      "LDPR_RESOLVED_DYN",
565
    };
566
  claim_file_t *claimfile = dumpresolutions ? claimfiles_list : NULL;
567
  add_file_t *addfile = addfiles_list;
568
  TV_MESSAGE (LDPL_INFO, "hook called: all symbols read.");
569
  for ( ; claimfile; claimfile = claimfile->next)
570
    {
571
      enum ld_plugin_status rv;
572
      int n;
573
      if (claimfile->n_syms_used && !tv_get_symbols)
574
        return LDPS_ERR;
575
      else if (!claimfile->n_syms_used)
576
        continue;
577
      rv = tv_get_symbols (claimfile->file.handle, claimfile->n_syms_used,
578
                                claimfile->symbols);
579
      if (rv != LDPS_OK)
580
        return rv;
581
      for (n = 0; n < claimfile->n_syms_used; n++)
582
        TV_MESSAGE (LDPL_INFO, "Sym: '%s%s%s' Resolution: %s",
583
                    claimfile->symbols[n].name,
584
                    claimfile->symbols[n].version ? "@" : "",
585
                    (claimfile->symbols[n].version
586
                     ? claimfile->symbols[n].version : ""),
587
                    resolutions[claimfile->symbols[n].resolution]);
588
    }
589
  for ( ; addfile ; addfile = addfile->next)
590
    {
591
      enum ld_plugin_status rv;
592
      if (addfile->type == ADD_LIB && tv_add_input_library)
593
        rv = (*tv_add_input_library) (addfile->name);
594
      else if (addfile->type == ADD_FILE && tv_add_input_file)
595
        rv = (*tv_add_input_file) (addfile->name);
596
      else if (addfile->type == ADD_DIR && tv_set_extra_library_path)
597
        rv = (*tv_set_extra_library_path) (addfile->name);
598
      else
599
        rv = LDPS_ERR;
600
      if (rv != LDPS_OK)
601
        return rv;
602
    }
603
  fflush (NULL);
604
  return all_symbols_read_ret;
605
}
606
 
607
/* Standard plugin API registerable hook.  */
608
static enum ld_plugin_status
609
oncleanup (void)
610
{
611
  TV_MESSAGE (LDPL_INFO, "hook called: cleanup.");
612
  fflush (NULL);
613
  return cleanup_ret;
614
}

powered by: WebSVN 2.1.0

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