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