]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/testplug4.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / ld / testplug4.c
CommitLineData
3355cb3b
L
1/* Test plugin for the GNU linker. Check non-object IR file as well as
2 get_input_file, get_view, release_input_file and get_symbols interfaces.
fd67aa11 3 Copyright (C) 2016-2024 Free Software Foundation, Inc.
3355cb3b
L
4
5 This file is part of the GNU Binutils.
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 "sysdep.h"
23#include "bfd.h"
0381901e 24#if BFD_SUPPORTS_PLUGINS
3355cb3b
L
25#include "plugin-api.h"
26#include "filenames.h"
27/* For ARRAY_SIZE macro only - we don't link the library itself. */
28#include "libiberty.h"
29
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;
f38a2680 44 bool claimed;
3355cb3b
L
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),
b21318bd 85 ADDENTRY(LDPT_REGISTER_CLAIM_FILE_HOOK_V2),
3355cb3b
L
86 ADDENTRY(LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK),
87 ADDENTRY(LDPT_REGISTER_CLEANUP_HOOK),
88 ADDENTRY(LDPT_ADD_SYMBOLS),
89 ADDENTRY(LDPT_GET_SYMBOLS),
90 ADDENTRY(LDPT_GET_SYMBOLS_V2),
91 ADDENTRY(LDPT_ADD_INPUT_FILE),
92 ADDENTRY(LDPT_MESSAGE),
93 ADDENTRY(LDPT_GET_INPUT_FILE),
94 ADDENTRY(LDPT_GET_VIEW),
95 ADDENTRY(LDPT_RELEASE_INPUT_FILE),
96 ADDENTRY(LDPT_ADD_INPUT_LIBRARY),
97 ADDENTRY(LDPT_OUTPUT_NAME),
98 ADDENTRY(LDPT_SET_EXTRA_LIBRARY_PATH),
99 ADDENTRY(LDPT_GNU_LD_VERSION)
100};
101
102/* Function pointers to cache hooks passed at onload time. */
103static ld_plugin_register_claim_file tv_register_claim_file = 0;
b21318bd 104static ld_plugin_register_claim_file_v2 tv_register_claim_file_v2 = 0;
3355cb3b
L
105static ld_plugin_register_all_symbols_read tv_register_all_symbols_read = 0;
106static ld_plugin_register_cleanup tv_register_cleanup = 0;
107static ld_plugin_add_symbols tv_add_symbols = 0;
108static ld_plugin_get_symbols tv_get_symbols = 0;
109static ld_plugin_get_symbols tv_get_symbols_v2 = 0;
110static ld_plugin_add_input_file tv_add_input_file = 0;
111static ld_plugin_message tv_message = 0;
112static ld_plugin_get_input_file tv_get_input_file = 0;
113static ld_plugin_get_view tv_get_view = 0;
114static ld_plugin_release_input_file tv_release_input_file = 0;
115static ld_plugin_add_input_library tv_add_input_library = 0;
116static ld_plugin_set_extra_library_path tv_set_extra_library_path = 0;
117
118/* Other cached info from the transfer vector. */
119static enum ld_plugin_output_file_type linker_output;
120static const char *output_name;
121
122/* Behaviour control flags set by plugin options. */
123static enum ld_plugin_status onload_ret = LDPS_OK;
124static enum ld_plugin_status claim_file_ret = LDPS_OK;
125static enum ld_plugin_status all_symbols_read_ret = LDPS_OK;
126static enum ld_plugin_status cleanup_ret = LDPS_OK;
f38a2680
AM
127static bool register_claimfile_hook = true;
128static bool register_allsymbolsread_hook = false;
129static bool register_cleanup_hook = false;
130static bool dumpresolutions = false;
131static bool allsymbolsread_silent = false;
3355cb3b
L
132
133/* The master list of all claimable/claimed files. */
134static claim_file_t *claimfiles_list = NULL;
135
136/* We keep a tail pointer for easy linking on the end. */
137static claim_file_t **claimfiles_tail_chain_ptr = &claimfiles_list;
138
139/* The last claimed file added to the list, for receiving syms. */
140static claim_file_t *last_claimfile = NULL;
141
142/* The master list of all files to add to the final link. */
143static add_file_t *addfiles_list = NULL;
144
145/* We keep a tail pointer for easy linking on the end. */
146static add_file_t **addfiles_tail_chain_ptr = &addfiles_list;
147
148/* Add a new claimfile on the end of the chain. */
149static enum ld_plugin_status
150record_claim_file (const char *file, off_t filesize)
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 newfile->file.filesize = filesize;
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
169/* Add a new addfile on the end of the chain. */
170static enum ld_plugin_status
171record_add_file (const char *file, addfile_enum_t type)
172{
173 add_file_t *newfile;
174
175 newfile = malloc (sizeof *newfile);
176 if (!newfile)
177 return LDPS_ERR;
178 newfile->next = NULL;
179 newfile->name = file;
180 newfile->type = type;
181 /* Chain it on the end of the list. */
182 *addfiles_tail_chain_ptr = newfile;
183 addfiles_tail_chain_ptr = &newfile->next;
184 return LDPS_OK;
185}
186
187/* Parse a command-line argument string into a symbol definition.
188 Symbol-strings follow the colon-separated format:
189 NAME:VERSION:def:vis:size:COMDATKEY
190 where the fields in capitals are strings and those in lower
191 case are integers. We don't allow to specify a resolution as
192 doing so is not meaningful when calling the add symbols hook. */
193static enum ld_plugin_status
194parse_symdefstr (const char *str, struct ld_plugin_symbol *sym)
195{
196 int n;
197 long long size;
198 const char *colon1, *colon2, *colon5;
199
200 /* Locate the colons separating the first two strings. */
201 colon1 = strchr (str, ':');
202 if (!colon1)
203 return LDPS_ERR;
204 colon2 = strchr (colon1+1, ':');
205 if (!colon2)
206 return LDPS_ERR;
207 /* Name must not be empty (version may be). */
208 if (colon1 == str)
209 return LDPS_ERR;
210
211 /* The fifth colon and trailing comdat key string are optional,
212 but the intermediate ones must all be present. */
213 colon5 = strchr (colon2+1, ':'); /* Actually only third so far. */
214 if (!colon5)
215 return LDPS_ERR;
216 colon5 = strchr (colon5+1, ':'); /* Hopefully fourth now. */
217 if (!colon5)
218 return LDPS_ERR;
219 colon5 = strchr (colon5+1, ':'); /* Optional fifth now. */
220
221 /* Finally we'll use sscanf to parse the numeric fields, then
222 we'll split out the strings which we need to allocate separate
223 storage for anyway so that we can add nul termination. */
c02d6661 224 n = sscanf (colon2 + 1, "%hhi:%i:%lli", &sym->def, &sym->visibility, &size);
3355cb3b
L
225 if (n != 3)
226 return LDPS_ERR;
227
228 /* Parsed successfully, so allocate strings and fill out fields. */
229 sym->size = size;
c02d6661
AM
230 sym->unused = 0;
231 sym->section_kind = 0;
232 sym->symbol_type = 0;
3355cb3b
L
233 sym->resolution = LDPR_UNKNOWN;
234 sym->name = malloc (colon1 - str + 1);
235 if (!sym->name)
236 return LDPS_ERR;
237 memcpy (sym->name, str, colon1 - str);
238 sym->name[colon1 - str] = '\0';
239 if (colon2 > (colon1 + 1))
240 {
241 sym->version = malloc (colon2 - colon1);
242 if (!sym->version)
243 return LDPS_ERR;
244 memcpy (sym->version, colon1 + 1, colon2 - (colon1 + 1));
245 sym->version[colon2 - (colon1 + 1)] = '\0';
246 }
247 else
248 sym->version = NULL;
249 if (colon5 && colon5[1])
250 {
251 sym->comdat_key = malloc (strlen (colon5 + 1) + 1);
252 if (!sym->comdat_key)
253 return LDPS_ERR;
254 strcpy (sym->comdat_key, colon5 + 1);
255 }
256 else
257 sym->comdat_key = 0;
258 return LDPS_OK;
259}
260
261/* Record a symbol to be added for the last-added claimfile. */
262static enum ld_plugin_status
263record_claimed_file_symbol (const char *symdefstr)
264{
265 struct ld_plugin_symbol sym;
266
267 /* Can't add symbols except as belonging to claimed files. */
268 if (!last_claimfile)
269 return LDPS_ERR;
270
271 /* If string doesn't parse correctly, give an error. */
272 if (parse_symdefstr (symdefstr, &sym) != LDPS_OK)
273 return LDPS_ERR;
274
275 /* Check for enough space, resize array if needed, and add it. */
276 if (last_claimfile->n_syms_allocated == last_claimfile->n_syms_used)
277 {
278 int new_n_syms = last_claimfile->n_syms_allocated
279 ? 2 * last_claimfile->n_syms_allocated
280 : 10;
281 last_claimfile->symbols = realloc (last_claimfile->symbols,
282 new_n_syms * sizeof *last_claimfile->symbols);
283 if (!last_claimfile->symbols)
284 return LDPS_ERR;
285 last_claimfile->n_syms_allocated = new_n_syms;
286 }
287 last_claimfile->symbols[last_claimfile->n_syms_used++] = sym;
288
289 return LDPS_OK;
290}
291
292/* Records the status to return from one of the registered hooks. */
293static enum ld_plugin_status
294set_ret_val (const char *whichval, enum ld_plugin_status retval)
295{
296 if (!strcmp ("onload", whichval))
297 onload_ret = retval;
298 else if (!strcmp ("claimfile", whichval))
299 claim_file_ret = retval;
300 else if (!strcmp ("allsymbolsread", whichval))
301 all_symbols_read_ret = retval;
302 else if (!strcmp ("cleanup", whichval))
303 cleanup_ret = retval;
304 else
305 return LDPS_ERR;
306 return LDPS_OK;
307}
308
309/* Records hooks which should be registered. */
310static enum ld_plugin_status
f38a2680 311set_register_hook (const char *whichhook, bool yesno)
3355cb3b
L
312{
313 if (!strcmp ("claimfile", whichhook))
314 register_claimfile_hook = yesno;
315 else if (!strcmp ("allsymbolsread", whichhook))
316 register_allsymbolsread_hook = yesno;
317 else if (!strcmp ("allsymbolsreadsilent", whichhook))
318 {
319 register_allsymbolsread_hook = yesno;
f38a2680 320 allsymbolsread_silent = true;
3355cb3b
L
321 }
322 else if (!strcmp ("cleanup", whichhook))
323 register_cleanup_hook = yesno;
324 else
325 return LDPS_ERR;
326 return LDPS_OK;
327}
328
329/* Determine type of plugin option and pass to individual parsers. */
330static enum ld_plugin_status
331parse_option (const char *opt)
332{
333 if (!strncmp ("fatal", opt, 5))
334 {
335 TV_MESSAGE (LDPL_FATAL, "Fatal error");
336 fflush (NULL);
337 }
338 else if (!strncmp ("error", opt, 5))
339 {
340 TV_MESSAGE (LDPL_ERROR, "Error");
341 fflush (NULL);
342 }
343 else if (!strncmp ("warning", opt, 7))
344 {
345 TV_MESSAGE (LDPL_WARNING, "Warning");
346 fflush (NULL);
347 }
348 else if (!strncmp ("fail", opt, 4))
349 return set_ret_val (opt + 4, LDPS_ERR);
350 else if (!strncmp ("pass", opt, 4))
351 return set_ret_val (opt + 4, LDPS_OK);
352 else if (!strncmp ("register", opt, 8))
f38a2680 353 return set_register_hook (opt + 8, true);
3355cb3b 354 else if (!strncmp ("noregister", opt, 10))
f38a2680 355 return set_register_hook (opt + 10, false);
3355cb3b
L
356 else if (!strncmp ("claim:", opt, 6))
357 return record_claim_file (opt + 6, 0);
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))
f38a2680 367 dumpresolutions = true;
3355cb3b
L
368 else
369 return LDPS_ERR;
370 return LDPS_OK;
371}
372
373/* Handle/record information received in a transfer vector entry. */
374static enum ld_plugin_status
375parse_tv_tag (struct ld_plugin_tv *tv)
376{
377#define SETVAR(x) x = tv->tv_u.x
378 switch (tv->tv_tag)
379 {
380 case LDPT_OPTION:
381 return parse_option (tv->tv_u.tv_string);
382 case LDPT_NULL:
383 case LDPT_GOLD_VERSION:
384 case LDPT_GNU_LD_VERSION:
385 case LDPT_API_VERSION:
386 default:
387 break;
388 case LDPT_OUTPUT_NAME:
389 output_name = tv->tv_u.tv_string;
390 break;
391 case LDPT_LINKER_OUTPUT:
392 linker_output = tv->tv_u.tv_val;
393 break;
394 case LDPT_REGISTER_CLAIM_FILE_HOOK:
395 SETVAR(tv_register_claim_file);
396 break;
b21318bd
JM
397 case LDPT_REGISTER_CLAIM_FILE_HOOK_V2:
398 SETVAR(tv_register_claim_file_v2);
399 break;
3355cb3b
L
400 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
401 SETVAR(tv_register_all_symbols_read);
402 break;
403 case LDPT_REGISTER_CLEANUP_HOOK:
404 SETVAR(tv_register_cleanup);
405 break;
406 case LDPT_ADD_SYMBOLS:
407 SETVAR(tv_add_symbols);
408 break;
409 case LDPT_GET_SYMBOLS:
410 SETVAR(tv_get_symbols);
411 break;
412 case LDPT_GET_SYMBOLS_V2:
413 tv_get_symbols_v2 = tv->tv_u.tv_get_symbols;
414 break;
415 case LDPT_ADD_INPUT_FILE:
416 SETVAR(tv_add_input_file);
417 break;
418 case LDPT_MESSAGE:
419 SETVAR(tv_message);
420 break;
421 case LDPT_GET_INPUT_FILE:
422 SETVAR(tv_get_input_file);
423 break;
424 case LDPT_GET_VIEW:
425 SETVAR(tv_get_view);
426 break;
427 case LDPT_RELEASE_INPUT_FILE:
428 SETVAR(tv_release_input_file);
429 break;
430 case LDPT_ADD_INPUT_LIBRARY:
431 SETVAR(tv_add_input_library);
432 break;
433 case LDPT_SET_EXTRA_LIBRARY_PATH:
434 SETVAR(tv_set_extra_library_path);
435 break;
436 }
437#undef SETVAR
438 return LDPS_OK;
439}
440
441/* Standard plugin API entry point. */
442enum ld_plugin_status
443onload (struct ld_plugin_tv *tv)
444{
445 enum ld_plugin_status rv;
446
447 /* This plugin does nothing but dump the tv array. It would
448 be an error if this function was called without one. */
449 if (!tv)
450 return LDPS_ERR;
451
452 /* First entry should always be LDPT_MESSAGE, letting us get
453 hold of it easily so we can send output straight away. */
454 if (tv[0].tv_tag == LDPT_MESSAGE)
455 tv_message = tv[0].tv_u.tv_message;
456
457 do
458 if ((rv = parse_tv_tag (tv)) != LDPS_OK)
459 return rv;
460 while ((tv++)->tv_tag != LDPT_NULL);
461
462 /* Register hooks only if instructed by options. */
463 if (register_claimfile_hook)
464 {
465 if (!tv_register_claim_file)
466 {
467 TV_MESSAGE (LDPL_FATAL, "No register_claim_file hook");
468 fflush (NULL);
469 return LDPS_ERR;
470 }
471 (*tv_register_claim_file) (onclaim_file);
472 }
473 if (register_allsymbolsread_hook)
474 {
475 if (!tv_register_all_symbols_read)
476 {
477 TV_MESSAGE (LDPL_FATAL, "No register_all_symbols_read hook");
478 fflush (NULL);
479 return LDPS_ERR;
480 }
481 (*tv_register_all_symbols_read) (onall_symbols_read);
482 }
483 if (register_cleanup_hook)
484 {
485 if (!tv_register_cleanup)
486 {
487 TV_MESSAGE (LDPL_FATAL, "No register_cleanup hook");
488 fflush (NULL);
489 return LDPS_ERR;
490 }
491 (*tv_register_cleanup) (oncleanup);
492 }
493
494 /* Claim testsuite/ld-plugin/pr20070b.c, standalone or in a library.
495 Its size must be SIZE_OF_PR20070B_C bytes. */
496#define SIZE_OF_PR20070B_C 248
497 if (onload_ret == LDPS_OK
498 && (record_claim_file ("pr20070b.c", SIZE_OF_PR20070B_C) != LDPS_OK
499 || record_claimed_file_symbol ("def::0:0:0") != LDPS_OK
500 || record_claimed_file_symbol ("weakdef::1:0:0") != LDPS_OK
501 || record_claimed_file_symbol ("undef::2:0:0") != LDPS_OK
502 || record_claimed_file_symbol ("weakundef::3:0:0") != LDPS_OK
503 || record_claimed_file_symbol ("common::4:0:0") != LDPS_OK
504 || record_claim_file ("libpr20070.a", SIZE_OF_PR20070B_C) != LDPS_OK
505 || record_claimed_file_symbol ("def::0:0:0") != LDPS_OK
506 || record_claimed_file_symbol ("weakdef::1:0:0") != LDPS_OK
507 || record_claimed_file_symbol ("undef::2:0:0") != LDPS_OK
508 || record_claimed_file_symbol ("weakundef::3:0:0") != LDPS_OK
509 || record_claimed_file_symbol ("common::4:0:0") != LDPS_OK))
510 onload_ret = LDPS_ERR;
511
512 return onload_ret;
513}
514
515char *
516xstrdup (const char *s)
517{
518 size_t len = strlen (s) + 1;
519 char *ret = malloc (len + 1);
520 return (char *) memcpy (ret, s, len);
521}
522
523/* Standard plugin API registerable hook. */
524static enum ld_plugin_status
525onclaim_file (const struct ld_plugin_input_file *file, int *claimed)
526{
527 /* Let's see if we want to claim this file. */
528 claim_file_t *claimfile = claimfiles_list;
529 size_t len = strlen (file->name);
530 char *name = xstrdup (file->name);
531 char *p = name + len;
f38a2680 532 bool islib;
3355cb3b
L
533
534 /* Only match the file name without the directory part. */
535 islib = *p == 'a' && *(p - 1) == '.';
536 for (; p != name; p--)
537 if (IS_DIR_SEPARATOR (*p))
538 {
539 p++;
540 break;
541 }
542
543 while (claimfile)
544 {
545 /* Claim the file only if the file name and size match and don't
546 match the whole library. */
547 if (!strcmp (p, claimfile->file.name)
548 && claimfile->file.filesize == file->filesize
549 && (!islib || file->offset != 0))
550 break;
551 claimfile = claimfile->next;
552 }
553
554 free (name);
555
556 /* If we decided to claim it, record that fact, and add any symbols
557 that were defined for it by plugin options. */
558 *claimed = (claimfile != 0);
559 if (claimfile)
560 {
f38a2680 561 claimfile->claimed = true;
3355cb3b
L
562 claimfile->file = *file;
563 if (claimfile->n_syms_used && !tv_add_symbols)
564 return LDPS_ERR;
565 else if (claimfile->n_syms_used)
566 return (*tv_add_symbols) (claimfile->file.handle,
567 claimfile->n_syms_used, claimfile->symbols);
568 }
569
570 return claim_file_ret;
571}
572
573/* Standard plugin API registerable hook. */
574static enum ld_plugin_status
575onall_symbols_read (void)
576{
577 static const char *resolutions[] =
578 {
579 "LDPR_UNKNOWN",
580 "LDPR_UNDEF",
581 "LDPR_PREVAILING_DEF",
582 "LDPR_PREVAILING_DEF_IRONLY",
583 "LDPR_PREEMPTED_REG",
584 "LDPR_PREEMPTED_IR",
585 "LDPR_RESOLVED_IR",
586 "LDPR_RESOLVED_EXEC",
587 "LDPR_RESOLVED_DYN",
588 "LDPR_PREVAILING_DEF_IRONLY_EXP",
589 };
590 claim_file_t *claimfile = dumpresolutions ? claimfiles_list : NULL;
591 add_file_t *addfile = addfiles_list;
592 struct ld_plugin_input_file file;
593 const void *view;
594 char buffer[30];
595 int fd;
596 char *filename;
597 if (! allsymbolsread_silent)
598 TV_MESSAGE (LDPL_INFO, "hook called: all symbols read.");
599 for ( ; claimfile; claimfile = claimfile->next)
600 {
601 enum ld_plugin_status rv;
602 int n;
603 if (claimfile->n_syms_used && !tv_get_symbols_v2)
604 return LDPS_ERR;
605 else if (!claimfile->n_syms_used)
606 continue;
607 else if (!claimfile->file.handle)
608 continue;
609 rv = tv_get_input_file (claimfile->file.handle, &file);
610 if (rv != LDPS_OK)
611 return rv;
612 TV_MESSAGE (LDPL_INFO, "Input: %s (%s)", file.name,
613 claimfile->file.name);
614 rv = tv_get_view (claimfile->file.handle, &view);
615 if (rv != LDPS_OK)
616 return rv;
617#define EXPECTED_VIEW "/* The first line of this file must match the expectation of"
618#define EXPECTED_VIEW_LENGTH (sizeof (EXPECTED_VIEW) - 1)
619 if (file.filesize != SIZE_OF_PR20070B_C
bf6f87e7 620 || SIZE_OF_PR20070B_C < EXPECTED_VIEW_LENGTH
3355cb3b
L
621 || memcmp (view, EXPECTED_VIEW, EXPECTED_VIEW_LENGTH) != 0)
622 {
623 char result[EXPECTED_VIEW_LENGTH + 1];
624 memcpy (result, view, sizeof (result));
625 result[EXPECTED_VIEW_LENGTH] = '\0';
626 TV_MESSAGE (LDPL_INFO, "Incorrect view:");
627 TV_MESSAGE (LDPL_INFO, " Expect: " EXPECTED_VIEW);
628 TV_MESSAGE (LDPL_INFO, " Result: %s", result);
629 }
630 rv = tv_get_symbols_v2 (claimfile->file.handle, claimfile->n_syms_used,
631 claimfile->symbols);
632 if (rv != LDPS_OK)
633 return rv;
634 for (n = 0; n < claimfile->n_syms_used; n++)
635 TV_MESSAGE (LDPL_INFO, "Sym: '%s%s%s' Resolution: %s",
636 claimfile->symbols[n].name,
637 claimfile->symbols[n].version ? "@" : "",
638 (claimfile->symbols[n].version
639 ? claimfile->symbols[n].version : ""),
640 resolutions[claimfile->symbols[n].resolution]);
641 fd = claimfile->file.fd;
642 filename = xstrdup (claimfile->file.name);
643 rv = tv_release_input_file (claimfile->file.handle);
644 if (rv != LDPS_OK)
645 {
646 free (filename);
647 return rv;
648 }
649 if (read (fd, buffer, sizeof (buffer)) >= 0)
650 {
651 TV_MESSAGE (LDPL_FATAL, "Unreleased file descriptor on: %s",
652 claimfile->file.name);
653 free (filename);
654 return LDPS_ERR;
655 }
656 free (filename);
657 }
658 for ( ; addfile ; addfile = addfile->next)
659 {
660 enum ld_plugin_status rv;
661 if (addfile->type == ADD_LIB && tv_add_input_library)
662 rv = (*tv_add_input_library) (addfile->name);
663 else if (addfile->type == ADD_FILE && tv_add_input_file)
664 rv = (*tv_add_input_file) (addfile->name);
665 else if (addfile->type == ADD_DIR && tv_set_extra_library_path)
666 rv = (*tv_set_extra_library_path) (addfile->name);
667 else
668 rv = LDPS_ERR;
669 if (rv != LDPS_OK)
670 return rv;
671 }
672 fflush (NULL);
673 return all_symbols_read_ret;
674}
675
676/* Standard plugin API registerable hook. */
677static enum ld_plugin_status
678oncleanup (void)
679{
680 TV_MESSAGE (LDPL_INFO, "hook called: cleanup.");
681 fflush (NULL);
682 return cleanup_ret;
683}
0381901e 684#endif /* BFD_SUPPORTS_PLUGINS */