1 /* Plugin support for BFD. 2 Copyright (C) 2009-2022 Free Software Foundation, Inc. 3 4 This file is part of BFD, the Binary File Descriptor library. 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 24 #if BFD_SUPPORTS_PLUGINS 25 26 #include <assert.h> 27 #ifdef HAVE_DLFCN_H 28 #include <dlfcn.h> 29 #elif defined (HAVE_WINDOWS_H) 30 #include <windows.h> 31 #else 32 #error Unknown how to handle dynamic-load-libraries. 33 #endif 34 #include <stdarg.h> 35 #include "plugin-api.h" 36 #include "plugin.h" 37 #include "libbfd.h" 38 #include "libiberty.h" 39 #include <dirent.h> 40 41 #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) 42 43 #define RTLD_NOW 0 /* Dummy value. */ 44 45 static void * 46 dlopen (const char *file, int mode ATTRIBUTE_UNUSED) 47 { 48 return LoadLibrary (file); 49 } 50 51 static void * 52 dlsym (void *handle, const char *name) 53 { 54 return GetProcAddress (handle, name); 55 } 56 57 static int ATTRIBUTE_UNUSED 58 dlclose (void *handle) 59 { 60 FreeLibrary (handle); 61 return 0; 62 } 63 64 static const char * 65 dlerror (void) 66 { 67 return "Unable to load DLL."; 68 } 69 70 #endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) */ 71 72 #define bfd_plugin_close_and_cleanup _bfd_generic_close_and_cleanup 73 #define bfd_plugin_bfd_free_cached_info _bfd_generic_bfd_free_cached_info 74 #define bfd_plugin_new_section_hook _bfd_generic_new_section_hook 75 #define bfd_plugin_get_section_contents _bfd_generic_get_section_contents 76 #define bfd_plugin_get_section_contents_in_window _bfd_generic_get_section_contents_in_window 77 #define bfd_plugin_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data 78 #define bfd_plugin_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data 79 #define bfd_plugin_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data 80 #define bfd_plugin_bfd_set_private_flags _bfd_generic_bfd_set_private_flags 81 #define bfd_plugin_core_file_matches_executable_p generic_core_file_matches_executable_p 82 #define bfd_plugin_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name 83 #define bfd_plugin_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false 84 #define bfd_plugin_get_lineno _bfd_nosymbols_get_lineno 85 #define bfd_plugin_find_nearest_line _bfd_nosymbols_find_nearest_line 86 #define bfd_plugin_find_line _bfd_nosymbols_find_line 87 #define bfd_plugin_find_inliner_info _bfd_nosymbols_find_inliner_info 88 #define bfd_plugin_get_symbol_version_string _bfd_nosymbols_get_symbol_version_string 89 #define bfd_plugin_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol 90 #define bfd_plugin_read_minisymbols _bfd_generic_read_minisymbols 91 #define bfd_plugin_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol 92 #define bfd_plugin_set_arch_mach bfd_default_set_arch_mach 93 #define bfd_plugin_set_section_contents _bfd_generic_set_section_contents 94 #define bfd_plugin_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents 95 #define bfd_plugin_bfd_relax_section bfd_generic_relax_section 96 #define bfd_plugin_bfd_link_hash_table_create _bfd_generic_link_hash_table_create 97 #define bfd_plugin_bfd_link_add_symbols _bfd_generic_link_add_symbols 98 #define bfd_plugin_bfd_link_just_syms _bfd_generic_link_just_syms 99 #define bfd_plugin_bfd_final_link _bfd_generic_final_link 100 #define bfd_plugin_bfd_link_split_section _bfd_generic_link_split_section 101 #define bfd_plugin_bfd_gc_sections bfd_generic_gc_sections 102 #define bfd_plugin_bfd_lookup_section_flags bfd_generic_lookup_section_flags 103 #define bfd_plugin_bfd_merge_sections bfd_generic_merge_sections 104 #define bfd_plugin_bfd_is_group_section bfd_generic_is_group_section 105 #define bfd_plugin_bfd_group_name bfd_generic_group_name 106 #define bfd_plugin_bfd_discard_group bfd_generic_discard_group 107 #define bfd_plugin_section_already_linked _bfd_generic_section_already_linked 108 #define bfd_plugin_bfd_define_common_symbol bfd_generic_define_common_symbol 109 #define bfd_plugin_bfd_link_hide_symbol _bfd_generic_link_hide_symbol 110 #define bfd_plugin_bfd_define_start_stop bfd_generic_define_start_stop 111 #define bfd_plugin_bfd_copy_link_hash_symbol_type _bfd_generic_copy_link_hash_symbol_type 112 #define bfd_plugin_bfd_link_check_relocs _bfd_generic_link_check_relocs 113 114 static enum ld_plugin_status 115 message (int level ATTRIBUTE_UNUSED, 116 const char * format, ...) 117 { 118 va_list args; 119 va_start (args, format); 120 printf ("bfd plugin: "); 121 vprintf (format, args); 122 putchar ('\n'); 123 va_end (args); 124 return LDPS_OK; 125 } 126 127 struct plugin_list_entry 128 { 129 /* These must be initialized for each IR object with LTO wrapper. */ 130 ld_plugin_claim_file_handler claim_file; 131 ld_plugin_all_symbols_read_handler all_symbols_read; 132 ld_plugin_all_symbols_read_handler cleanup_handler; 133 bool has_symbol_type; 134 135 struct plugin_list_entry *next; 136 137 /* These can be reused for all IR objects. */ 138 const char *plugin_name; 139 }; 140 141 static const char *plugin_program_name; 142 143 void 144 bfd_plugin_set_program_name (const char *program_name) 145 { 146 plugin_program_name = program_name; 147 } 148 149 static struct plugin_list_entry *plugin_list = NULL; 150 static struct plugin_list_entry *current_plugin = NULL; 151 152 /* Register a claim-file handler. */ 153 154 static enum ld_plugin_status 155 register_claim_file (ld_plugin_claim_file_handler handler) 156 { 157 current_plugin->claim_file = handler; 158 return LDPS_OK; 159 } 160 161 static enum ld_plugin_status 162 add_symbols (void * handle, 163 int nsyms, 164 const struct ld_plugin_symbol * syms) 165 { 166 bfd *abfd = handle; 167 struct plugin_data_struct *plugin_data = 168 bfd_alloc (abfd, sizeof (plugin_data_struct)); 169 170 if (!plugin_data) 171 return LDPS_ERR; 172 173 plugin_data->nsyms = nsyms; 174 plugin_data->syms = syms; 175 176 if (nsyms != 0) 177 abfd->flags |= HAS_SYMS; 178 179 abfd->tdata.plugin_data = plugin_data; 180 return LDPS_OK; 181 } 182 183 static enum ld_plugin_status 184 add_symbols_v2 (void *handle, int nsyms, 185 const struct ld_plugin_symbol *syms) 186 { 187 current_plugin->has_symbol_type = true; 188 return add_symbols (handle, nsyms, syms); 189 } 190 191 int 192 bfd_plugin_open_input (bfd *ibfd, struct ld_plugin_input_file *file) 193 { 194 bfd *iobfd; 195 int fd; 196 197 iobfd = ibfd; 198 while (iobfd->my_archive 199 && !bfd_is_thin_archive (iobfd->my_archive)) 200 iobfd = iobfd->my_archive; 201 file->name = bfd_get_filename (iobfd); 202 203 if (!iobfd->iostream && !bfd_open_file (iobfd)) 204 return 0; 205 206 /* Reuse the archive plugin file descriptor. */ 207 if (iobfd != ibfd) 208 fd = iobfd->archive_plugin_fd; 209 else 210 fd = -1; 211 212 if (fd < 0) 213 { 214 /* The plugin API expects that the file descriptor won't be closed 215 and reused as done by the bfd file cache. So open it again. 216 dup isn't good enough. plugin IO uses lseek/read while BFD uses 217 fseek/fread. It isn't wise to mix the unistd and stdio calls on 218 the same underlying file descriptor. */ 219 fd = open (file->name, O_RDONLY | O_BINARY); 220 if (fd < 0) 221 { 222 #ifndef EMFILE 223 return 0; 224 #else 225 if (errno != EMFILE) 226 return 0; 227 228 #ifdef HAVE_GETRLIMIT 229 struct rlimit lim; 230 231 /* Complicated links involving lots of files and/or large 232 archives can exhaust the number of file descriptors 233 available to us. If possible, try to allocate more 234 descriptors. */ 235 if (getrlimit (RLIMIT_NOFILE, & lim) == 0 236 && lim.rlim_cur < lim.rlim_max) 237 { 238 lim.rlim_cur = lim.rlim_max; 239 if (setrlimit (RLIMIT_NOFILE, &lim) == 0) 240 fd = open (file->name, O_RDONLY | O_BINARY); 241 } 242 243 if (fd < 0) 244 #endif 245 { 246 _bfd_error_handler (_("plugin framework: out of file descriptors. Try using fewer objects/archives\n")); 247 return 0; 248 } 249 #endif 250 } 251 } 252 253 if (iobfd == ibfd) 254 { 255 struct stat stat_buf; 256 257 if (fstat (fd, &stat_buf)) 258 { 259 close (fd); 260 return 0; 261 } 262 263 file->offset = 0; 264 file->filesize = stat_buf.st_size; 265 } 266 else 267 { 268 /* Cache the archive plugin file descriptor. */ 269 iobfd->archive_plugin_fd = fd; 270 iobfd->archive_plugin_fd_open_count++; 271 272 file->offset = ibfd->origin; 273 file->filesize = arelt_size (ibfd); 274 } 275 276 file->fd = fd; 277 return 1; 278 } 279 280 /* Close the plugin file descriptor FD. If ABFD isn't NULL, it is an 281 archive member. */ 282 283 void 284 bfd_plugin_close_file_descriptor (bfd *abfd, int fd) 285 { 286 if (abfd == NULL) 287 close (fd); 288 else 289 { 290 while (abfd->my_archive 291 && !bfd_is_thin_archive (abfd->my_archive)) 292 abfd = abfd->my_archive; 293 294 /* Close the file descriptor if there is no archive plugin file 295 descriptor. */ 296 if (abfd->archive_plugin_fd == -1) 297 { 298 close (fd); 299 return; 300 } 301 302 abfd->archive_plugin_fd_open_count--; 303 /* Dup the archive plugin file descriptor for later use, which 304 will be closed by _bfd_archive_close_and_cleanup. */ 305 if (abfd->archive_plugin_fd_open_count == 0) 306 { 307 abfd->archive_plugin_fd = dup (fd); 308 close (fd); 309 } 310 } 311 } 312 313 static int 314 try_claim (bfd *abfd) 315 { 316 int claimed = 0; 317 struct ld_plugin_input_file file; 318 319 file.handle = abfd; 320 if (bfd_plugin_open_input (abfd, &file) 321 && current_plugin->claim_file) 322 { 323 current_plugin->claim_file (&file, &claimed); 324 bfd_plugin_close_file_descriptor ((abfd->my_archive != NULL 325 ? abfd : NULL), 326 file.fd); 327 } 328 329 return claimed; 330 } 331 332 static bool 333 try_load_plugin (const char *pname, 334 struct plugin_list_entry *plugin_list_iter, 335 bfd *abfd, 336 bool build_list_p) 337 { 338 void *plugin_handle; 339 struct ld_plugin_tv tv[5]; 340 int i; 341 ld_plugin_onload onload; 342 enum ld_plugin_status status; 343 bool result = false; 344 345 /* NB: Each object is independent. Reuse the previous plugin from 346 the last run will lead to wrong result. */ 347 if (current_plugin) 348 memset (current_plugin, 0, 349 offsetof (struct plugin_list_entry, next)); 350 351 if (plugin_list_iter) 352 pname = plugin_list_iter->plugin_name; 353 354 plugin_handle = dlopen (pname, RTLD_NOW); 355 if (!plugin_handle) 356 { 357 /* If we are building a list of viable plugins, then 358 we do not bother the user with the details of any 359 plugins that cannot be loaded. */ 360 if (! build_list_p) 361 _bfd_error_handler ("Failed to load plugin '%s', reason: %s\n", 362 pname, dlerror ()); 363 return false; 364 } 365 366 if (plugin_list_iter == NULL) 367 { 368 size_t length_plugin_name = strlen (pname) + 1; 369 char *plugin_name = bfd_malloc (length_plugin_name); 370 371 if (plugin_name == NULL) 372 goto short_circuit; 373 plugin_list_iter = bfd_malloc (sizeof *plugin_list_iter); 374 if (plugin_list_iter == NULL) 375 { 376 free (plugin_name); 377 goto short_circuit; 378 } 379 /* Make a copy of PNAME since PNAME from load_plugin () will be 380 freed. */ 381 memcpy (plugin_name, pname, length_plugin_name); 382 memset (plugin_list_iter, 0, sizeof (*plugin_list_iter)); 383 plugin_list_iter->plugin_name = plugin_name; 384 plugin_list_iter->next = plugin_list; 385 plugin_list = plugin_list_iter; 386 } 387 388 current_plugin = plugin_list_iter; 389 if (build_list_p) 390 goto short_circuit; 391 392 onload = dlsym (plugin_handle, "onload"); 393 if (!onload) 394 goto short_circuit; 395 396 i = 0; 397 tv[i].tv_tag = LDPT_MESSAGE; 398 tv[i].tv_u.tv_message = message; 399 400 ++i; 401 tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK; 402 tv[i].tv_u.tv_register_claim_file = register_claim_file; 403 404 ++i; 405 tv[i].tv_tag = LDPT_ADD_SYMBOLS; 406 tv[i].tv_u.tv_add_symbols = add_symbols; 407 408 ++i; 409 tv[i].tv_tag = LDPT_ADD_SYMBOLS_V2; 410 tv[i].tv_u.tv_add_symbols = add_symbols_v2; 411 412 ++i; 413 tv[i].tv_tag = LDPT_NULL; 414 tv[i].tv_u.tv_val = 0; 415 416 /* LTO plugin will call handler hooks to set up plugin handlers. */ 417 status = (*onload)(tv); 418 419 if (status != LDPS_OK) 420 goto short_circuit; 421 422 abfd->plugin_format = bfd_plugin_no; 423 424 if (!current_plugin->claim_file) 425 goto short_circuit; 426 427 if (!try_claim (abfd)) 428 goto short_circuit; 429 430 abfd->plugin_format = bfd_plugin_yes; 431 result = true; 432 433 short_circuit: 434 dlclose (plugin_handle); 435 return result; 436 } 437 438 /* There may be plugin libraries in lib/bfd-plugins. */ 439 static int has_plugin_list = -1; 440 441 static bfd_cleanup (*ld_plugin_object_p) (bfd *); 442 443 static const char *plugin_name; 444 445 void 446 bfd_plugin_set_plugin (const char *p) 447 { 448 plugin_name = p; 449 } 450 451 /* Return TRUE if a plugin library is used. */ 452 453 bool 454 bfd_plugin_specified_p (void) 455 { 456 return plugin_list != NULL; 457 } 458 459 /* Return TRUE if ABFD can be claimed by linker LTO plugin. */ 460 461 bool 462 bfd_link_plugin_object_p (bfd *abfd) 463 { 464 if (ld_plugin_object_p) 465 return ld_plugin_object_p (abfd) != NULL; 466 return false; 467 } 468 469 extern const bfd_target plugin_vec; 470 471 /* Return TRUE if TARGET is a pointer to plugin_vec. */ 472 473 bool 474 bfd_plugin_target_p (const bfd_target *target) 475 { 476 return target == &plugin_vec; 477 } 478 479 /* Register OBJECT_P to be used by bfd_plugin_object_p. */ 480 481 void 482 register_ld_plugin_object_p (bfd_cleanup (*object_p) (bfd *)) 483 { 484 ld_plugin_object_p = object_p; 485 } 486 487 static void 488 build_plugin_list (bfd *abfd) 489 { 490 /* The intent was to search ${libdir}/bfd-plugins for plugins, but 491 unfortunately the original implementation wasn't precisely that 492 when configuring binutils using --libdir. Search in the proper 493 path first, then the old one for backwards compatibility. */ 494 static const char *path[] 495 = { LIBDIR "/bfd-plugins", BINDIR "/../lib/bfd-plugins" }; 496 struct stat last_st; 497 unsigned int i; 498 499 if (has_plugin_list >= 0) 500 return; 501 502 /* Try not to search the same dir twice, by looking at st_dev and 503 st_ino for the dir. If we are on a file system that always sets 504 st_ino to zero or the actual st_ino is zero we might waste some 505 time, but that doesn't matter too much. */ 506 last_st.st_dev = 0; 507 last_st.st_ino = 0; 508 for (i = 0; i < sizeof (path) / sizeof (path[0]); i++) 509 { 510 char *plugin_dir = make_relative_prefix (plugin_program_name, 511 BINDIR, 512 path[i]); 513 if (plugin_dir) 514 { 515 struct stat st; 516 DIR *d; 517 518 if (stat (plugin_dir, &st) == 0 519 && S_ISDIR (st.st_mode) 520 && !(last_st.st_dev == st.st_dev 521 && last_st.st_ino == st.st_ino 522 && st.st_ino != 0) 523 && (d = opendir (plugin_dir)) != NULL) 524 { 525 struct dirent *ent; 526 527 last_st.st_dev = st.st_dev; 528 last_st.st_ino = st.st_ino; 529 while ((ent = readdir (d)) != NULL) 530 { 531 char *full_name; 532 533 full_name = concat (plugin_dir, "/", ent->d_name, NULL); 534 if (stat (full_name, &st) == 0 && S_ISREG (st.st_mode)) 535 (void) try_load_plugin (full_name, NULL, abfd, true); 536 free (full_name); 537 } 538 closedir (d); 539 } 540 free (plugin_dir); 541 } 542 } 543 544 has_plugin_list = plugin_list != NULL; 545 } 546 547 static bool 548 load_plugin (bfd *abfd) 549 { 550 struct plugin_list_entry *plugin_list_iter; 551 552 if (plugin_name) 553 return try_load_plugin (plugin_name, plugin_list, abfd, false); 554 555 if (plugin_program_name == NULL) 556 return false; 557 558 build_plugin_list (abfd); 559 560 for (plugin_list_iter = plugin_list; 561 plugin_list_iter; 562 plugin_list_iter = plugin_list_iter->next) 563 if (try_load_plugin (NULL, plugin_list_iter, abfd, false)) 564 return true; 565 566 return false; 567 } 568 569 570 static bfd_cleanup 571 bfd_plugin_object_p (bfd *abfd) 572 { 573 if (ld_plugin_object_p) 574 return ld_plugin_object_p (abfd); 575 576 if (abfd->plugin_format == bfd_plugin_unknown && !load_plugin (abfd)) 577 return NULL; 578 579 return abfd->plugin_format == bfd_plugin_yes ? _bfd_no_cleanup : NULL; 580 } 581 582 /* Copy any private info we understand from the input bfd 583 to the output bfd. */ 584 585 static bool 586 bfd_plugin_bfd_copy_private_bfd_data (bfd *ibfd ATTRIBUTE_UNUSED, 587 bfd *obfd ATTRIBUTE_UNUSED) 588 { 589 BFD_ASSERT (0); 590 return true; 591 } 592 593 /* Copy any private info we understand from the input section 594 to the output section. */ 595 596 static bool 597 bfd_plugin_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, 598 asection *isection ATTRIBUTE_UNUSED, 599 bfd *obfd ATTRIBUTE_UNUSED, 600 asection *osection ATTRIBUTE_UNUSED) 601 { 602 BFD_ASSERT (0); 603 return true; 604 } 605 606 /* Copy any private info we understand from the input symbol 607 to the output symbol. */ 608 609 static bool 610 bfd_plugin_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED, 611 asymbol *isymbol ATTRIBUTE_UNUSED, 612 bfd *obfd ATTRIBUTE_UNUSED, 613 asymbol *osymbol ATTRIBUTE_UNUSED) 614 { 615 BFD_ASSERT (0); 616 return true; 617 } 618 619 static bool 620 bfd_plugin_bfd_print_private_bfd_data (bfd *abfd ATTRIBUTE_UNUSED, void *ptr ATTRIBUTE_UNUSED) 621 { 622 BFD_ASSERT (0); 623 return true; 624 } 625 626 static char * 627 bfd_plugin_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED) 628 { 629 BFD_ASSERT (0); 630 return NULL; 631 } 632 633 static int 634 bfd_plugin_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED) 635 { 636 BFD_ASSERT (0); 637 return 0; 638 } 639 640 static int 641 bfd_plugin_core_file_pid (bfd *abfd ATTRIBUTE_UNUSED) 642 { 643 BFD_ASSERT (0); 644 return 0; 645 } 646 647 static long 648 bfd_plugin_get_symtab_upper_bound (bfd *abfd) 649 { 650 struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data; 651 long nsyms = plugin_data->nsyms; 652 653 BFD_ASSERT (nsyms >= 0); 654 655 return ((nsyms + 1) * sizeof (asymbol *)); 656 } 657 658 static flagword 659 convert_flags (const struct ld_plugin_symbol *sym) 660 { 661 switch (sym->def) 662 { 663 case LDPK_DEF: 664 case LDPK_COMMON: 665 case LDPK_UNDEF: 666 return BSF_GLOBAL; 667 668 case LDPK_WEAKUNDEF: 669 case LDPK_WEAKDEF: 670 return BSF_GLOBAL | BSF_WEAK; 671 672 default: 673 BFD_ASSERT (0); 674 return 0; 675 } 676 } 677 678 static long 679 bfd_plugin_canonicalize_symtab (bfd *abfd, 680 asymbol **alocation) 681 { 682 struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data; 683 long nsyms = plugin_data->nsyms; 684 const struct ld_plugin_symbol *syms = plugin_data->syms; 685 static asection fake_text_section 686 = BFD_FAKE_SECTION (fake_text_section, NULL, "plug", 0, 687 SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS); 688 static asection fake_data_section 689 = BFD_FAKE_SECTION (fake_data_section, NULL, "plug", 0, 690 SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS); 691 static asection fake_bss_section 692 = BFD_FAKE_SECTION (fake_bss_section, NULL, "plug", 0, 693 SEC_ALLOC); 694 static asection fake_common_section 695 = BFD_FAKE_SECTION (fake_common_section, NULL, "plug", 0, SEC_IS_COMMON); 696 int i; 697 698 for (i = 0; i < nsyms; i++) 699 { 700 asymbol *s = bfd_alloc (abfd, sizeof (asymbol)); 701 702 BFD_ASSERT (s); 703 alocation[i] = s; 704 705 s->the_bfd = abfd; 706 s->name = syms[i].name; 707 s->value = 0; 708 s->flags = convert_flags (&syms[i]); 709 switch (syms[i].def) 710 { 711 case LDPK_COMMON: 712 s->section = &fake_common_section; 713 break; 714 case LDPK_UNDEF: 715 case LDPK_WEAKUNDEF: 716 s->section = bfd_und_section_ptr; 717 break; 718 case LDPK_DEF: 719 case LDPK_WEAKDEF: 720 if (current_plugin->has_symbol_type) 721 switch (syms[i].symbol_type) 722 { 723 default: 724 /* FIXME: Should we issue an error here ? */ 725 case LDST_UNKNOWN: 726 /* What is the best fake section for LDST_UNKNOWN? */ 727 case LDST_FUNCTION: 728 s->section = &fake_text_section; 729 break; 730 case LDST_VARIABLE: 731 if (syms[i].section_kind == LDSSK_BSS) 732 s->section = &fake_bss_section; 733 else 734 s->section = &fake_data_section; 735 break; 736 } 737 else 738 s->section = &fake_text_section; 739 break; 740 default: 741 BFD_ASSERT (0); 742 } 743 744 s->udata.p = (void *) &syms[i]; 745 } 746 747 return nsyms; 748 } 749 750 static void 751 bfd_plugin_print_symbol (bfd *abfd ATTRIBUTE_UNUSED, 752 void *afile ATTRIBUTE_UNUSED, 753 asymbol *symbol ATTRIBUTE_UNUSED, 754 bfd_print_symbol_type how ATTRIBUTE_UNUSED) 755 { 756 BFD_ASSERT (0); 757 } 758 759 static void 760 bfd_plugin_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, 761 asymbol *symbol, 762 symbol_info *ret) 763 { 764 bfd_symbol_info (symbol, ret); 765 } 766 767 /* Make an empty symbol. */ 768 769 static asymbol * 770 bfd_plugin_make_empty_symbol (bfd *abfd) 771 { 772 asymbol *new_symbol = bfd_zalloc (abfd, sizeof (asymbol)); 773 if (new_symbol == NULL) 774 return new_symbol; 775 new_symbol->the_bfd = abfd; 776 return new_symbol; 777 } 778 779 static int 780 bfd_plugin_sizeof_headers (bfd *a ATTRIBUTE_UNUSED, 781 struct bfd_link_info *info ATTRIBUTE_UNUSED) 782 { 783 BFD_ASSERT (0); 784 return 0; 785 } 786 787 const bfd_target plugin_vec = 788 { 789 "plugin", /* Name. */ 790 bfd_target_unknown_flavour, 791 BFD_ENDIAN_LITTLE, /* Target byte order. */ 792 BFD_ENDIAN_LITTLE, /* Target headers byte order. */ 793 (HAS_RELOC | EXEC_P | /* Object flags. */ 794 HAS_LINENO | HAS_DEBUG | 795 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), 796 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS 797 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ 798 0, /* symbol_leading_char. */ 799 '/', /* ar_pad_char. */ 800 15, /* ar_max_namelen. */ 801 255, /* match priority. */ 802 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */ 803 804 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 805 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 806 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ 807 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 808 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 809 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ 810 811 { /* bfd_check_format. */ 812 _bfd_dummy_target, 813 bfd_plugin_object_p, 814 bfd_generic_archive_p, 815 _bfd_dummy_target 816 }, 817 { /* bfd_set_format. */ 818 _bfd_bool_bfd_false_error, 819 _bfd_bool_bfd_false_error, 820 _bfd_generic_mkarchive, 821 _bfd_bool_bfd_false_error, 822 }, 823 { /* bfd_write_contents. */ 824 _bfd_bool_bfd_false_error, 825 _bfd_bool_bfd_false_error, 826 _bfd_write_archive_contents, 827 _bfd_bool_bfd_false_error, 828 }, 829 830 BFD_JUMP_TABLE_GENERIC (bfd_plugin), 831 BFD_JUMP_TABLE_COPY (bfd_plugin), 832 BFD_JUMP_TABLE_CORE (bfd_plugin), 833 #ifdef USE_64_BIT_ARCHIVE 834 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_64_bit), 835 #else 836 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), 837 #endif 838 BFD_JUMP_TABLE_SYMBOLS (bfd_plugin), 839 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), 840 BFD_JUMP_TABLE_WRITE (bfd_plugin), 841 BFD_JUMP_TABLE_LINK (bfd_plugin), 842 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 843 844 NULL, 845 846 NULL /* backend_data. */ 847 }; 848 #endif /* BFD_SUPPORTS_PLUGINS */ 849