1*a9fa9459Szrj /* Plugin support for BFD. 2*a9fa9459Szrj Copyright (C) 2009-2016 Free Software Foundation, Inc. 3*a9fa9459Szrj 4*a9fa9459Szrj This file is part of BFD, the Binary File Descriptor library. 5*a9fa9459Szrj 6*a9fa9459Szrj This program is free software; you can redistribute it and/or modify 7*a9fa9459Szrj it under the terms of the GNU General Public License as published by 8*a9fa9459Szrj the Free Software Foundation; either version 3 of the License, or 9*a9fa9459Szrj (at your option) any later version. 10*a9fa9459Szrj 11*a9fa9459Szrj This program is distributed in the hope that it will be useful, 12*a9fa9459Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of 13*a9fa9459Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*a9fa9459Szrj GNU General Public License for more details. 15*a9fa9459Szrj 16*a9fa9459Szrj You should have received a copy of the GNU General Public License 17*a9fa9459Szrj along with this program; if not, write to the Free Software 18*a9fa9459Szrj Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19*a9fa9459Szrj MA 02110-1301, USA. */ 20*a9fa9459Szrj 21*a9fa9459Szrj #include "sysdep.h" 22*a9fa9459Szrj #include "bfd.h" 23*a9fa9459Szrj 24*a9fa9459Szrj #if BFD_SUPPORTS_PLUGINS 25*a9fa9459Szrj 26*a9fa9459Szrj #include <assert.h> 27*a9fa9459Szrj #ifdef HAVE_DLFCN_H 28*a9fa9459Szrj #include <dlfcn.h> 29*a9fa9459Szrj #elif defined (HAVE_WINDOWS_H) 30*a9fa9459Szrj #include <windows.h> 31*a9fa9459Szrj #else 32*a9fa9459Szrj #error Unknown how to handle dynamic-load-libraries. 33*a9fa9459Szrj #endif 34*a9fa9459Szrj #include <stdarg.h> 35*a9fa9459Szrj #include "plugin-api.h" 36*a9fa9459Szrj #include "plugin.h" 37*a9fa9459Szrj #include "libbfd.h" 38*a9fa9459Szrj #include "libiberty.h" 39*a9fa9459Szrj #include <dirent.h> 40*a9fa9459Szrj 41*a9fa9459Szrj #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) 42*a9fa9459Szrj 43*a9fa9459Szrj #define RTLD_NOW 0 /* Dummy value. */ 44*a9fa9459Szrj 45*a9fa9459Szrj static void * 46*a9fa9459Szrj dlopen (const char *file, int mode ATTRIBUTE_UNUSED) 47*a9fa9459Szrj { 48*a9fa9459Szrj return LoadLibrary (file); 49*a9fa9459Szrj } 50*a9fa9459Szrj 51*a9fa9459Szrj static void * 52*a9fa9459Szrj dlsym (void *handle, const char *name) 53*a9fa9459Szrj { 54*a9fa9459Szrj return GetProcAddress (handle, name); 55*a9fa9459Szrj } 56*a9fa9459Szrj 57*a9fa9459Szrj static int ATTRIBUTE_UNUSED 58*a9fa9459Szrj dlclose (void *handle) 59*a9fa9459Szrj { 60*a9fa9459Szrj FreeLibrary (handle); 61*a9fa9459Szrj return 0; 62*a9fa9459Szrj } 63*a9fa9459Szrj 64*a9fa9459Szrj static const char * 65*a9fa9459Szrj dlerror (void) 66*a9fa9459Szrj { 67*a9fa9459Szrj return "Unable to load DLL."; 68*a9fa9459Szrj } 69*a9fa9459Szrj 70*a9fa9459Szrj #endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) */ 71*a9fa9459Szrj 72*a9fa9459Szrj #define bfd_plugin_close_and_cleanup _bfd_generic_close_and_cleanup 73*a9fa9459Szrj #define bfd_plugin_bfd_free_cached_info _bfd_generic_bfd_free_cached_info 74*a9fa9459Szrj #define bfd_plugin_new_section_hook _bfd_generic_new_section_hook 75*a9fa9459Szrj #define bfd_plugin_get_section_contents _bfd_generic_get_section_contents 76*a9fa9459Szrj #define bfd_plugin_get_section_contents_in_window _bfd_generic_get_section_contents_in_window 77*a9fa9459Szrj #define bfd_plugin_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data 78*a9fa9459Szrj #define bfd_plugin_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data 79*a9fa9459Szrj #define bfd_plugin_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data 80*a9fa9459Szrj #define bfd_plugin_bfd_set_private_flags _bfd_generic_bfd_set_private_flags 81*a9fa9459Szrj #define bfd_plugin_core_file_matches_executable_p generic_core_file_matches_executable_p 82*a9fa9459Szrj #define bfd_plugin_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name 83*a9fa9459Szrj #define bfd_plugin_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) 84*a9fa9459Szrj #define bfd_plugin_get_lineno _bfd_nosymbols_get_lineno 85*a9fa9459Szrj #define bfd_plugin_find_nearest_line _bfd_nosymbols_find_nearest_line 86*a9fa9459Szrj #define bfd_plugin_find_line _bfd_nosymbols_find_line 87*a9fa9459Szrj #define bfd_plugin_find_inliner_info _bfd_nosymbols_find_inliner_info 88*a9fa9459Szrj #define bfd_plugin_get_symbol_version_string _bfd_nosymbols_get_symbol_version_string 89*a9fa9459Szrj #define bfd_plugin_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol 90*a9fa9459Szrj #define bfd_plugin_read_minisymbols _bfd_generic_read_minisymbols 91*a9fa9459Szrj #define bfd_plugin_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol 92*a9fa9459Szrj #define bfd_plugin_set_arch_mach bfd_default_set_arch_mach 93*a9fa9459Szrj #define bfd_plugin_set_section_contents _bfd_generic_set_section_contents 94*a9fa9459Szrj #define bfd_plugin_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents 95*a9fa9459Szrj #define bfd_plugin_bfd_relax_section bfd_generic_relax_section 96*a9fa9459Szrj #define bfd_plugin_bfd_link_hash_table_create _bfd_generic_link_hash_table_create 97*a9fa9459Szrj #define bfd_plugin_bfd_link_add_symbols _bfd_generic_link_add_symbols 98*a9fa9459Szrj #define bfd_plugin_bfd_link_just_syms _bfd_generic_link_just_syms 99*a9fa9459Szrj #define bfd_plugin_bfd_final_link _bfd_generic_final_link 100*a9fa9459Szrj #define bfd_plugin_bfd_link_split_section _bfd_generic_link_split_section 101*a9fa9459Szrj #define bfd_plugin_bfd_gc_sections bfd_generic_gc_sections 102*a9fa9459Szrj #define bfd_plugin_bfd_lookup_section_flags bfd_generic_lookup_section_flags 103*a9fa9459Szrj #define bfd_plugin_bfd_merge_sections bfd_generic_merge_sections 104*a9fa9459Szrj #define bfd_plugin_bfd_is_group_section bfd_generic_is_group_section 105*a9fa9459Szrj #define bfd_plugin_bfd_discard_group bfd_generic_discard_group 106*a9fa9459Szrj #define bfd_plugin_section_already_linked _bfd_generic_section_already_linked 107*a9fa9459Szrj #define bfd_plugin_bfd_define_common_symbol bfd_generic_define_common_symbol 108*a9fa9459Szrj #define bfd_plugin_bfd_copy_link_hash_symbol_type _bfd_generic_copy_link_hash_symbol_type 109*a9fa9459Szrj #define bfd_plugin_bfd_link_check_relocs _bfd_generic_link_check_relocs 110*a9fa9459Szrj 111*a9fa9459Szrj static enum ld_plugin_status 112*a9fa9459Szrj message (int level ATTRIBUTE_UNUSED, 113*a9fa9459Szrj const char * format, ...) 114*a9fa9459Szrj { 115*a9fa9459Szrj va_list args; 116*a9fa9459Szrj va_start (args, format); 117*a9fa9459Szrj printf ("bfd plugin: "); 118*a9fa9459Szrj vprintf (format, args); 119*a9fa9459Szrj putchar ('\n'); 120*a9fa9459Szrj va_end (args); 121*a9fa9459Szrj return LDPS_OK; 122*a9fa9459Szrj } 123*a9fa9459Szrj 124*a9fa9459Szrj /* Register a claim-file handler. */ 125*a9fa9459Szrj static ld_plugin_claim_file_handler claim_file; 126*a9fa9459Szrj 127*a9fa9459Szrj static enum ld_plugin_status 128*a9fa9459Szrj register_claim_file (ld_plugin_claim_file_handler handler) 129*a9fa9459Szrj { 130*a9fa9459Szrj claim_file = handler; 131*a9fa9459Szrj return LDPS_OK; 132*a9fa9459Szrj } 133*a9fa9459Szrj 134*a9fa9459Szrj static enum ld_plugin_status 135*a9fa9459Szrj add_symbols (void * handle, 136*a9fa9459Szrj int nsyms, 137*a9fa9459Szrj const struct ld_plugin_symbol * syms) 138*a9fa9459Szrj { 139*a9fa9459Szrj bfd *abfd = handle; 140*a9fa9459Szrj struct plugin_data_struct *plugin_data = 141*a9fa9459Szrj bfd_alloc (abfd, sizeof (plugin_data_struct)); 142*a9fa9459Szrj 143*a9fa9459Szrj plugin_data->nsyms = nsyms; 144*a9fa9459Szrj plugin_data->syms = syms; 145*a9fa9459Szrj 146*a9fa9459Szrj if (nsyms != 0) 147*a9fa9459Szrj abfd->flags |= HAS_SYMS; 148*a9fa9459Szrj 149*a9fa9459Szrj abfd->tdata.plugin_data = plugin_data; 150*a9fa9459Szrj return LDPS_OK; 151*a9fa9459Szrj } 152*a9fa9459Szrj 153*a9fa9459Szrj static const char *plugin_program_name; 154*a9fa9459Szrj 155*a9fa9459Szrj void 156*a9fa9459Szrj bfd_plugin_set_program_name (const char *program_name) 157*a9fa9459Szrj { 158*a9fa9459Szrj plugin_program_name = program_name; 159*a9fa9459Szrj } 160*a9fa9459Szrj 161*a9fa9459Szrj static int 162*a9fa9459Szrj try_claim (bfd *abfd) 163*a9fa9459Szrj { 164*a9fa9459Szrj int claimed = 0; 165*a9fa9459Szrj struct ld_plugin_input_file file; 166*a9fa9459Szrj bfd *iobfd; 167*a9fa9459Szrj 168*a9fa9459Szrj file.name = abfd->filename; 169*a9fa9459Szrj 170*a9fa9459Szrj if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive)) 171*a9fa9459Szrj { 172*a9fa9459Szrj iobfd = abfd->my_archive; 173*a9fa9459Szrj file.offset = abfd->origin; 174*a9fa9459Szrj file.filesize = arelt_size (abfd); 175*a9fa9459Szrj } 176*a9fa9459Szrj else 177*a9fa9459Szrj { 178*a9fa9459Szrj iobfd = abfd; 179*a9fa9459Szrj file.offset = 0; 180*a9fa9459Szrj file.filesize = 0; 181*a9fa9459Szrj } 182*a9fa9459Szrj 183*a9fa9459Szrj if (!iobfd->iostream && !bfd_open_file (iobfd)) 184*a9fa9459Szrj return 0; 185*a9fa9459Szrj 186*a9fa9459Szrj file.fd = fileno ((FILE *) iobfd->iostream); 187*a9fa9459Szrj 188*a9fa9459Szrj if (!abfd->my_archive || bfd_is_thin_archive (abfd->my_archive)) 189*a9fa9459Szrj { 190*a9fa9459Szrj struct stat stat_buf; 191*a9fa9459Szrj if (fstat (file.fd, &stat_buf)) 192*a9fa9459Szrj return 0; 193*a9fa9459Szrj file.filesize = stat_buf.st_size; 194*a9fa9459Szrj } 195*a9fa9459Szrj 196*a9fa9459Szrj file.handle = abfd; 197*a9fa9459Szrj off_t cur_offset = lseek(file.fd, 0, SEEK_CUR); 198*a9fa9459Szrj claim_file (&file, &claimed); 199*a9fa9459Szrj lseek(file.fd, cur_offset, SEEK_SET); 200*a9fa9459Szrj if (!claimed) 201*a9fa9459Szrj return 0; 202*a9fa9459Szrj 203*a9fa9459Szrj return 1; 204*a9fa9459Szrj } 205*a9fa9459Szrj 206*a9fa9459Szrj static int 207*a9fa9459Szrj try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p) 208*a9fa9459Szrj { 209*a9fa9459Szrj void *plugin_handle; 210*a9fa9459Szrj struct ld_plugin_tv tv[4]; 211*a9fa9459Szrj int i; 212*a9fa9459Szrj ld_plugin_onload onload; 213*a9fa9459Szrj enum ld_plugin_status status; 214*a9fa9459Szrj 215*a9fa9459Szrj *has_plugin_p = 0; 216*a9fa9459Szrj 217*a9fa9459Szrj plugin_handle = dlopen (pname, RTLD_NOW); 218*a9fa9459Szrj if (!plugin_handle) 219*a9fa9459Szrj { 220*a9fa9459Szrj (*_bfd_error_handler)("%s\n", dlerror ()); 221*a9fa9459Szrj return 0; 222*a9fa9459Szrj } 223*a9fa9459Szrj 224*a9fa9459Szrj onload = dlsym (plugin_handle, "onload"); 225*a9fa9459Szrj if (!onload) 226*a9fa9459Szrj goto err; 227*a9fa9459Szrj 228*a9fa9459Szrj i = 0; 229*a9fa9459Szrj tv[i].tv_tag = LDPT_MESSAGE; 230*a9fa9459Szrj tv[i].tv_u.tv_message = message; 231*a9fa9459Szrj 232*a9fa9459Szrj ++i; 233*a9fa9459Szrj tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK; 234*a9fa9459Szrj tv[i].tv_u.tv_register_claim_file = register_claim_file; 235*a9fa9459Szrj 236*a9fa9459Szrj ++i; 237*a9fa9459Szrj tv[i].tv_tag = LDPT_ADD_SYMBOLS; 238*a9fa9459Szrj tv[i].tv_u.tv_add_symbols = add_symbols; 239*a9fa9459Szrj 240*a9fa9459Szrj ++i; 241*a9fa9459Szrj tv[i].tv_tag = LDPT_NULL; 242*a9fa9459Szrj tv[i].tv_u.tv_val = 0; 243*a9fa9459Szrj 244*a9fa9459Szrj status = (*onload)(tv); 245*a9fa9459Szrj 246*a9fa9459Szrj if (status != LDPS_OK) 247*a9fa9459Szrj goto err; 248*a9fa9459Szrj 249*a9fa9459Szrj *has_plugin_p = 1; 250*a9fa9459Szrj 251*a9fa9459Szrj abfd->plugin_format = bfd_plugin_no; 252*a9fa9459Szrj 253*a9fa9459Szrj if (!claim_file) 254*a9fa9459Szrj goto err; 255*a9fa9459Szrj 256*a9fa9459Szrj if (!try_claim (abfd)) 257*a9fa9459Szrj goto err; 258*a9fa9459Szrj 259*a9fa9459Szrj abfd->plugin_format = bfd_plugin_yes; 260*a9fa9459Szrj 261*a9fa9459Szrj return 1; 262*a9fa9459Szrj 263*a9fa9459Szrj err: 264*a9fa9459Szrj return 0; 265*a9fa9459Szrj } 266*a9fa9459Szrj 267*a9fa9459Szrj /* There may be plugin libraries in lib/bfd-plugins. */ 268*a9fa9459Szrj 269*a9fa9459Szrj static int has_plugin = -1; 270*a9fa9459Szrj 271*a9fa9459Szrj static const bfd_target *(*ld_plugin_object_p) (bfd *); 272*a9fa9459Szrj 273*a9fa9459Szrj static const char *plugin_name; 274*a9fa9459Szrj 275*a9fa9459Szrj void 276*a9fa9459Szrj bfd_plugin_set_plugin (const char *p) 277*a9fa9459Szrj { 278*a9fa9459Szrj plugin_name = p; 279*a9fa9459Szrj has_plugin = p != NULL; 280*a9fa9459Szrj } 281*a9fa9459Szrj 282*a9fa9459Szrj /* Return TRUE if a plugin library is used. */ 283*a9fa9459Szrj 284*a9fa9459Szrj bfd_boolean 285*a9fa9459Szrj bfd_plugin_specified_p (void) 286*a9fa9459Szrj { 287*a9fa9459Szrj return has_plugin > 0; 288*a9fa9459Szrj } 289*a9fa9459Szrj 290*a9fa9459Szrj /* Return TRUE if ABFD can be claimed by linker LTO plugin. */ 291*a9fa9459Szrj 292*a9fa9459Szrj bfd_boolean 293*a9fa9459Szrj bfd_link_plugin_object_p (bfd *abfd) 294*a9fa9459Szrj { 295*a9fa9459Szrj if (ld_plugin_object_p) 296*a9fa9459Szrj return ld_plugin_object_p (abfd) != NULL; 297*a9fa9459Szrj return FALSE; 298*a9fa9459Szrj } 299*a9fa9459Szrj 300*a9fa9459Szrj extern const bfd_target plugin_vec; 301*a9fa9459Szrj 302*a9fa9459Szrj /* Return TRUE if TARGET is a pointer to plugin_vec. */ 303*a9fa9459Szrj 304*a9fa9459Szrj bfd_boolean 305*a9fa9459Szrj bfd_plugin_target_p (const bfd_target *target) 306*a9fa9459Szrj { 307*a9fa9459Szrj return target == &plugin_vec; 308*a9fa9459Szrj } 309*a9fa9459Szrj 310*a9fa9459Szrj /* Register OBJECT_P to be used by bfd_plugin_object_p. */ 311*a9fa9459Szrj 312*a9fa9459Szrj void 313*a9fa9459Szrj register_ld_plugin_object_p (const bfd_target *(*object_p) (bfd *)) 314*a9fa9459Szrj { 315*a9fa9459Szrj ld_plugin_object_p = object_p; 316*a9fa9459Szrj } 317*a9fa9459Szrj 318*a9fa9459Szrj static int 319*a9fa9459Szrj load_plugin (bfd *abfd) 320*a9fa9459Szrj { 321*a9fa9459Szrj char *plugin_dir; 322*a9fa9459Szrj char *p; 323*a9fa9459Szrj DIR *d; 324*a9fa9459Szrj struct dirent *ent; 325*a9fa9459Szrj int found = 0; 326*a9fa9459Szrj 327*a9fa9459Szrj if (!has_plugin) 328*a9fa9459Szrj return found; 329*a9fa9459Szrj 330*a9fa9459Szrj if (plugin_name) 331*a9fa9459Szrj return try_load_plugin (plugin_name, abfd, &has_plugin); 332*a9fa9459Szrj 333*a9fa9459Szrj if (plugin_program_name == NULL) 334*a9fa9459Szrj return found; 335*a9fa9459Szrj 336*a9fa9459Szrj plugin_dir = concat (BINDIR, "/../lib/bfd-plugins", NULL); 337*a9fa9459Szrj p = make_relative_prefix (plugin_program_name, 338*a9fa9459Szrj BINDIR, 339*a9fa9459Szrj plugin_dir); 340*a9fa9459Szrj free (plugin_dir); 341*a9fa9459Szrj plugin_dir = NULL; 342*a9fa9459Szrj 343*a9fa9459Szrj d = opendir (p); 344*a9fa9459Szrj if (!d) 345*a9fa9459Szrj goto out; 346*a9fa9459Szrj 347*a9fa9459Szrj while ((ent = readdir (d))) 348*a9fa9459Szrj { 349*a9fa9459Szrj char *full_name; 350*a9fa9459Szrj struct stat s; 351*a9fa9459Szrj int valid_plugin; 352*a9fa9459Szrj 353*a9fa9459Szrj full_name = concat (p, "/", ent->d_name, NULL); 354*a9fa9459Szrj if (stat(full_name, &s) == 0 && S_ISREG (s.st_mode)) 355*a9fa9459Szrj found = try_load_plugin (full_name, abfd, &valid_plugin); 356*a9fa9459Szrj if (has_plugin <= 0) 357*a9fa9459Szrj has_plugin = valid_plugin; 358*a9fa9459Szrj free (full_name); 359*a9fa9459Szrj if (found) 360*a9fa9459Szrj break; 361*a9fa9459Szrj } 362*a9fa9459Szrj 363*a9fa9459Szrj out: 364*a9fa9459Szrj free (p); 365*a9fa9459Szrj if (d) 366*a9fa9459Szrj closedir (d); 367*a9fa9459Szrj 368*a9fa9459Szrj return found; 369*a9fa9459Szrj } 370*a9fa9459Szrj 371*a9fa9459Szrj 372*a9fa9459Szrj static const bfd_target * 373*a9fa9459Szrj bfd_plugin_object_p (bfd *abfd) 374*a9fa9459Szrj { 375*a9fa9459Szrj if (ld_plugin_object_p) 376*a9fa9459Szrj return ld_plugin_object_p (abfd); 377*a9fa9459Szrj 378*a9fa9459Szrj if (abfd->plugin_format == bfd_plugin_unknown && !load_plugin (abfd)) 379*a9fa9459Szrj return NULL; 380*a9fa9459Szrj 381*a9fa9459Szrj return abfd->plugin_format == bfd_plugin_yes ? abfd->xvec : NULL; 382*a9fa9459Szrj } 383*a9fa9459Szrj 384*a9fa9459Szrj /* Copy any private info we understand from the input bfd 385*a9fa9459Szrj to the output bfd. */ 386*a9fa9459Szrj 387*a9fa9459Szrj static bfd_boolean 388*a9fa9459Szrj bfd_plugin_bfd_copy_private_bfd_data (bfd *ibfd ATTRIBUTE_UNUSED, 389*a9fa9459Szrj bfd *obfd ATTRIBUTE_UNUSED) 390*a9fa9459Szrj { 391*a9fa9459Szrj BFD_ASSERT (0); 392*a9fa9459Szrj return TRUE; 393*a9fa9459Szrj } 394*a9fa9459Szrj 395*a9fa9459Szrj /* Copy any private info we understand from the input section 396*a9fa9459Szrj to the output section. */ 397*a9fa9459Szrj 398*a9fa9459Szrj static bfd_boolean 399*a9fa9459Szrj bfd_plugin_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, 400*a9fa9459Szrj asection *isection ATTRIBUTE_UNUSED, 401*a9fa9459Szrj bfd *obfd ATTRIBUTE_UNUSED, 402*a9fa9459Szrj asection *osection ATTRIBUTE_UNUSED) 403*a9fa9459Szrj { 404*a9fa9459Szrj BFD_ASSERT (0); 405*a9fa9459Szrj return TRUE; 406*a9fa9459Szrj } 407*a9fa9459Szrj 408*a9fa9459Szrj /* Copy any private info we understand from the input symbol 409*a9fa9459Szrj to the output symbol. */ 410*a9fa9459Szrj 411*a9fa9459Szrj static bfd_boolean 412*a9fa9459Szrj bfd_plugin_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED, 413*a9fa9459Szrj asymbol *isymbol ATTRIBUTE_UNUSED, 414*a9fa9459Szrj bfd *obfd ATTRIBUTE_UNUSED, 415*a9fa9459Szrj asymbol *osymbol ATTRIBUTE_UNUSED) 416*a9fa9459Szrj { 417*a9fa9459Szrj BFD_ASSERT (0); 418*a9fa9459Szrj return TRUE; 419*a9fa9459Szrj } 420*a9fa9459Szrj 421*a9fa9459Szrj static bfd_boolean 422*a9fa9459Szrj bfd_plugin_bfd_print_private_bfd_data (bfd *abfd ATTRIBUTE_UNUSED, PTR ptr ATTRIBUTE_UNUSED) 423*a9fa9459Szrj { 424*a9fa9459Szrj BFD_ASSERT (0); 425*a9fa9459Szrj return TRUE; 426*a9fa9459Szrj } 427*a9fa9459Szrj 428*a9fa9459Szrj static char * 429*a9fa9459Szrj bfd_plugin_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED) 430*a9fa9459Szrj { 431*a9fa9459Szrj BFD_ASSERT (0); 432*a9fa9459Szrj return NULL; 433*a9fa9459Szrj } 434*a9fa9459Szrj 435*a9fa9459Szrj static int 436*a9fa9459Szrj bfd_plugin_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED) 437*a9fa9459Szrj { 438*a9fa9459Szrj BFD_ASSERT (0); 439*a9fa9459Szrj return 0; 440*a9fa9459Szrj } 441*a9fa9459Szrj 442*a9fa9459Szrj static int 443*a9fa9459Szrj bfd_plugin_core_file_pid (bfd *abfd ATTRIBUTE_UNUSED) 444*a9fa9459Szrj { 445*a9fa9459Szrj BFD_ASSERT (0); 446*a9fa9459Szrj return 0; 447*a9fa9459Szrj } 448*a9fa9459Szrj 449*a9fa9459Szrj static long 450*a9fa9459Szrj bfd_plugin_get_symtab_upper_bound (bfd *abfd) 451*a9fa9459Szrj { 452*a9fa9459Szrj struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data; 453*a9fa9459Szrj long nsyms = plugin_data->nsyms; 454*a9fa9459Szrj 455*a9fa9459Szrj BFD_ASSERT (nsyms >= 0); 456*a9fa9459Szrj 457*a9fa9459Szrj return ((nsyms + 1) * sizeof (asymbol *)); 458*a9fa9459Szrj } 459*a9fa9459Szrj 460*a9fa9459Szrj static flagword 461*a9fa9459Szrj convert_flags (const struct ld_plugin_symbol *sym) 462*a9fa9459Szrj { 463*a9fa9459Szrj switch (sym->def) 464*a9fa9459Szrj { 465*a9fa9459Szrj case LDPK_DEF: 466*a9fa9459Szrj case LDPK_COMMON: 467*a9fa9459Szrj case LDPK_UNDEF: 468*a9fa9459Szrj return BSF_GLOBAL; 469*a9fa9459Szrj 470*a9fa9459Szrj case LDPK_WEAKUNDEF: 471*a9fa9459Szrj case LDPK_WEAKDEF: 472*a9fa9459Szrj return BSF_GLOBAL | BSF_WEAK; 473*a9fa9459Szrj 474*a9fa9459Szrj default: 475*a9fa9459Szrj BFD_ASSERT (0); 476*a9fa9459Szrj return 0; 477*a9fa9459Szrj } 478*a9fa9459Szrj } 479*a9fa9459Szrj 480*a9fa9459Szrj static long 481*a9fa9459Szrj bfd_plugin_canonicalize_symtab (bfd *abfd, 482*a9fa9459Szrj asymbol **alocation) 483*a9fa9459Szrj { 484*a9fa9459Szrj struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data; 485*a9fa9459Szrj long nsyms = plugin_data->nsyms; 486*a9fa9459Szrj const struct ld_plugin_symbol *syms = plugin_data->syms; 487*a9fa9459Szrj static asection fake_section; 488*a9fa9459Szrj static asection fake_common_section; 489*a9fa9459Szrj int i; 490*a9fa9459Szrj 491*a9fa9459Szrj fake_section.name = ".text"; 492*a9fa9459Szrj fake_common_section.flags = SEC_IS_COMMON; 493*a9fa9459Szrj 494*a9fa9459Szrj for (i = 0; i < nsyms; i++) 495*a9fa9459Szrj { 496*a9fa9459Szrj asymbol *s = bfd_alloc (abfd, sizeof (asymbol)); 497*a9fa9459Szrj 498*a9fa9459Szrj BFD_ASSERT (s); 499*a9fa9459Szrj alocation[i] = s; 500*a9fa9459Szrj 501*a9fa9459Szrj s->the_bfd = abfd; 502*a9fa9459Szrj s->name = syms[i].name; 503*a9fa9459Szrj s->value = 0; 504*a9fa9459Szrj s->flags = convert_flags (&syms[i]); 505*a9fa9459Szrj switch (syms[i].def) 506*a9fa9459Szrj { 507*a9fa9459Szrj case LDPK_COMMON: 508*a9fa9459Szrj s->section = &fake_common_section; 509*a9fa9459Szrj break; 510*a9fa9459Szrj case LDPK_UNDEF: 511*a9fa9459Szrj case LDPK_WEAKUNDEF: 512*a9fa9459Szrj s->section = bfd_und_section_ptr; 513*a9fa9459Szrj break; 514*a9fa9459Szrj case LDPK_DEF: 515*a9fa9459Szrj case LDPK_WEAKDEF: 516*a9fa9459Szrj s->section = &fake_section; 517*a9fa9459Szrj break; 518*a9fa9459Szrj default: 519*a9fa9459Szrj BFD_ASSERT (0); 520*a9fa9459Szrj } 521*a9fa9459Szrj 522*a9fa9459Szrj s->udata.p = (void *) &syms[i]; 523*a9fa9459Szrj } 524*a9fa9459Szrj 525*a9fa9459Szrj return nsyms; 526*a9fa9459Szrj } 527*a9fa9459Szrj 528*a9fa9459Szrj static void 529*a9fa9459Szrj bfd_plugin_print_symbol (bfd *abfd ATTRIBUTE_UNUSED, 530*a9fa9459Szrj PTR afile ATTRIBUTE_UNUSED, 531*a9fa9459Szrj asymbol *symbol ATTRIBUTE_UNUSED, 532*a9fa9459Szrj bfd_print_symbol_type how ATTRIBUTE_UNUSED) 533*a9fa9459Szrj { 534*a9fa9459Szrj BFD_ASSERT (0); 535*a9fa9459Szrj } 536*a9fa9459Szrj 537*a9fa9459Szrj static void 538*a9fa9459Szrj bfd_plugin_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, 539*a9fa9459Szrj asymbol *symbol, 540*a9fa9459Szrj symbol_info *ret) 541*a9fa9459Szrj { 542*a9fa9459Szrj bfd_symbol_info (symbol, ret); 543*a9fa9459Szrj } 544*a9fa9459Szrj 545*a9fa9459Szrj /* Make an empty symbol. */ 546*a9fa9459Szrj 547*a9fa9459Szrj static asymbol * 548*a9fa9459Szrj bfd_plugin_make_empty_symbol (bfd *abfd) 549*a9fa9459Szrj { 550*a9fa9459Szrj asymbol *new_symbol = bfd_zalloc (abfd, sizeof (asymbol)); 551*a9fa9459Szrj if (new_symbol == NULL) 552*a9fa9459Szrj return new_symbol; 553*a9fa9459Szrj new_symbol->the_bfd = abfd; 554*a9fa9459Szrj return new_symbol; 555*a9fa9459Szrj } 556*a9fa9459Szrj 557*a9fa9459Szrj static int 558*a9fa9459Szrj bfd_plugin_sizeof_headers (bfd *a ATTRIBUTE_UNUSED, 559*a9fa9459Szrj struct bfd_link_info *info ATTRIBUTE_UNUSED) 560*a9fa9459Szrj { 561*a9fa9459Szrj BFD_ASSERT (0); 562*a9fa9459Szrj return 0; 563*a9fa9459Szrj } 564*a9fa9459Szrj 565*a9fa9459Szrj const bfd_target plugin_vec = 566*a9fa9459Szrj { 567*a9fa9459Szrj "plugin", /* Name. */ 568*a9fa9459Szrj bfd_target_unknown_flavour, 569*a9fa9459Szrj BFD_ENDIAN_LITTLE, /* Target byte order. */ 570*a9fa9459Szrj BFD_ENDIAN_LITTLE, /* Target headers byte order. */ 571*a9fa9459Szrj (HAS_RELOC | EXEC_P | /* Object flags. */ 572*a9fa9459Szrj HAS_LINENO | HAS_DEBUG | 573*a9fa9459Szrj HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), 574*a9fa9459Szrj (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS 575*a9fa9459Szrj | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ 576*a9fa9459Szrj 0, /* symbol_leading_char. */ 577*a9fa9459Szrj '/', /* ar_pad_char. */ 578*a9fa9459Szrj 15, /* ar_max_namelen. */ 579*a9fa9459Szrj 255, /* match priority. */ 580*a9fa9459Szrj 581*a9fa9459Szrj bfd_getl64, bfd_getl_signed_64, bfd_putl64, 582*a9fa9459Szrj bfd_getl32, bfd_getl_signed_32, bfd_putl32, 583*a9fa9459Szrj bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ 584*a9fa9459Szrj bfd_getl64, bfd_getl_signed_64, bfd_putl64, 585*a9fa9459Szrj bfd_getl32, bfd_getl_signed_32, bfd_putl32, 586*a9fa9459Szrj bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ 587*a9fa9459Szrj 588*a9fa9459Szrj { /* bfd_check_format. */ 589*a9fa9459Szrj _bfd_dummy_target, 590*a9fa9459Szrj bfd_plugin_object_p, 591*a9fa9459Szrj bfd_generic_archive_p, 592*a9fa9459Szrj _bfd_dummy_target 593*a9fa9459Szrj }, 594*a9fa9459Szrj { /* bfd_set_format. */ 595*a9fa9459Szrj bfd_false, 596*a9fa9459Szrj bfd_false, 597*a9fa9459Szrj _bfd_generic_mkarchive, 598*a9fa9459Szrj bfd_false, 599*a9fa9459Szrj }, 600*a9fa9459Szrj { /* bfd_write_contents. */ 601*a9fa9459Szrj bfd_false, 602*a9fa9459Szrj bfd_false, 603*a9fa9459Szrj _bfd_write_archive_contents, 604*a9fa9459Szrj bfd_false, 605*a9fa9459Szrj }, 606*a9fa9459Szrj 607*a9fa9459Szrj BFD_JUMP_TABLE_GENERIC (bfd_plugin), 608*a9fa9459Szrj BFD_JUMP_TABLE_COPY (bfd_plugin), 609*a9fa9459Szrj BFD_JUMP_TABLE_CORE (bfd_plugin), 610*a9fa9459Szrj #ifdef USE_64_BIT_ARCHIVE 611*a9fa9459Szrj BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_64_bit), 612*a9fa9459Szrj #else 613*a9fa9459Szrj BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), 614*a9fa9459Szrj #endif 615*a9fa9459Szrj BFD_JUMP_TABLE_SYMBOLS (bfd_plugin), 616*a9fa9459Szrj BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), 617*a9fa9459Szrj BFD_JUMP_TABLE_WRITE (bfd_plugin), 618*a9fa9459Szrj BFD_JUMP_TABLE_LINK (bfd_plugin), 619*a9fa9459Szrj BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 620*a9fa9459Szrj 621*a9fa9459Szrj NULL, 622*a9fa9459Szrj 623*a9fa9459Szrj NULL /* backend_data. */ 624*a9fa9459Szrj }; 625*a9fa9459Szrj #endif /* BFD_SUPPORTS_PLUGIN */ 626