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