]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/testplug.c
Update year range in copyright notice of binutils files
[thirdparty/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')
179 {
180 fprintf (stderr, "APB: Bad length string: %s\n", tmp);
181 return LDPS_ERR;
182 }
183
184 bytes_to_read_before_claim = atoi (length);
185 return LDPS_OK;
186}
187
5d3236ee
DK
188/* Add a new addfile on the end of the chain. */
189static enum ld_plugin_status
190record_add_file (const char *file, addfile_enum_t type)
191{
192 add_file_t *newfile;
193
194 newfile = malloc (sizeof *newfile);
195 if (!newfile)
196 return LDPS_ERR;
197 newfile->next = NULL;
198 newfile->name = file;
5bb3703f 199 newfile->type = type;
5d3236ee
DK
200 /* Chain it on the end of the list. */
201 *addfiles_tail_chain_ptr = newfile;
202 addfiles_tail_chain_ptr = &newfile->next;
203 return LDPS_OK;
204}
205
206/* Parse a command-line argument string into a symbol definition.
207 Symbol-strings follow the colon-separated format:
208 NAME:VERSION:def:vis:size:COMDATKEY
209 where the fields in capitals are strings and those in lower
210 case are integers. We don't allow to specify a resolution as
211 doing so is not meaningful when calling the add symbols hook. */
212static enum ld_plugin_status
213parse_symdefstr (const char *str, struct ld_plugin_symbol *sym)
214{
215 int n;
216 long long size;
217 const char *colon1, *colon2, *colon5;
218
219 /* Locate the colons separating the first two strings. */
220 colon1 = strchr (str, ':');
221 if (!colon1)
222 return LDPS_ERR;
223 colon2 = strchr (colon1+1, ':');
224 if (!colon2)
225 return LDPS_ERR;
226 /* Name must not be empty (version may be). */
227 if (colon1 == str)
228 return LDPS_ERR;
229
230 /* The fifth colon and trailing comdat key string are optional,
231 but the intermediate ones must all be present. */
232 colon5 = strchr (colon2+1, ':'); /* Actually only third so far. */
233 if (!colon5)
234 return LDPS_ERR;
235 colon5 = strchr (colon5+1, ':'); /* Hopefully fourth now. */
236 if (!colon5)
237 return LDPS_ERR;
238 colon5 = strchr (colon5+1, ':'); /* Optional fifth now. */
239
240 /* Finally we'll use sscanf to parse the numeric fields, then
241 we'll split out the strings which we need to allocate separate
242 storage for anyway so that we can add nul termination. */
c02d6661 243 n = sscanf (colon2 + 1, "%hhi:%i:%lli", &sym->def, &sym->visibility, &size);
5d3236ee
DK
244 if (n != 3)
245 return LDPS_ERR;
246
247 /* Parsed successfully, so allocate strings and fill out fields. */
248 sym->size = size;
c02d6661
AM
249 sym->unused = 0;
250 sym->section_kind = 0;
251 sym->symbol_type = 0;
5d3236ee
DK
252 sym->resolution = LDPR_UNKNOWN;
253 sym->name = malloc (colon1 - str + 1);
254 if (!sym->name)
255 return LDPS_ERR;
256 memcpy (sym->name, str, colon1 - str);
257 sym->name[colon1 - str] = '\0';
258 if (colon2 > (colon1 + 1))
259 {
260 sym->version = malloc (colon2 - colon1);
261 if (!sym->version)
262 return LDPS_ERR;
263 memcpy (sym->version, colon1 + 1, colon2 - (colon1 + 1));
264 sym->version[colon2 - (colon1 + 1)] = '\0';
265 }
266 else
267 sym->version = NULL;
268 if (colon5 && colon5[1])
269 {
270 sym->comdat_key = malloc (strlen (colon5 + 1) + 1);
271 if (!sym->comdat_key)
272 return LDPS_ERR;
273 strcpy (sym->comdat_key, colon5 + 1);
274 }
275 else
276 sym->comdat_key = 0;
277 return LDPS_OK;
278}
279
280/* Record a symbol to be added for the last-added claimfile. */
281static enum ld_plugin_status
282record_claimed_file_symbol (const char *symdefstr)
283{
284 struct ld_plugin_symbol sym;
285
286 /* Can't add symbols except as belonging to claimed files. */
287 if (!last_claimfile)
288 return LDPS_ERR;
289
290 /* If string doesn't parse correctly, give an error. */
291 if (parse_symdefstr (symdefstr, &sym) != LDPS_OK)
292 return LDPS_ERR;
293
294 /* Check for enough space, resize array if needed, and add it. */
295 if (last_claimfile->n_syms_allocated == last_claimfile->n_syms_used)
296 {
297 int new_n_syms = last_claimfile->n_syms_allocated
298 ? 2 * last_claimfile->n_syms_allocated
299 : 10;
300 last_claimfile->symbols = realloc (last_claimfile->symbols,
301 new_n_syms * sizeof *last_claimfile->symbols);
302 if (!last_claimfile->symbols)
303 return LDPS_ERR;
304 last_claimfile->n_syms_allocated = new_n_syms;
305 }
306 last_claimfile->symbols[last_claimfile->n_syms_used++] = sym;
307
308 return LDPS_OK;
309}
310
311/* Records the status to return from one of the registered hooks. */
312static enum ld_plugin_status
313set_ret_val (const char *whichval, enum ld_plugin_status retval)
314{
315 if (!strcmp ("onload", whichval))
316 onload_ret = retval;
317 else if (!strcmp ("claimfile", whichval))
318 claim_file_ret = retval;
319 else if (!strcmp ("allsymbolsread", whichval))
320 all_symbols_read_ret = retval;
321 else if (!strcmp ("cleanup", whichval))
322 cleanup_ret = retval;
323 else
324 return LDPS_ERR;
325 return LDPS_OK;
326}
327
328/* Records hooks which should be registered. */
329static enum ld_plugin_status
330set_register_hook (const char *whichhook, bfd_boolean yesno)
331{
332 if (!strcmp ("claimfile", whichhook))
333 register_claimfile_hook = yesno;
334 else if (!strcmp ("allsymbolsread", whichhook))
335 register_allsymbolsread_hook = yesno;
336 else if (!strcmp ("cleanup", whichhook))
337 register_cleanup_hook = yesno;
338 else
339 return LDPS_ERR;
340 return LDPS_OK;
341}
342
343/* Determine type of plugin option and pass to individual parsers. */
344static enum ld_plugin_status
345parse_option (const char *opt)
346{
347 if (!strncmp ("fail", opt, 4))
348 return set_ret_val (opt + 4, LDPS_ERR);
349 else if (!strncmp ("pass", opt, 4))
350 return set_ret_val (opt + 4, LDPS_OK);
351 else if (!strncmp ("register", opt, 8))
352 return set_register_hook (opt + 8, TRUE);
353 else if (!strncmp ("noregister", opt, 10))
354 return set_register_hook (opt + 10, FALSE);
355 else if (!strncmp ("claim:", opt, 6))
356 return record_claim_file (opt + 6);
ace667e5
AB
357 else if (!strncmp ("read:", opt, 5))
358 return record_read_length (opt + 5);
5d3236ee
DK
359 else if (!strncmp ("sym:", opt, 4))
360 return record_claimed_file_symbol (opt + 4);
361 else if (!strncmp ("add:", opt, 4))
362 return record_add_file (opt + 4, ADD_FILE);
363 else if (!strncmp ("lib:", opt, 4))
364 return record_add_file (opt + 4, ADD_LIB);
365 else if (!strncmp ("dir:", opt, 4))
366 return record_add_file (opt + 4, ADD_DIR);
367 else if (!strcmp ("dumpresolutions", opt))
368 dumpresolutions = TRUE;
369 else
370 return LDPS_ERR;
371 return LDPS_OK;
372}
373
374/* Output contents of transfer vector array entry in human-readable form. */
375static void
376dump_tv_tag (size_t n, struct ld_plugin_tv *tv)
377{
378 size_t tag;
379 char unknownbuf[40];
380 const char *name;
381
382 for (tag = 0; tag < ARRAY_SIZE (tag_names); tag++)
383 if (tag_names[tag].tag == tv->tv_tag)
384 break;
385 sprintf (unknownbuf, "unknown tag #%d", tv->tv_tag);
386 name = (tag < ARRAY_SIZE (tag_names)) ? tag_names[tag].name : unknownbuf;
5d3236ee
DK
387 switch (tv->tv_tag)
388 {
389 case LDPT_OPTION:
390 case LDPT_OUTPUT_NAME:
ada487f6
L
391 TV_MESSAGE (LDPL_INFO, "tv[%d]: %s '%s'", n, name,
392 tv->tv_u.tv_string);
5d3236ee
DK
393 break;
394 case LDPT_REGISTER_CLAIM_FILE_HOOK:
395 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
396 case LDPT_REGISTER_CLEANUP_HOOK:
397 case LDPT_ADD_SYMBOLS:
398 case LDPT_GET_SYMBOLS:
69ee6ab2 399 case LDPT_GET_SYMBOLS_V2:
5d3236ee
DK
400 case LDPT_ADD_INPUT_FILE:
401 case LDPT_MESSAGE:
402 case LDPT_GET_INPUT_FILE:
15f7a26b 403 case LDPT_GET_VIEW:
5d3236ee
DK
404 case LDPT_RELEASE_INPUT_FILE:
405 case LDPT_ADD_INPUT_LIBRARY:
406 case LDPT_SET_EXTRA_LIBRARY_PATH:
ada487f6
L
407 TV_MESSAGE (LDPL_INFO, "tv[%d]: %s func@0x%p", n, name,
408 (void *)(tv->tv_u.tv_message));
5d3236ee
DK
409 break;
410 case LDPT_NULL:
411 case LDPT_API_VERSION:
412 case LDPT_GOLD_VERSION:
413 case LDPT_LINKER_OUTPUT:
414 case LDPT_GNU_LD_VERSION:
415 default:
ada487f6
L
416 TV_MESSAGE (LDPL_INFO, "tv[%d]: %s value %W (%d)", n, name,
417 (bfd_vma)tv->tv_u.tv_val, tv->tv_u.tv_val);
5d3236ee
DK
418 break;
419 }
420}
421
422/* Handle/record information received in a transfer vector entry. */
423static enum ld_plugin_status
424parse_tv_tag (struct ld_plugin_tv *tv)
425{
426#define SETVAR(x) x = tv->tv_u.x
427 switch (tv->tv_tag)
428 {
429 case LDPT_OPTION:
430 return parse_option (tv->tv_u.tv_string);
431 case LDPT_NULL:
432 case LDPT_GOLD_VERSION:
433 case LDPT_GNU_LD_VERSION:
434 case LDPT_API_VERSION:
435 default:
436 break;
437 case LDPT_OUTPUT_NAME:
438 output_name = tv->tv_u.tv_string;
439 break;
440 case LDPT_LINKER_OUTPUT:
441 linker_output = tv->tv_u.tv_val;
442 break;
443 case LDPT_REGISTER_CLAIM_FILE_HOOK:
444 SETVAR(tv_register_claim_file);
445 break;
446 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
447 SETVAR(tv_register_all_symbols_read);
448 break;
449 case LDPT_REGISTER_CLEANUP_HOOK:
450 SETVAR(tv_register_cleanup);
451 break;
452 case LDPT_ADD_SYMBOLS:
453 SETVAR(tv_add_symbols);
454 break;
455 case LDPT_GET_SYMBOLS:
456 SETVAR(tv_get_symbols);
457 break;
69ee6ab2
AM
458 case LDPT_GET_SYMBOLS_V2:
459 tv_get_symbols_v2 = tv->tv_u.tv_get_symbols;
460 break;
5d3236ee
DK
461 case LDPT_ADD_INPUT_FILE:
462 SETVAR(tv_add_input_file);
463 break;
464 case LDPT_MESSAGE:
465 SETVAR(tv_message);
466 break;
467 case LDPT_GET_INPUT_FILE:
468 SETVAR(tv_get_input_file);
469 break;
15f7a26b
L
470 case LDPT_GET_VIEW:
471 SETVAR(tv_get_view);
472 break;
5d3236ee
DK
473 case LDPT_RELEASE_INPUT_FILE:
474 SETVAR(tv_release_input_file);
475 break;
476 case LDPT_ADD_INPUT_LIBRARY:
477 SETVAR(tv_add_input_library);
478 break;
479 case LDPT_SET_EXTRA_LIBRARY_PATH:
480 SETVAR(tv_set_extra_library_path);
481 break;
482 }
483#undef SETVAR
484 return LDPS_OK;
485}
486
487/* Record any useful information in transfer vector entry and display
488 it in human-readable form using the plugin API message() callback. */
489enum ld_plugin_status
490parse_and_dump_tv_tag (size_t n, struct ld_plugin_tv *tv)
491{
492 enum ld_plugin_status rv = parse_tv_tag (tv);
493 dump_tv_tag (n, tv);
494 return rv;
495}
496
497/* Standard plugin API entry point. */
498enum ld_plugin_status
499onload (struct ld_plugin_tv *tv)
500{
501 size_t n = 0;
502 enum ld_plugin_status rv;
503
504 /* This plugin does nothing but dump the tv array. It would
505 be an error if this function was called without one. */
506 if (!tv)
507 return LDPS_ERR;
508
509 /* First entry should always be LDPT_MESSAGE, letting us get
510 hold of it easily so we can send output straight away. */
511 if (tv[0].tv_tag == LDPT_MESSAGE)
512 tv_message = tv[0].tv_u.tv_message;
513
514 fflush (NULL);
ada487f6 515 TV_MESSAGE (LDPL_INFO, "Hello from testplugin.");
5d3236ee
DK
516
517 do
518 if ((rv = parse_and_dump_tv_tag (n++, tv)) != LDPS_OK)
519 return rv;
520 while ((tv++)->tv_tag != LDPT_NULL);
521
5d3236ee
DK
522 /* Register hooks only if instructed by options. */
523 if (register_claimfile_hook)
524 {
525 if (!tv_register_claim_file)
526 {
ada487f6 527 TV_MESSAGE (LDPL_FATAL, "No register_claim_file hook");
5d3236ee
DK
528 fflush (NULL);
529 return LDPS_ERR;
530 }
531 (*tv_register_claim_file) (onclaim_file);
532 }
533 if (register_allsymbolsread_hook)
534 {
535 if (!tv_register_all_symbols_read)
536 {
ada487f6 537 TV_MESSAGE (LDPL_FATAL, "No register_all_symbols_read hook");
5d3236ee
DK
538 fflush (NULL);
539 return LDPS_ERR;
540 }
541 (*tv_register_all_symbols_read) (onall_symbols_read);
542 }
543 if (register_cleanup_hook)
544 {
545 if (!tv_register_cleanup)
546 {
ada487f6 547 TV_MESSAGE (LDPL_FATAL, "No register_cleanup hook");
5d3236ee
DK
548 fflush (NULL);
549 return LDPS_ERR;
550 }
551 (*tv_register_cleanup) (oncleanup);
552 }
553 fflush (NULL);
554 return onload_ret;
555}
556
557/* Standard plugin API registerable hook. */
558static enum ld_plugin_status
559onclaim_file (const struct ld_plugin_input_file *file, int *claimed)
560{
ace667e5
AB
561 /* Possible read of some bytes out of the input file into a buffer. This
562 simulates a plugin that reads some file content in order to decide if
563 the file should be claimed or not. */
564 if (bytes_to_read_before_claim > 0)
565 {
566 char *buffer = malloc (bytes_to_read_before_claim);
567
568 if (buffer == NULL)
569 return LDPS_ERR;
570 if (read (file->fd, buffer, bytes_to_read_before_claim) < 0)
571 return LDPS_ERR;
572 free (buffer);
573 }
574
5d3236ee
DK
575 /* Let's see if we want to claim this file. */
576 claim_file_t *claimfile = claimfiles_list;
577 while (claimfile)
578 {
f4c37f56 579 if (!strcmp (file->name, claimfile->file.name))
5d3236ee
DK
580 break;
581 claimfile = claimfile->next;
582 }
583
584 /* Inform the user/testsuite. */
ada487f6
L
585 TV_MESSAGE (LDPL_INFO, "hook called: claim_file %s [@%ld/%ld] %s",
586 file->name, (long)file->offset, (long)file->filesize,
587 claimfile ? "CLAIMED" : "not claimed");
5d3236ee
DK
588 fflush (NULL);
589
590 /* If we decided to claim it, record that fact, and add any symbols
591 that were defined for it by plugin options. */
592 *claimed = (claimfile != 0);
593 if (claimfile)
594 {
595 claimfile->claimed = TRUE;
596 claimfile->file = *file;
597 if (claimfile->n_syms_used && !tv_add_symbols)
598 return LDPS_ERR;
599 else if (claimfile->n_syms_used)
600 return (*tv_add_symbols) (claimfile->file.handle,
601 claimfile->n_syms_used, claimfile->symbols);
602 }
603
604 return claim_file_ret;
605}
606
607/* Standard plugin API registerable hook. */
608static enum ld_plugin_status
609onall_symbols_read (void)
610{
611 static const char *resolutions[] =
612 {
613 "LDPR_UNKNOWN",
614 "LDPR_UNDEF",
615 "LDPR_PREVAILING_DEF",
616 "LDPR_PREVAILING_DEF_IRONLY",
617 "LDPR_PREEMPTED_REG",
618 "LDPR_PREEMPTED_IR",
619 "LDPR_RESOLVED_IR",
620 "LDPR_RESOLVED_EXEC",
621 "LDPR_RESOLVED_DYN",
69ee6ab2 622 "LDPR_PREVAILING_DEF_IRONLY_EXP",
5d3236ee
DK
623 };
624 claim_file_t *claimfile = dumpresolutions ? claimfiles_list : NULL;
625 add_file_t *addfile = addfiles_list;
ada487f6 626 TV_MESSAGE (LDPL_INFO, "hook called: all symbols read.");
5d3236ee
DK
627 for ( ; claimfile; claimfile = claimfile->next)
628 {
629 enum ld_plugin_status rv;
630 int n;
69ee6ab2 631 if (claimfile->n_syms_used && !tv_get_symbols_v2)
5d3236ee
DK
632 return LDPS_ERR;
633 else if (!claimfile->n_syms_used)
634 continue;
69ee6ab2
AM
635 rv = tv_get_symbols_v2 (claimfile->file.handle, claimfile->n_syms_used,
636 claimfile->symbols);
5d3236ee
DK
637 if (rv != LDPS_OK)
638 return rv;
639 for (n = 0; n < claimfile->n_syms_used; n++)
ada487f6
L
640 TV_MESSAGE (LDPL_INFO, "Sym: '%s%s%s' Resolution: %s",
641 claimfile->symbols[n].name,
642 claimfile->symbols[n].version ? "@" : "",
643 (claimfile->symbols[n].version
644 ? claimfile->symbols[n].version : ""),
645 resolutions[claimfile->symbols[n].resolution]);
5d3236ee
DK
646 }
647 for ( ; addfile ; addfile = addfile->next)
648 {
649 enum ld_plugin_status rv;
650 if (addfile->type == ADD_LIB && tv_add_input_library)
651 rv = (*tv_add_input_library) (addfile->name);
652 else if (addfile->type == ADD_FILE && tv_add_input_file)
653 rv = (*tv_add_input_file) (addfile->name);
654 else if (addfile->type == ADD_DIR && tv_set_extra_library_path)
655 rv = (*tv_set_extra_library_path) (addfile->name);
656 else
657 rv = LDPS_ERR;
658 if (rv != LDPS_OK)
659 return rv;
660 }
661 fflush (NULL);
662 return all_symbols_read_ret;
663}
664
665/* Standard plugin API registerable hook. */
666static enum ld_plugin_status
667oncleanup (void)
668{
ada487f6 669 TV_MESSAGE (LDPL_INFO, "hook called: cleanup.");
5d3236ee
DK
670 fflush (NULL);
671 return cleanup_ret;
672}
0381901e 673#endif /* BFD_SUPPORTS_PLUGINS */