1 1.1 christos /* Plugin control for the GNU linker. 2 1.1.1.11 christos Copyright (C) 2010-2026 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of the GNU Binutils. 5 1.1 christos 6 1.1 christos This program is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program; if not, write to the Free Software 18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 1.1 christos MA 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos #include "sysdep.h" 22 1.1 christos #include "libiberty.h" 23 1.1 christos #include "bfd.h" 24 1.1 christos #include "bfdlink.h" 25 1.1 christos #include "bfdver.h" 26 1.1.1.7 christos #include "ctf-api.h" 27 1.1 christos #include "ld.h" 28 1.1 christos #include "ldmain.h" 29 1.1 christos #include "ldmisc.h" 30 1.1 christos #include "ldexp.h" 31 1.1 christos #include "ldlang.h" 32 1.1 christos #include "ldfile.h" 33 1.1.1.5 christos #include "plugin-api.h" 34 1.1.1.3 christos #include "../bfd/plugin.h" 35 1.1 christos #include "plugin.h" 36 1.1 christos #include "elf-bfd.h" 37 1.1.1.3 christos #if HAVE_MMAP 38 1.1.1.3 christos # include <sys/mman.h> 39 1.1.1.3 christos # ifndef MAP_FAILED 40 1.1.1.3 christos # define MAP_FAILED ((void *) -1) 41 1.1.1.3 christos # endif 42 1.1.1.3 christos # ifndef PROT_READ 43 1.1.1.3 christos # define PROT_READ 0 44 1.1.1.3 christos # endif 45 1.1.1.3 christos # ifndef MAP_PRIVATE 46 1.1.1.3 christos # define MAP_PRIVATE 0 47 1.1.1.3 christos # endif 48 1.1.1.3 christos #endif 49 1.1.1.3 christos #include <errno.h> 50 1.1.1.3 christos #if !(defined(errno) || defined(_MSC_VER) && defined(_INC_ERRNO)) 51 1.1.1.3 christos extern int errno; 52 1.1.1.3 christos #endif 53 1.1.1.9 christos #if defined (HAVE_DLFCN_H) 54 1.1.1.9 christos #include <dlfcn.h> 55 1.1.1.9 christos #elif defined (HAVE_WINDOWS_H) 56 1.1.1.2 christos #include <windows.h> 57 1.1 christos #endif 58 1.1 christos 59 1.1 christos /* Report plugin symbols. */ 60 1.1.1.8 christos bool report_plugin_symbols; 61 1.1 christos 62 1.1 christos /* The suffix to append to the name of the real (claimed) object file 63 1.1 christos when generating a dummy BFD to hold the IR symbols sent from the 64 1.1 christos plugin. For cosmetic use only; appears in maps, crefs etc. */ 65 1.1 christos #define IRONLY_SUFFIX " (symbol from plugin)" 66 1.1 christos 67 1.1 christos /* Stores a single argument passed to a plugin. */ 68 1.1 christos typedef struct plugin_arg 69 1.1 christos { 70 1.1 christos struct plugin_arg *next; 71 1.1 christos const char *arg; 72 1.1 christos } plugin_arg_t; 73 1.1 christos 74 1.1 christos /* Holds all details of a single plugin. */ 75 1.1 christos typedef struct plugin 76 1.1 christos { 77 1.1 christos /* Next on the list of plugins, or NULL at end of chain. */ 78 1.1 christos struct plugin *next; 79 1.1 christos /* The argument string given to --plugin. */ 80 1.1 christos const char *name; 81 1.1 christos /* The shared library handle returned by dlopen. */ 82 1.1 christos void *dlhandle; 83 1.1 christos /* The list of argument string given to --plugin-opt. */ 84 1.1 christos plugin_arg_t *args; 85 1.1 christos /* Number of args in the list, for convenience. */ 86 1.1 christos size_t n_args; 87 1.1 christos /* The plugin's event handlers. */ 88 1.1 christos ld_plugin_claim_file_handler claim_file_handler; 89 1.1.1.9 christos ld_plugin_claim_file_handler_v2 claim_file_handler_v2; 90 1.1 christos ld_plugin_all_symbols_read_handler all_symbols_read_handler; 91 1.1 christos ld_plugin_cleanup_handler cleanup_handler; 92 1.1 christos /* TRUE if the cleanup handlers have been called. */ 93 1.1.1.8 christos bool cleanup_done; 94 1.1 christos } plugin_t; 95 1.1 christos 96 1.1.1.3 christos typedef struct view_buffer 97 1.1.1.3 christos { 98 1.1.1.3 christos char *addr; 99 1.1.1.3 christos size_t filesize; 100 1.1.1.3 christos off_t offset; 101 1.1.1.3 christos } view_buffer_t; 102 1.1.1.3 christos 103 1.1.1.3 christos /* The internal version of struct ld_plugin_input_file with a BFD 104 1.1.1.3 christos pointer. */ 105 1.1.1.3 christos typedef struct plugin_input_file 106 1.1.1.3 christos { 107 1.1.1.8 christos /* The dummy BFD. */ 108 1.1.1.3 christos bfd *abfd; 109 1.1.1.8 christos /* The original input BFD. Non-NULL if it is an archive member. */ 110 1.1.1.8 christos bfd *ibfd; 111 1.1.1.3 christos view_buffer_t view_buffer; 112 1.1.1.3 christos char *name; 113 1.1.1.3 christos int fd; 114 1.1.1.8 christos bool use_mmap; 115 1.1.1.3 christos off_t offset; 116 1.1.1.3 christos off_t filesize; 117 1.1.1.3 christos } plugin_input_file_t; 118 1.1.1.3 christos 119 1.1 christos /* The master list of all plugins. */ 120 1.1 christos static plugin_t *plugins_list = NULL; 121 1.1 christos 122 1.1 christos /* We keep a tail pointer for easy linking on the end. */ 123 1.1 christos static plugin_t **plugins_tail_chain_ptr = &plugins_list; 124 1.1 christos 125 1.1 christos /* The last plugin added to the list, for receiving args. */ 126 1.1 christos static plugin_t *last_plugin = NULL; 127 1.1 christos 128 1.1 christos /* The tail of the arg chain of the last plugin added to the list. */ 129 1.1 christos static plugin_arg_t **last_plugin_args_tail_chain_ptr = NULL; 130 1.1 christos 131 1.1 christos /* The plugin which is currently having a callback executed. */ 132 1.1 christos static plugin_t *called_plugin = NULL; 133 1.1 christos 134 1.1 christos /* Last plugin to cause an error, if any. */ 135 1.1 christos static const char *error_plugin = NULL; 136 1.1 christos 137 1.1 christos /* State of linker "notice" interface before we poked at it. */ 138 1.1.1.8 christos static bool orig_notice_all; 139 1.1 christos 140 1.1 christos /* Original linker callbacks, and the plugin version. */ 141 1.1 christos static const struct bfd_link_callbacks *orig_callbacks; 142 1.1 christos static struct bfd_link_callbacks plugin_callbacks; 143 1.1 christos 144 1.1 christos /* Set at all symbols read time, to avoid recursively offering the plugin 145 1.1 christos its own newly-added input files and libs to claim. */ 146 1.1.1.8 christos bool no_more_claiming = false; 147 1.1 christos 148 1.1.1.3 christos #if HAVE_MMAP && HAVE_GETPAGESIZE 149 1.1.1.3 christos /* Page size used by mmap. */ 150 1.1.1.3 christos static off_t plugin_pagesize; 151 1.1.1.3 christos #endif 152 1.1.1.3 christos 153 1.1 christos /* List of tags to set in the constant leading part of the tv array. */ 154 1.1 christos static const enum ld_plugin_tag tv_header_tags[] = 155 1.1 christos { 156 1.1 christos LDPT_MESSAGE, 157 1.1 christos LDPT_API_VERSION, 158 1.1 christos LDPT_GNU_LD_VERSION, 159 1.1 christos LDPT_LINKER_OUTPUT, 160 1.1 christos LDPT_OUTPUT_NAME, 161 1.1 christos LDPT_REGISTER_CLAIM_FILE_HOOK, 162 1.1.1.9 christos LDPT_REGISTER_CLAIM_FILE_HOOK_V2, 163 1.1 christos LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK, 164 1.1 christos LDPT_REGISTER_CLEANUP_HOOK, 165 1.1 christos LDPT_ADD_SYMBOLS, 166 1.1 christos LDPT_GET_INPUT_FILE, 167 1.1.1.3 christos LDPT_GET_VIEW, 168 1.1 christos LDPT_RELEASE_INPUT_FILE, 169 1.1 christos LDPT_GET_SYMBOLS, 170 1.1.1.2 christos LDPT_GET_SYMBOLS_V2, 171 1.1 christos LDPT_ADD_INPUT_FILE, 172 1.1 christos LDPT_ADD_INPUT_LIBRARY, 173 1.1 christos LDPT_SET_EXTRA_LIBRARY_PATH 174 1.1 christos }; 175 1.1 christos 176 1.1 christos /* How many entries in the constant leading part of the tv array. */ 177 1.1 christos static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags); 178 1.1 christos 179 1.1 christos /* Forward references. */ 180 1.1.1.8 christos static bool plugin_notice (struct bfd_link_info *, 181 1.1.1.8 christos struct bfd_link_hash_entry *, 182 1.1.1.8 christos struct bfd_link_hash_entry *, 183 1.1.1.8 christos bfd *, asection *, bfd_vma, flagword); 184 1.1.1.3 christos 185 1.1.1.9 christos static bfd_cleanup plugin_object_p (bfd *, bool); 186 1.1 christos 187 1.1 christos #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) 188 1.1 christos 189 1.1 christos #define RTLD_NOW 0 /* Dummy value. */ 190 1.1 christos 191 1.1 christos static void * 192 1.1 christos dlopen (const char *file, int mode ATTRIBUTE_UNUSED) 193 1.1 christos { 194 1.1 christos return LoadLibrary (file); 195 1.1 christos } 196 1.1 christos 197 1.1 christos static void * 198 1.1 christos dlsym (void *handle, const char *name) 199 1.1 christos { 200 1.1 christos return GetProcAddress (handle, name); 201 1.1 christos } 202 1.1 christos 203 1.1 christos static int 204 1.1 christos dlclose (void *handle) 205 1.1 christos { 206 1.1 christos FreeLibrary (handle); 207 1.1 christos return 0; 208 1.1 christos } 209 1.1 christos 210 1.1 christos #endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) */ 211 1.1 christos 212 1.1.1.2 christos #ifndef HAVE_DLFCN_H 213 1.1.1.2 christos static const char * 214 1.1.1.2 christos dlerror (void) 215 1.1.1.2 christos { 216 1.1.1.2 christos return ""; 217 1.1.1.2 christos } 218 1.1.1.2 christos #endif 219 1.1.1.2 christos 220 1.1 christos /* Helper function for exiting with error status. */ 221 1.1 christos static int 222 1.1 christos set_plugin_error (const char *plugin) 223 1.1 christos { 224 1.1 christos error_plugin = plugin; 225 1.1 christos return -1; 226 1.1 christos } 227 1.1 christos 228 1.1 christos /* Test if an error occurred. */ 229 1.1.1.8 christos static bool 230 1.1 christos plugin_error_p (void) 231 1.1 christos { 232 1.1 christos return error_plugin != NULL; 233 1.1 christos } 234 1.1 christos 235 1.1 christos /* Return name of plugin which caused an error if any. */ 236 1.1 christos const char * 237 1.1 christos plugin_error_plugin (void) 238 1.1 christos { 239 1.1 christos return error_plugin ? error_plugin : _("<no plugin>"); 240 1.1 christos } 241 1.1 christos 242 1.1 christos /* Handle -plugin arg: find and load plugin, or return error. */ 243 1.1.1.2 christos void 244 1.1 christos plugin_opt_plugin (const char *plugin) 245 1.1 christos { 246 1.1 christos plugin_t *newplug; 247 1.1.1.5 christos plugin_t *curplug = plugins_list; 248 1.1 christos 249 1.1 christos newplug = xmalloc (sizeof *newplug); 250 1.1 christos memset (newplug, 0, sizeof *newplug); 251 1.1 christos newplug->name = plugin; 252 1.1 christos newplug->dlhandle = dlopen (plugin, RTLD_NOW); 253 1.1 christos if (!newplug->dlhandle) 254 1.1.1.10 christos fatal (_("%P: %s: error loading plugin: %s\n"), plugin, dlerror ()); 255 1.1 christos 256 1.1.1.5 christos /* Check if plugin has been loaded already. */ 257 1.1.1.5 christos while (curplug) 258 1.1.1.5 christos { 259 1.1.1.5 christos if (newplug->dlhandle == curplug->dlhandle) 260 1.1.1.5 christos { 261 1.1.1.5 christos einfo (_("%P: %s: duplicated plugin\n"), plugin); 262 1.1.1.5 christos free (newplug); 263 1.1.1.5 christos return; 264 1.1.1.5 christos } 265 1.1.1.5 christos curplug = curplug->next; 266 1.1.1.5 christos } 267 1.1.1.5 christos 268 1.1 christos /* Chain on end, so when we run list it is in command-line order. */ 269 1.1 christos *plugins_tail_chain_ptr = newplug; 270 1.1 christos plugins_tail_chain_ptr = &newplug->next; 271 1.1 christos 272 1.1 christos /* Record it as current plugin for receiving args. */ 273 1.1 christos last_plugin = newplug; 274 1.1 christos last_plugin_args_tail_chain_ptr = &newplug->args; 275 1.1 christos } 276 1.1 christos 277 1.1 christos /* Accumulate option arguments for last-loaded plugin, or return 278 1.1 christos error if none. */ 279 1.1 christos int 280 1.1 christos plugin_opt_plugin_arg (const char *arg) 281 1.1 christos { 282 1.1 christos plugin_arg_t *newarg; 283 1.1 christos 284 1.1 christos if (!last_plugin) 285 1.1 christos return set_plugin_error (_("<no plugin>")); 286 1.1 christos 287 1.1.1.3 christos /* Ignore -pass-through= from GCC driver. */ 288 1.1.1.3 christos if (*arg == '-') 289 1.1.1.3 christos { 290 1.1.1.3 christos const char *p = arg + 1; 291 1.1.1.3 christos 292 1.1.1.3 christos if (*p == '-') 293 1.1.1.3 christos ++p; 294 1.1.1.3 christos if (strncmp (p, "pass-through=", 13) == 0) 295 1.1.1.3 christos return 0; 296 1.1.1.3 christos } 297 1.1.1.3 christos 298 1.1 christos newarg = xmalloc (sizeof *newarg); 299 1.1 christos newarg->arg = arg; 300 1.1 christos newarg->next = NULL; 301 1.1 christos 302 1.1 christos /* Chain on end to preserve command-line order. */ 303 1.1 christos *last_plugin_args_tail_chain_ptr = newarg; 304 1.1 christos last_plugin_args_tail_chain_ptr = &newarg->next; 305 1.1 christos last_plugin->n_args++; 306 1.1 christos return 0; 307 1.1 christos } 308 1.1 christos 309 1.1.1.3 christos /* Generate a dummy BFD to represent an IR file, for any callers of 310 1.1.1.3 christos plugin_call_claim_file to use as the handle in the ld_plugin_input_file 311 1.1.1.3 christos struct that they build to pass in. The BFD is initially writable, so 312 1.1.1.3 christos that symbols can be added to it; it must be made readable after the 313 1.1.1.3 christos add_symbols hook has been called so that it can be read when linking. */ 314 1.1.1.3 christos static bfd * 315 1.1 christos plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate) 316 1.1 christos { 317 1.1.1.10 christos bool bfd_plugin_target = bfd_plugin_target_p (srctemplate->xvec); 318 1.1.1.10 christos char *filename = concat (name, IRONLY_SUFFIX, (const char *) NULL); 319 1.1.1.10 christos bfd *abfd = bfd_create (filename, (bfd_plugin_target 320 1.1.1.10 christos ? link_info.output_bfd : srctemplate)); 321 1.1.1.10 christos free (filename); 322 1.1 christos if (abfd != NULL) 323 1.1 christos { 324 1.1 christos abfd->flags |= BFD_LINKER_CREATED | BFD_PLUGIN; 325 1.1.1.3 christos if (!bfd_make_writable (abfd)) 326 1.1.1.3 christos goto report_error; 327 1.1.1.3 christos if (!bfd_plugin_target) 328 1.1.1.3 christos { 329 1.1.1.3 christos bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate)); 330 1.1.1.3 christos bfd_set_gp_size (abfd, bfd_get_gp_size (srctemplate)); 331 1.1.1.3 christos if (!bfd_copy_private_bfd_data (srctemplate, abfd)) 332 1.1.1.3 christos goto report_error; 333 1.1.1.3 christos } 334 1.1 christos { 335 1.1 christos flagword flags; 336 1.1 christos 337 1.1.1.2 christos /* Create section to own the symbols. */ 338 1.1 christos flags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY 339 1.1 christos | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE); 340 1.1 christos if (bfd_make_section_anyway_with_flags (abfd, ".text", flags)) 341 1.1 christos return abfd; 342 1.1 christos } 343 1.1 christos } 344 1.1.1.8 christos report_error: 345 1.1.1.10 christos fatal (_("%P: could not create dummy IR bfd: %E\n")); 346 1.1 christos return NULL; 347 1.1 christos } 348 1.1 christos 349 1.1 christos /* Check if the BFD passed in is an IR dummy object file. */ 350 1.1.1.8 christos static inline bool 351 1.1 christos is_ir_dummy_bfd (const bfd *abfd) 352 1.1 christos { 353 1.1 christos /* ABFD can sometimes legitimately be NULL, e.g. when called from one 354 1.1.1.3 christos of the linker callbacks for a symbol in the *ABS* or *UND* sections. */ 355 1.1.1.3 christos return abfd != NULL && (abfd->flags & BFD_PLUGIN) != 0; 356 1.1 christos } 357 1.1 christos 358 1.1 christos /* Helpers to convert between BFD and GOLD symbol formats. */ 359 1.1 christos static enum ld_plugin_status 360 1.1 christos asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym, 361 1.1 christos const struct ld_plugin_symbol *ldsym) 362 1.1 christos { 363 1.1 christos flagword flags = BSF_NO_FLAGS; 364 1.1 christos struct bfd_section *section; 365 1.1 christos 366 1.1 christos asym->the_bfd = abfd; 367 1.1 christos asym->name = (ldsym->version 368 1.1.1.10 christos ? stat_concat (ldsym->name, "@", ldsym->version, 369 1.1.1.10 christos (const char *) NULL) 370 1.1 christos : ldsym->name); 371 1.1 christos asym->value = 0; 372 1.1 christos switch (ldsym->def) 373 1.1 christos { 374 1.1 christos case LDPK_WEAKDEF: 375 1.1 christos flags = BSF_WEAK; 376 1.1 christos /* FALLTHRU */ 377 1.1 christos case LDPK_DEF: 378 1.1 christos flags |= BSF_GLOBAL; 379 1.1.1.2 christos if (ldsym->comdat_key) 380 1.1.1.2 christos { 381 1.1.1.10 christos char *name = stat_concat (".gnu.linkonce.t.", ldsym->comdat_key, 382 1.1.1.10 christos (const char *) NULL); 383 1.1.1.2 christos section = bfd_get_section_by_name (abfd, name); 384 1.1.1.2 christos if (section != NULL) 385 1.1.1.10 christos stat_free (name); 386 1.1.1.2 christos else 387 1.1.1.2 christos { 388 1.1.1.2 christos flagword sflags; 389 1.1.1.2 christos 390 1.1.1.2 christos sflags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY 391 1.1.1.2 christos | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE 392 1.1.1.2 christos | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD); 393 1.1.1.2 christos section = bfd_make_section_anyway_with_flags (abfd, name, sflags); 394 1.1.1.2 christos if (section == NULL) 395 1.1.1.2 christos return LDPS_ERR; 396 1.1.1.2 christos } 397 1.1.1.2 christos } 398 1.1.1.2 christos else 399 1.1.1.2 christos section = bfd_get_section_by_name (abfd, ".text"); 400 1.1 christos break; 401 1.1 christos 402 1.1 christos case LDPK_WEAKUNDEF: 403 1.1 christos flags = BSF_WEAK; 404 1.1 christos /* FALLTHRU */ 405 1.1 christos case LDPK_UNDEF: 406 1.1 christos section = bfd_und_section_ptr; 407 1.1 christos break; 408 1.1 christos 409 1.1 christos case LDPK_COMMON: 410 1.1 christos flags = BSF_GLOBAL; 411 1.1 christos section = bfd_com_section_ptr; 412 1.1 christos asym->value = ldsym->size; 413 1.1 christos break; 414 1.1 christos 415 1.1 christos default: 416 1.1 christos return LDPS_ERR; 417 1.1 christos } 418 1.1 christos asym->flags = flags; 419 1.1 christos asym->section = section; 420 1.1 christos 421 1.1 christos if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) 422 1.1 christos { 423 1.1.1.8 christos elf_symbol_type *elfsym = elf_symbol_from (asym); 424 1.1 christos unsigned char visibility; 425 1.1 christos 426 1.1 christos if (!elfsym) 427 1.1.1.10 christos fatal (_("%P: %s: non-ELF symbol in ELF BFD!\n"), asym->name); 428 1.1.1.7 christos 429 1.1.1.7 christos if (ldsym->def == LDPK_COMMON) 430 1.1.1.7 christos { 431 1.1.1.7 christos elfsym->internal_elf_sym.st_shndx = SHN_COMMON; 432 1.1.1.7 christos elfsym->internal_elf_sym.st_value = 1; 433 1.1.1.7 christos } 434 1.1.1.7 christos 435 1.1 christos switch (ldsym->visibility) 436 1.1 christos { 437 1.1 christos default: 438 1.1.1.10 christos fatal (_("%P: unknown ELF symbol visibility: %d!\n"), 439 1.1 christos ldsym->visibility); 440 1.1.1.5 christos return LDPS_ERR; 441 1.1.1.5 christos 442 1.1 christos case LDPV_DEFAULT: 443 1.1 christos visibility = STV_DEFAULT; 444 1.1 christos break; 445 1.1 christos case LDPV_PROTECTED: 446 1.1 christos visibility = STV_PROTECTED; 447 1.1 christos break; 448 1.1 christos case LDPV_INTERNAL: 449 1.1 christos visibility = STV_INTERNAL; 450 1.1 christos break; 451 1.1 christos case LDPV_HIDDEN: 452 1.1 christos visibility = STV_HIDDEN; 453 1.1 christos break; 454 1.1 christos } 455 1.1.1.7 christos elfsym->internal_elf_sym.st_other |= visibility; 456 1.1 christos } 457 1.1 christos 458 1.1 christos return LDPS_OK; 459 1.1 christos } 460 1.1 christos 461 1.1 christos /* Register a claim-file handler. */ 462 1.1 christos static enum ld_plugin_status 463 1.1 christos register_claim_file (ld_plugin_claim_file_handler handler) 464 1.1 christos { 465 1.1 christos ASSERT (called_plugin); 466 1.1 christos called_plugin->claim_file_handler = handler; 467 1.1 christos return LDPS_OK; 468 1.1 christos } 469 1.1 christos 470 1.1.1.9 christos /* Register a claim-file version 2 handler. */ 471 1.1.1.9 christos static enum ld_plugin_status 472 1.1.1.9 christos register_claim_file_v2 (ld_plugin_claim_file_handler_v2 handler) 473 1.1.1.9 christos { 474 1.1.1.9 christos ASSERT (called_plugin); 475 1.1.1.9 christos called_plugin->claim_file_handler_v2 = handler; 476 1.1.1.9 christos return LDPS_OK; 477 1.1.1.9 christos } 478 1.1.1.9 christos 479 1.1 christos /* Register an all-symbols-read handler. */ 480 1.1 christos static enum ld_plugin_status 481 1.1 christos register_all_symbols_read (ld_plugin_all_symbols_read_handler handler) 482 1.1 christos { 483 1.1 christos ASSERT (called_plugin); 484 1.1 christos called_plugin->all_symbols_read_handler = handler; 485 1.1 christos return LDPS_OK; 486 1.1 christos } 487 1.1 christos 488 1.1 christos /* Register a cleanup handler. */ 489 1.1 christos static enum ld_plugin_status 490 1.1 christos register_cleanup (ld_plugin_cleanup_handler handler) 491 1.1 christos { 492 1.1 christos ASSERT (called_plugin); 493 1.1 christos called_plugin->cleanup_handler = handler; 494 1.1 christos return LDPS_OK; 495 1.1 christos } 496 1.1 christos 497 1.1 christos /* Add symbols from a plugin-claimed input file. */ 498 1.1 christos static enum ld_plugin_status 499 1.1 christos add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms) 500 1.1 christos { 501 1.1 christos asymbol **symptrs; 502 1.1.1.3 christos plugin_input_file_t *input = handle; 503 1.1.1.3 christos bfd *abfd = input->abfd; 504 1.1 christos int n; 505 1.1.1.2 christos 506 1.1 christos ASSERT (called_plugin); 507 1.1.1.10 christos symptrs = bfd_alloc (abfd, nsyms * sizeof *symptrs); 508 1.1.1.10 christos if (symptrs == NULL) 509 1.1.1.10 christos return LDPS_ERR; 510 1.1 christos for (n = 0; n < nsyms; n++) 511 1.1 christos { 512 1.1 christos enum ld_plugin_status rv; 513 1.1.1.2 christos asymbol *bfdsym; 514 1.1.1.2 christos 515 1.1.1.2 christos bfdsym = bfd_make_empty_symbol (abfd); 516 1.1 christos symptrs[n] = bfdsym; 517 1.1.1.10 christos if (bfdsym == NULL) 518 1.1.1.10 christos return LDPS_ERR; 519 1.1 christos rv = asymbol_from_plugin_symbol (abfd, bfdsym, syms + n); 520 1.1 christos if (rv != LDPS_OK) 521 1.1 christos return rv; 522 1.1 christos } 523 1.1 christos bfd_set_symtab (abfd, symptrs, nsyms); 524 1.1 christos return LDPS_OK; 525 1.1 christos } 526 1.1 christos 527 1.1 christos /* Get the input file information with an open (possibly re-opened) 528 1.1 christos file descriptor. */ 529 1.1 christos static enum ld_plugin_status 530 1.1 christos get_input_file (const void *handle, struct ld_plugin_input_file *file) 531 1.1 christos { 532 1.1.1.3 christos const plugin_input_file_t *input = handle; 533 1.1.1.3 christos 534 1.1 christos ASSERT (called_plugin); 535 1.1.1.3 christos 536 1.1.1.3 christos file->name = input->name; 537 1.1.1.3 christos file->offset = input->offset; 538 1.1.1.3 christos file->filesize = input->filesize; 539 1.1.1.3 christos file->handle = (void *) handle; 540 1.1.1.3 christos 541 1.1.1.3 christos return LDPS_OK; 542 1.1.1.3 christos } 543 1.1.1.3 christos 544 1.1.1.3 christos /* Get view of the input file. */ 545 1.1.1.3 christos static enum ld_plugin_status 546 1.1.1.3 christos get_view (const void *handle, const void **viewp) 547 1.1.1.3 christos { 548 1.1.1.3 christos plugin_input_file_t *input = (plugin_input_file_t *) handle; 549 1.1.1.3 christos char *buffer; 550 1.1.1.3 christos size_t size = input->filesize; 551 1.1.1.3 christos off_t offset = input->offset; 552 1.1.1.3 christos #if HAVE_MMAP && HAVE_GETPAGESIZE 553 1.1.1.3 christos off_t bias; 554 1.1.1.3 christos #endif 555 1.1.1.3 christos 556 1.1.1.3 christos ASSERT (called_plugin); 557 1.1.1.3 christos 558 1.1.1.3 christos /* FIXME: einfo should support %lld. */ 559 1.1.1.3 christos if ((off_t) size != input->filesize) 560 1.1.1.10 christos fatal (_("%P: unsupported input file size: %s (%ld bytes)\n"), 561 1.1.1.3 christos input->name, (long) input->filesize); 562 1.1.1.3 christos 563 1.1.1.3 christos /* Check the cached view buffer. */ 564 1.1.1.3 christos if (input->view_buffer.addr != NULL 565 1.1.1.3 christos && input->view_buffer.filesize == size 566 1.1.1.3 christos && input->view_buffer.offset == offset) 567 1.1.1.3 christos { 568 1.1.1.3 christos *viewp = input->view_buffer.addr; 569 1.1.1.3 christos return LDPS_OK; 570 1.1.1.3 christos } 571 1.1.1.3 christos 572 1.1.1.3 christos input->view_buffer.filesize = size; 573 1.1.1.3 christos input->view_buffer.offset = offset; 574 1.1.1.3 christos 575 1.1.1.3 christos #if HAVE_MMAP 576 1.1.1.3 christos # if HAVE_GETPAGESIZE 577 1.1.1.3 christos bias = offset % plugin_pagesize; 578 1.1.1.3 christos offset -= bias; 579 1.1.1.3 christos size += bias; 580 1.1.1.3 christos # endif 581 1.1.1.3 christos buffer = mmap (NULL, size, PROT_READ, MAP_PRIVATE, input->fd, offset); 582 1.1.1.3 christos if (buffer != MAP_FAILED) 583 1.1.1.3 christos { 584 1.1.1.8 christos input->use_mmap = true; 585 1.1.1.3 christos # if HAVE_GETPAGESIZE 586 1.1.1.3 christos buffer += bias; 587 1.1.1.3 christos # endif 588 1.1.1.3 christos } 589 1.1.1.3 christos else 590 1.1.1.3 christos #endif 591 1.1.1.3 christos { 592 1.1.1.3 christos char *p; 593 1.1.1.3 christos 594 1.1.1.8 christos input->use_mmap = false; 595 1.1.1.3 christos 596 1.1.1.3 christos if (lseek (input->fd, offset, SEEK_SET) < 0) 597 1.1.1.3 christos return LDPS_ERR; 598 1.1.1.3 christos 599 1.1.1.3 christos buffer = bfd_alloc (input->abfd, size); 600 1.1.1.3 christos if (buffer == NULL) 601 1.1.1.3 christos return LDPS_ERR; 602 1.1.1.3 christos 603 1.1.1.3 christos p = buffer; 604 1.1.1.3 christos do 605 1.1.1.3 christos { 606 1.1.1.3 christos ssize_t got = read (input->fd, p, size); 607 1.1.1.3 christos if (got == 0) 608 1.1.1.3 christos break; 609 1.1.1.3 christos else if (got > 0) 610 1.1.1.3 christos { 611 1.1.1.3 christos p += got; 612 1.1.1.3 christos size -= got; 613 1.1.1.3 christos } 614 1.1.1.3 christos else if (errno != EINTR) 615 1.1.1.3 christos return LDPS_ERR; 616 1.1.1.3 christos } 617 1.1.1.3 christos while (size > 0); 618 1.1.1.3 christos } 619 1.1.1.3 christos 620 1.1.1.3 christos input->view_buffer.addr = buffer; 621 1.1.1.3 christos *viewp = buffer; 622 1.1.1.3 christos 623 1.1.1.3 christos return LDPS_OK; 624 1.1 christos } 625 1.1 christos 626 1.1.1.8 christos /* Release plugin file descriptor. */ 627 1.1.1.8 christos 628 1.1.1.8 christos static void 629 1.1.1.8 christos release_plugin_file_descriptor (plugin_input_file_t *input) 630 1.1.1.8 christos { 631 1.1.1.8 christos if (input->fd != -1) 632 1.1.1.8 christos { 633 1.1.1.8 christos bfd_plugin_close_file_descriptor (input->ibfd, input->fd); 634 1.1.1.8 christos input->fd = -1; 635 1.1.1.8 christos } 636 1.1.1.8 christos } 637 1.1.1.8 christos 638 1.1 christos /* Release the input file. */ 639 1.1 christos static enum ld_plugin_status 640 1.1 christos release_input_file (const void *handle) 641 1.1 christos { 642 1.1.1.3 christos plugin_input_file_t *input = (plugin_input_file_t *) handle; 643 1.1 christos ASSERT (called_plugin); 644 1.1.1.8 christos release_plugin_file_descriptor (input); 645 1.1.1.3 christos return LDPS_OK; 646 1.1 christos } 647 1.1 christos 648 1.1 christos /* Return TRUE if a defined symbol might be reachable from outside the 649 1.1 christos universe of claimed objects. */ 650 1.1.1.8 christos static inline bool 651 1.1.1.2 christos is_visible_from_outside (struct ld_plugin_symbol *lsym, 652 1.1 christos struct bfd_link_hash_entry *blhe) 653 1.1 christos { 654 1.1.1.3 christos if (bfd_link_relocatable (&link_info)) 655 1.1.1.8 christos return true; 656 1.1.1.5 christos if (blhe->non_ir_ref_dynamic 657 1.1.1.5 christos || link_info.export_dynamic 658 1.1.1.5 christos || bfd_link_dll (&link_info)) 659 1.1 christos { 660 1.1.1.2 christos /* Check if symbol is hidden by version script. */ 661 1.1.1.2 christos if (bfd_hide_sym_by_version (link_info.version_info, 662 1.1.1.2 christos blhe->root.string)) 663 1.1.1.8 christos return false; 664 1.1 christos /* Only ELF symbols really have visibility. */ 665 1.1.1.8 christos if (is_elf_hash_table (link_info.hash)) 666 1.1 christos { 667 1.1 christos struct elf_link_hash_entry *el = (struct elf_link_hash_entry *)blhe; 668 1.1 christos int vis = ELF_ST_VISIBILITY (el->other); 669 1.1 christos return vis == STV_DEFAULT || vis == STV_PROTECTED; 670 1.1 christos } 671 1.1 christos /* On non-ELF targets, we can safely make inferences by considering 672 1.1 christos what visibility the plugin would have liked to apply when it first 673 1.1 christos sent us the symbol. During ELF symbol processing, visibility only 674 1.1 christos ever becomes more restrictive, not less, when symbols are merged, 675 1.1 christos so this is a conservative estimate; it may give false positives, 676 1.1 christos declaring something visible from outside when it in fact would 677 1.1 christos not have been, but this will only lead to missed optimisation 678 1.1 christos opportunities during LTRANS at worst; it will not give false 679 1.1 christos negatives, which can lead to the disastrous conclusion that the 680 1.1 christos related symbol is IRONLY. (See GCC PR46319 for an example.) */ 681 1.1 christos return (lsym->visibility == LDPV_DEFAULT 682 1.1 christos || lsym->visibility == LDPV_PROTECTED); 683 1.1 christos } 684 1.1 christos 685 1.1.1.8 christos return false; 686 1.1 christos } 687 1.1 christos 688 1.1.1.7 christos /* Return LTO kind string name that corresponds to IDX enum value. */ 689 1.1.1.7 christos static const char * 690 1.1.1.7 christos get_lto_kind (unsigned int idx) 691 1.1.1.7 christos { 692 1.1.1.7 christos static char buffer[64]; 693 1.1.1.7 christos const char *lto_kind_str[5] = 694 1.1.1.7 christos { 695 1.1.1.7 christos "DEF", 696 1.1.1.7 christos "WEAKDEF", 697 1.1.1.7 christos "UNDEF", 698 1.1.1.7 christos "WEAKUNDEF", 699 1.1.1.7 christos "COMMON" 700 1.1.1.7 christos }; 701 1.1.1.7 christos 702 1.1.1.7 christos if (idx < ARRAY_SIZE (lto_kind_str)) 703 1.1.1.7 christos return lto_kind_str [idx]; 704 1.1.1.7 christos 705 1.1.1.7 christos sprintf (buffer, _("unknown LTO kind value %x"), idx); 706 1.1.1.7 christos return buffer; 707 1.1.1.7 christos } 708 1.1.1.7 christos 709 1.1.1.7 christos /* Return LTO resolution string name that corresponds to IDX enum value. */ 710 1.1.1.7 christos static const char * 711 1.1.1.7 christos get_lto_resolution (unsigned int idx) 712 1.1.1.7 christos { 713 1.1.1.7 christos static char buffer[64]; 714 1.1.1.7 christos static const char *lto_resolution_str[10] = 715 1.1.1.7 christos { 716 1.1.1.7 christos "UNKNOWN", 717 1.1.1.7 christos "UNDEF", 718 1.1.1.7 christos "PREVAILING_DEF", 719 1.1.1.7 christos "PREVAILING_DEF_IRONLY", 720 1.1.1.7 christos "PREEMPTED_REG", 721 1.1.1.7 christos "PREEMPTED_IR", 722 1.1.1.7 christos "RESOLVED_IR", 723 1.1.1.7 christos "RESOLVED_EXEC", 724 1.1.1.7 christos "RESOLVED_DYN", 725 1.1.1.7 christos "PREVAILING_DEF_IRONLY_EXP", 726 1.1.1.7 christos }; 727 1.1.1.7 christos 728 1.1.1.7 christos if (idx < ARRAY_SIZE (lto_resolution_str)) 729 1.1.1.7 christos return lto_resolution_str [idx]; 730 1.1.1.7 christos 731 1.1.1.7 christos sprintf (buffer, _("unknown LTO resolution value %x"), idx); 732 1.1.1.7 christos return buffer; 733 1.1.1.7 christos } 734 1.1.1.7 christos 735 1.1.1.7 christos /* Return LTO visibility string name that corresponds to IDX enum value. */ 736 1.1.1.7 christos static const char * 737 1.1.1.7 christos get_lto_visibility (unsigned int idx) 738 1.1.1.7 christos { 739 1.1.1.7 christos static char buffer[64]; 740 1.1.1.7 christos const char *lto_visibility_str[4] = 741 1.1.1.7 christos { 742 1.1.1.7 christos "DEFAULT", 743 1.1.1.7 christos "PROTECTED", 744 1.1.1.7 christos "INTERNAL", 745 1.1.1.7 christos "HIDDEN" 746 1.1.1.7 christos }; 747 1.1.1.7 christos 748 1.1.1.7 christos if (idx < ARRAY_SIZE (lto_visibility_str)) 749 1.1.1.7 christos return lto_visibility_str [idx]; 750 1.1.1.7 christos 751 1.1.1.7 christos sprintf (buffer, _("unknown LTO visibility value %x"), idx); 752 1.1.1.7 christos return buffer; 753 1.1.1.7 christos } 754 1.1.1.7 christos 755 1.1 christos /* Get the symbol resolution info for a plugin-claimed input file. */ 756 1.1 christos static enum ld_plugin_status 757 1.1.1.2 christos get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms, 758 1.1.1.2 christos int def_ironly_exp) 759 1.1 christos { 760 1.1.1.3 christos const plugin_input_file_t *input = handle; 761 1.1.1.3 christos const bfd *abfd = (const bfd *) input->abfd; 762 1.1 christos int n; 763 1.1.1.2 christos 764 1.1 christos ASSERT (called_plugin); 765 1.1 christos for (n = 0; n < nsyms; n++) 766 1.1 christos { 767 1.1 christos struct bfd_link_hash_entry *blhe; 768 1.1 christos asection *owner_sec; 769 1.1.1.2 christos int res; 770 1.1.1.7 christos struct bfd_link_hash_entry *h 771 1.1.1.7 christos = bfd_link_hash_lookup (link_info.hash, syms[n].name, 772 1.1.1.8 christos false, false, true); 773 1.1.1.7 christos enum { wrap_none, wrapper, wrapped } wrap_status = wrap_none; 774 1.1.1.2 christos 775 1.1.1.7 christos if (syms[n].def != LDPK_UNDEF && syms[n].def != LDPK_WEAKUNDEF) 776 1.1.1.7 christos { 777 1.1.1.7 christos blhe = h; 778 1.1.1.10 christos /* Check if a symbol is a wrapper symbol. */ 779 1.1.1.10 christos if (blhe) 780 1.1.1.7 christos { 781 1.1.1.10 christos if (blhe->wrapper_symbol) 782 1.1.1.7 christos wrap_status = wrapper; 783 1.1.1.10 christos else if (link_info.wrap_hash != NULL) 784 1.1.1.10 christos { 785 1.1.1.10 christos struct bfd_link_hash_entry *unwrap 786 1.1.1.10 christos = unwrap_hash_lookup (&link_info, (bfd *) abfd, blhe); 787 1.1.1.10 christos if (unwrap != NULL && unwrap != h) 788 1.1.1.10 christos wrap_status = wrapper; 789 1.1.1.10 christos } 790 1.1.1.10 christos } 791 1.1.1.7 christos } 792 1.1 christos else 793 1.1.1.7 christos { 794 1.1.1.7 christos blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, 795 1.1.1.7 christos &link_info, syms[n].name, 796 1.1.1.8 christos false, false, true); 797 1.1.1.7 christos /* Check if a symbol is a wrapped symbol. */ 798 1.1.1.7 christos if (blhe && blhe != h) 799 1.1.1.7 christos wrap_status = wrapped; 800 1.1.1.7 christos } 801 1.1 christos if (!blhe) 802 1.1 christos { 803 1.1.1.4 christos /* The plugin is called to claim symbols in an archive element 804 1.1.1.4 christos from plugin_object_p. But those symbols aren't needed to 805 1.1.1.4 christos create output. They are defined and referenced only within 806 1.1.1.4 christos IR. */ 807 1.1.1.4 christos switch (syms[n].def) 808 1.1.1.4 christos { 809 1.1.1.4 christos default: 810 1.1.1.4 christos abort (); 811 1.1.1.4 christos case LDPK_UNDEF: 812 1.1.1.4 christos case LDPK_WEAKUNDEF: 813 1.1.1.4 christos res = LDPR_UNDEF; 814 1.1.1.4 christos break; 815 1.1.1.4 christos case LDPK_DEF: 816 1.1.1.4 christos case LDPK_WEAKDEF: 817 1.1.1.4 christos case LDPK_COMMON: 818 1.1.1.4 christos res = LDPR_PREVAILING_DEF_IRONLY; 819 1.1.1.4 christos break; 820 1.1.1.4 christos } 821 1.1 christos goto report_symbol; 822 1.1 christos } 823 1.1 christos 824 1.1 christos /* Determine resolution from blhe type and symbol's original type. */ 825 1.1 christos if (blhe->type == bfd_link_hash_undefined 826 1.1 christos || blhe->type == bfd_link_hash_undefweak) 827 1.1 christos { 828 1.1.1.2 christos res = LDPR_UNDEF; 829 1.1 christos goto report_symbol; 830 1.1 christos } 831 1.1 christos if (blhe->type != bfd_link_hash_defined 832 1.1 christos && blhe->type != bfd_link_hash_defweak 833 1.1 christos && blhe->type != bfd_link_hash_common) 834 1.1 christos { 835 1.1 christos /* We should not have a new, indirect or warning symbol here. */ 836 1.1.1.10 christos fatal (_("%P: %s: plugin symbol table corrupt (sym type %d)\n"), 837 1.1 christos called_plugin->name, blhe->type); 838 1.1 christos } 839 1.1 christos 840 1.1 christos /* Find out which section owns the symbol. Since it's not undef, 841 1.1 christos it must have an owner; if it's not a common symbol, both defs 842 1.1 christos and weakdefs keep it in the same place. */ 843 1.1 christos owner_sec = (blhe->type == bfd_link_hash_common 844 1.1 christos ? blhe->u.c.p->section 845 1.1 christos : blhe->u.def.section); 846 1.1 christos 847 1.1 christos 848 1.1 christos /* If it was originally undefined or common, then it has been 849 1.1 christos resolved; determine how. */ 850 1.1 christos if (syms[n].def == LDPK_UNDEF 851 1.1 christos || syms[n].def == LDPK_WEAKUNDEF 852 1.1 christos || syms[n].def == LDPK_COMMON) 853 1.1 christos { 854 1.1 christos if (owner_sec->owner == link_info.output_bfd) 855 1.1.1.2 christos res = LDPR_RESOLVED_EXEC; 856 1.1 christos else if (owner_sec->owner == abfd) 857 1.1.1.2 christos res = LDPR_PREVAILING_DEF_IRONLY; 858 1.1 christos else if (is_ir_dummy_bfd (owner_sec->owner)) 859 1.1.1.2 christos res = LDPR_RESOLVED_IR; 860 1.1 christos else if (owner_sec->owner != NULL 861 1.1 christos && (owner_sec->owner->flags & DYNAMIC) != 0) 862 1.1.1.2 christos res = LDPR_RESOLVED_DYN; 863 1.1 christos else 864 1.1.1.2 christos res = LDPR_RESOLVED_EXEC; 865 1.1 christos } 866 1.1 christos 867 1.1 christos /* Was originally def, or weakdef. Does it prevail? If the 868 1.1 christos owner is the original dummy bfd that supplied it, then this 869 1.1 christos is the definition that has prevailed. */ 870 1.1.1.2 christos else if (owner_sec->owner == link_info.output_bfd) 871 1.1.1.2 christos res = LDPR_PREEMPTED_REG; 872 1.1 christos else if (owner_sec->owner == abfd) 873 1.1.1.2 christos res = LDPR_PREVAILING_DEF_IRONLY; 874 1.1 christos 875 1.1 christos /* Was originally def, weakdef, or common, but has been pre-empted. */ 876 1.1.1.2 christos else if (is_ir_dummy_bfd (owner_sec->owner)) 877 1.1.1.2 christos res = LDPR_PREEMPTED_IR; 878 1.1.1.2 christos else 879 1.1.1.2 christos res = LDPR_PREEMPTED_REG; 880 1.1.1.2 christos 881 1.1.1.2 christos if (res == LDPR_PREVAILING_DEF_IRONLY) 882 1.1.1.2 christos { 883 1.1.1.2 christos /* We need to know if the sym is referenced from non-IR files. Or 884 1.1.1.2 christos even potentially-referenced, perhaps in a future final link if 885 1.1.1.2 christos this is a partial one, perhaps dynamically at load-time if the 886 1.1.1.8 christos symbol is externally visible. Also check for __real_SYM 887 1.1.1.8 christos reference and wrapper symbol. */ 888 1.1.1.8 christos if (blhe->non_ir_ref_regular 889 1.1.1.8 christos || blhe->ref_real 890 1.1.1.8 christos || wrap_status == wrapper) 891 1.1.1.2 christos res = LDPR_PREVAILING_DEF; 892 1.1.1.7 christos else if (wrap_status == wrapped) 893 1.1.1.7 christos res = LDPR_RESOLVED_IR; 894 1.1.1.2 christos else if (is_visible_from_outside (&syms[n], blhe)) 895 1.1.1.2 christos res = def_ironly_exp; 896 1.1.1.2 christos } 897 1.1 christos 898 1.1 christos report_symbol: 899 1.1.1.2 christos syms[n].resolution = res; 900 1.1 christos if (report_plugin_symbols) 901 1.1.1.6 christos einfo (_("%P: %pB: symbol `%s' " 902 1.1.1.7 christos "definition: %s, visibility: %s, resolution: %s\n"), 903 1.1 christos abfd, syms[n].name, 904 1.1.1.7 christos get_lto_kind (syms[n].def), 905 1.1.1.7 christos get_lto_visibility (syms[n].visibility), 906 1.1.1.7 christos get_lto_resolution (res)); 907 1.1 christos } 908 1.1 christos return LDPS_OK; 909 1.1 christos } 910 1.1 christos 911 1.1.1.2 christos static enum ld_plugin_status 912 1.1.1.2 christos get_symbols_v1 (const void *handle, int nsyms, struct ld_plugin_symbol *syms) 913 1.1.1.2 christos { 914 1.1.1.2 christos return get_symbols (handle, nsyms, syms, LDPR_PREVAILING_DEF); 915 1.1.1.2 christos } 916 1.1.1.2 christos 917 1.1.1.2 christos static enum ld_plugin_status 918 1.1.1.2 christos get_symbols_v2 (const void *handle, int nsyms, struct ld_plugin_symbol *syms) 919 1.1.1.2 christos { 920 1.1.1.2 christos return get_symbols (handle, nsyms, syms, LDPR_PREVAILING_DEF_IRONLY_EXP); 921 1.1.1.2 christos } 922 1.1.1.2 christos 923 1.1 christos /* Add a new (real) input file generated by a plugin. */ 924 1.1 christos static enum ld_plugin_status 925 1.1 christos add_input_file (const char *pathname) 926 1.1 christos { 927 1.1.1.3 christos lang_input_statement_type *is; 928 1.1.1.3 christos 929 1.1 christos ASSERT (called_plugin); 930 1.1.1.3 christos is = lang_add_input_file (xstrdup (pathname), lang_input_file_is_file_enum, 931 1.1.1.3 christos NULL); 932 1.1.1.3 christos if (!is) 933 1.1 christos return LDPS_ERR; 934 1.1.1.3 christos is->flags.lto_output = 1; 935 1.1 christos return LDPS_OK; 936 1.1 christos } 937 1.1 christos 938 1.1 christos /* Add a new (real) library required by a plugin. */ 939 1.1 christos static enum ld_plugin_status 940 1.1 christos add_input_library (const char *pathname) 941 1.1 christos { 942 1.1.1.3 christos lang_input_statement_type *is; 943 1.1.1.3 christos 944 1.1 christos ASSERT (called_plugin); 945 1.1.1.3 christos is = lang_add_input_file (xstrdup (pathname), lang_input_file_is_l_enum, 946 1.1.1.3 christos NULL); 947 1.1.1.3 christos if (!is) 948 1.1 christos return LDPS_ERR; 949 1.1.1.3 christos is->flags.lto_output = 1; 950 1.1 christos return LDPS_OK; 951 1.1 christos } 952 1.1 christos 953 1.1 christos /* Set the extra library path to be used by libraries added via 954 1.1 christos add_input_library. */ 955 1.1 christos static enum ld_plugin_status 956 1.1 christos set_extra_library_path (const char *path) 957 1.1 christos { 958 1.1 christos ASSERT (called_plugin); 959 1.1.1.8 christos ldfile_add_library_path (xstrdup (path), false); 960 1.1 christos return LDPS_OK; 961 1.1 christos } 962 1.1 christos 963 1.1 christos /* Issue a diagnostic message from a plugin. */ 964 1.1 christos static enum ld_plugin_status 965 1.1 christos message (int level, const char *format, ...) 966 1.1 christos { 967 1.1 christos va_list args; 968 1.1 christos va_start (args, format); 969 1.1 christos 970 1.1 christos switch (level) 971 1.1 christos { 972 1.1 christos case LDPL_INFO: 973 1.1.1.8 christos vfinfo (stdout, format, args, false); 974 1.1 christos putchar ('\n'); 975 1.1 christos break; 976 1.1 christos case LDPL_WARNING: 977 1.1.1.3 christos { 978 1.1.1.6 christos char *newfmt = concat (_("%P: warning: "), format, "\n", 979 1.1.1.4 christos (const char *) NULL); 980 1.1.1.8 christos vfinfo (stdout, newfmt, args, true); 981 1.1.1.4 christos free (newfmt); 982 1.1.1.3 christos } 983 1.1 christos break; 984 1.1 christos case LDPL_FATAL: 985 1.1 christos case LDPL_ERROR: 986 1.1 christos default: 987 1.1 christos { 988 1.1.1.10 christos char *newfmt = concat (_("%X%P: error: "), format, "\n", 989 1.1.1.4 christos (const char *) NULL); 990 1.1 christos fflush (stdout); 991 1.1.1.8 christos vfinfo (stderr, newfmt, args, true); 992 1.1 christos fflush (stderr); 993 1.1.1.4 christos free (newfmt); 994 1.1.1.10 christos if (level == LDPL_FATAL) 995 1.1.1.10 christos fatal (""); 996 1.1 christos } 997 1.1 christos break; 998 1.1 christos } 999 1.1 christos 1000 1.1 christos va_end (args); 1001 1.1 christos return LDPS_OK; 1002 1.1 christos } 1003 1.1 christos 1004 1.1 christos /* Helper to size leading part of tv array and set it up. */ 1005 1.1.1.2 christos static void 1006 1.1 christos set_tv_header (struct ld_plugin_tv *tv) 1007 1.1 christos { 1008 1.1 christos size_t i; 1009 1.1 christos 1010 1.1 christos /* Version info. */ 1011 1.1 christos static const unsigned int major = (unsigned)(BFD_VERSION / 100000000UL); 1012 1.1 christos static const unsigned int minor = (unsigned)(BFD_VERSION / 1000000UL) % 100; 1013 1.1 christos 1014 1.1 christos for (i = 0; i < tv_header_size; i++) 1015 1.1 christos { 1016 1.1 christos tv[i].tv_tag = tv_header_tags[i]; 1017 1.1 christos #define TVU(x) tv[i].tv_u.tv_ ## x 1018 1.1 christos switch (tv[i].tv_tag) 1019 1.1 christos { 1020 1.1 christos case LDPT_MESSAGE: 1021 1.1 christos TVU(message) = message; 1022 1.1 christos break; 1023 1.1 christos case LDPT_API_VERSION: 1024 1.1 christos TVU(val) = LD_PLUGIN_API_VERSION; 1025 1.1 christos break; 1026 1.1 christos case LDPT_GNU_LD_VERSION: 1027 1.1 christos TVU(val) = major * 100 + minor; 1028 1.1 christos break; 1029 1.1 christos case LDPT_LINKER_OUTPUT: 1030 1.1.1.3 christos TVU(val) = (bfd_link_relocatable (&link_info) ? LDPO_REL 1031 1.1.1.3 christos : bfd_link_pde (&link_info) ? LDPO_EXEC 1032 1.1.1.3 christos : bfd_link_pie (&link_info) ? LDPO_PIE 1033 1.1.1.3 christos : LDPO_DYN); 1034 1.1 christos break; 1035 1.1 christos case LDPT_OUTPUT_NAME: 1036 1.1 christos TVU(string) = output_filename; 1037 1.1 christos break; 1038 1.1 christos case LDPT_REGISTER_CLAIM_FILE_HOOK: 1039 1.1 christos TVU(register_claim_file) = register_claim_file; 1040 1.1 christos break; 1041 1.1.1.9 christos case LDPT_REGISTER_CLAIM_FILE_HOOK_V2: 1042 1.1.1.9 christos TVU(register_claim_file_v2) = register_claim_file_v2; 1043 1.1.1.9 christos break; 1044 1.1 christos case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK: 1045 1.1 christos TVU(register_all_symbols_read) = register_all_symbols_read; 1046 1.1 christos break; 1047 1.1 christos case LDPT_REGISTER_CLEANUP_HOOK: 1048 1.1 christos TVU(register_cleanup) = register_cleanup; 1049 1.1 christos break; 1050 1.1 christos case LDPT_ADD_SYMBOLS: 1051 1.1 christos TVU(add_symbols) = add_symbols; 1052 1.1 christos break; 1053 1.1 christos case LDPT_GET_INPUT_FILE: 1054 1.1 christos TVU(get_input_file) = get_input_file; 1055 1.1 christos break; 1056 1.1.1.3 christos case LDPT_GET_VIEW: 1057 1.1.1.3 christos TVU(get_view) = get_view; 1058 1.1.1.3 christos break; 1059 1.1 christos case LDPT_RELEASE_INPUT_FILE: 1060 1.1 christos TVU(release_input_file) = release_input_file; 1061 1.1 christos break; 1062 1.1 christos case LDPT_GET_SYMBOLS: 1063 1.1.1.2 christos TVU(get_symbols) = get_symbols_v1; 1064 1.1.1.2 christos break; 1065 1.1.1.2 christos case LDPT_GET_SYMBOLS_V2: 1066 1.1.1.2 christos TVU(get_symbols) = get_symbols_v2; 1067 1.1 christos break; 1068 1.1 christos case LDPT_ADD_INPUT_FILE: 1069 1.1 christos TVU(add_input_file) = add_input_file; 1070 1.1 christos break; 1071 1.1 christos case LDPT_ADD_INPUT_LIBRARY: 1072 1.1 christos TVU(add_input_library) = add_input_library; 1073 1.1 christos break; 1074 1.1 christos case LDPT_SET_EXTRA_LIBRARY_PATH: 1075 1.1 christos TVU(set_extra_library_path) = set_extra_library_path; 1076 1.1 christos break; 1077 1.1 christos default: 1078 1.1 christos /* Added a new entry to the array without adding 1079 1.1 christos a new case to set up its value is a bug. */ 1080 1.1 christos FAIL (); 1081 1.1 christos } 1082 1.1 christos #undef TVU 1083 1.1 christos } 1084 1.1 christos } 1085 1.1 christos 1086 1.1 christos /* Append the per-plugin args list and trailing LDPT_NULL to tv. */ 1087 1.1 christos static void 1088 1.1 christos set_tv_plugin_args (plugin_t *plugin, struct ld_plugin_tv *tv) 1089 1.1 christos { 1090 1.1 christos plugin_arg_t *arg = plugin->args; 1091 1.1 christos while (arg) 1092 1.1 christos { 1093 1.1 christos tv->tv_tag = LDPT_OPTION; 1094 1.1 christos tv->tv_u.tv_string = arg->arg; 1095 1.1 christos arg = arg->next; 1096 1.1 christos tv++; 1097 1.1 christos } 1098 1.1 christos tv->tv_tag = LDPT_NULL; 1099 1.1 christos tv->tv_u.tv_val = 0; 1100 1.1 christos } 1101 1.1 christos 1102 1.1 christos /* Load up and initialise all plugins after argument parsing. */ 1103 1.1.1.2 christos void 1104 1.1 christos plugin_load_plugins (void) 1105 1.1 christos { 1106 1.1 christos struct ld_plugin_tv *my_tv; 1107 1.1 christos unsigned int max_args = 0; 1108 1.1 christos plugin_t *curplug = plugins_list; 1109 1.1 christos 1110 1.1 christos /* If there are no plugins, we need do nothing this run. */ 1111 1.1 christos if (!curplug) 1112 1.1.1.2 christos return; 1113 1.1 christos 1114 1.1 christos /* First pass over plugins to find max # args needed so that we 1115 1.1 christos can size and allocate the tv array. */ 1116 1.1 christos while (curplug) 1117 1.1 christos { 1118 1.1 christos if (curplug->n_args > max_args) 1119 1.1 christos max_args = curplug->n_args; 1120 1.1 christos curplug = curplug->next; 1121 1.1 christos } 1122 1.1 christos 1123 1.1 christos /* Allocate tv array and initialise constant part. */ 1124 1.1.1.10 christos my_tv = stat_alloc ((max_args + 1 + tv_header_size) * sizeof (*my_tv)); 1125 1.1 christos set_tv_header (my_tv); 1126 1.1 christos 1127 1.1 christos /* Pass over plugins again, activating them. */ 1128 1.1 christos curplug = plugins_list; 1129 1.1 christos while (curplug) 1130 1.1 christos { 1131 1.1 christos enum ld_plugin_status rv; 1132 1.1.1.2 christos ld_plugin_onload onloadfn; 1133 1.1.1.2 christos 1134 1.1.1.2 christos onloadfn = (ld_plugin_onload) dlsym (curplug->dlhandle, "onload"); 1135 1.1 christos if (!onloadfn) 1136 1.1.1.2 christos onloadfn = (ld_plugin_onload) dlsym (curplug->dlhandle, "_onload"); 1137 1.1 christos if (!onloadfn) 1138 1.1.1.10 christos fatal (_("%P: %s: error loading plugin: %s\n"), 1139 1.1.1.2 christos curplug->name, dlerror ()); 1140 1.1 christos set_tv_plugin_args (curplug, &my_tv[tv_header_size]); 1141 1.1 christos called_plugin = curplug; 1142 1.1 christos rv = (*onloadfn) (my_tv); 1143 1.1 christos called_plugin = NULL; 1144 1.1 christos if (rv != LDPS_OK) 1145 1.1.1.10 christos fatal (_("%P: %s: plugin error: %d\n"), curplug->name, rv); 1146 1.1 christos curplug = curplug->next; 1147 1.1 christos } 1148 1.1 christos 1149 1.1 christos /* Since plugin(s) inited ok, assume they're going to want symbol 1150 1.1 christos resolutions, which needs us to track which symbols are referenced 1151 1.1 christos by non-IR files using the linker's notice callback. */ 1152 1.1 christos orig_notice_all = link_info.notice_all; 1153 1.1 christos orig_callbacks = link_info.callbacks; 1154 1.1 christos plugin_callbacks = *orig_callbacks; 1155 1.1 christos plugin_callbacks.notice = &plugin_notice; 1156 1.1.1.8 christos link_info.notice_all = true; 1157 1.1.1.8 christos link_info.lto_plugin_active = true; 1158 1.1 christos link_info.callbacks = &plugin_callbacks; 1159 1.1.1.3 christos 1160 1.1.1.3 christos register_ld_plugin_object_p (plugin_object_p); 1161 1.1.1.3 christos 1162 1.1.1.3 christos #if HAVE_MMAP && HAVE_GETPAGESIZE 1163 1.1.1.3 christos plugin_pagesize = getpagesize (); 1164 1.1.1.3 christos #endif 1165 1.1 christos } 1166 1.1 christos 1167 1.1 christos /* Call 'claim file' hook for all plugins. */ 1168 1.1 christos static int 1169 1.1.1.9 christos plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed, 1170 1.1.1.10 christos int *claim_file_handler_v2, bool known_used) 1171 1.1 christos { 1172 1.1 christos plugin_t *curplug = plugins_list; 1173 1.1.1.8 christos *claimed = false; 1174 1.1.1.10 christos *claim_file_handler_v2 = false; 1175 1.1 christos while (curplug && !*claimed) 1176 1.1 christos { 1177 1.1 christos if (curplug->claim_file_handler) 1178 1.1 christos { 1179 1.1 christos enum ld_plugin_status rv; 1180 1.1.1.5 christos 1181 1.1 christos called_plugin = curplug; 1182 1.1.1.9 christos if (curplug->claim_file_handler_v2) 1183 1.1.1.10 christos { 1184 1.1.1.10 christos rv = (*curplug->claim_file_handler_v2) (file, claimed, 1185 1.1.1.10 christos known_used); 1186 1.1.1.10 christos *claim_file_handler_v2 = true; 1187 1.1.1.10 christos } 1188 1.1.1.9 christos else 1189 1.1.1.9 christos rv = (*curplug->claim_file_handler) (file, claimed); 1190 1.1 christos called_plugin = NULL; 1191 1.1 christos if (rv != LDPS_OK) 1192 1.1 christos set_plugin_error (curplug->name); 1193 1.1 christos } 1194 1.1 christos curplug = curplug->next; 1195 1.1 christos } 1196 1.1 christos return plugin_error_p () ? -1 : 0; 1197 1.1 christos } 1198 1.1 christos 1199 1.1.1.3 christos /* Duplicates a character string with memory attached to ABFD. */ 1200 1.1.1.3 christos 1201 1.1.1.3 christos static char * 1202 1.1.1.3 christos plugin_strdup (bfd *abfd, const char *str) 1203 1.1 christos { 1204 1.1.1.3 christos size_t strlength; 1205 1.1.1.3 christos char *copy; 1206 1.1.1.3 christos strlength = strlen (str) + 1; 1207 1.1.1.3 christos copy = bfd_alloc (abfd, strlength); 1208 1.1.1.3 christos if (copy == NULL) 1209 1.1.1.10 christos fatal (_("%P: plugin_strdup failed to allocate memory: %s\n"), 1210 1.1.1.3 christos bfd_get_error ()); 1211 1.1.1.3 christos memcpy (copy, str, strlength); 1212 1.1.1.3 christos return copy; 1213 1.1.1.3 christos } 1214 1.1.1.3 christos 1215 1.1.1.8 christos static void 1216 1.1.1.8 christos plugin_cleanup (bfd *abfd ATTRIBUTE_UNUSED) 1217 1.1.1.8 christos { 1218 1.1.1.8 christos } 1219 1.1.1.8 christos 1220 1.1.1.8 christos static bfd_cleanup 1221 1.1.1.9 christos plugin_object_p (bfd *ibfd, bool known_used) 1222 1.1.1.3 christos { 1223 1.1.1.10 christos int claimed, claim_file_handler_v2; 1224 1.1.1.3 christos plugin_input_file_t *input; 1225 1.1.1.3 christos struct ld_plugin_input_file file; 1226 1.1.1.3 christos bfd *abfd; 1227 1.1.1.3 christos 1228 1.1.1.3 christos /* Don't try the dummy object file. */ 1229 1.1.1.3 christos if ((ibfd->flags & BFD_PLUGIN) != 0) 1230 1.1.1.3 christos return NULL; 1231 1.1.1.3 christos 1232 1.1.1.10 christos /* When KNOWN_USED is false, we call plugin claim_file if plugin_format 1233 1.1.1.10 christos is bfd_plugin_unknown and set plugin_format to bfd_plugin_yes_unused 1234 1.1.1.10 christos on LTO object. When KNOWN_USED is true, we call plugin claim_file 1235 1.1.1.10 christos if plugin_format is bfd_plugin_unknown or bfd_plugin_yes_unused. */ 1236 1.1.1.10 christos if (ibfd->plugin_format != bfd_plugin_unknown 1237 1.1.1.10 christos && (!known_used || ibfd->plugin_format != bfd_plugin_yes_unused)) 1238 1.1.1.3 christos { 1239 1.1.1.10 christos if (ibfd->plugin_format == bfd_plugin_no) 1240 1.1.1.3 christos return NULL; 1241 1.1.1.10 christos else 1242 1.1.1.10 christos return plugin_cleanup; 1243 1.1.1.3 christos } 1244 1.1.1.3 christos 1245 1.1 christos /* We create a dummy BFD, initially empty, to house whatever symbols 1246 1.1 christos the plugin may want to add. */ 1247 1.1.1.8 christos abfd = plugin_get_ir_dummy_bfd (bfd_get_filename (ibfd), ibfd); 1248 1.1.1.3 christos 1249 1.1.1.3 christos input = bfd_alloc (abfd, sizeof (*input)); 1250 1.1.1.3 christos if (input == NULL) 1251 1.1.1.10 christos fatal (_("%P: plugin failed to allocate memory for input: %s\n"), 1252 1.1.1.3 christos bfd_get_error ()); 1253 1.1.1.3 christos 1254 1.1.1.5 christos if (!bfd_plugin_open_input (ibfd, &file)) 1255 1.1.1.5 christos return NULL; 1256 1.1.1.3 christos 1257 1.1.1.8 christos if (file.name == bfd_get_filename (ibfd)) 1258 1.1.1.5 christos { 1259 1.1.1.3 christos /* We must copy filename attached to ibfd if it is not an archive 1260 1.1.1.3 christos member since it may be freed by bfd_close below. */ 1261 1.1.1.5 christos file.name = plugin_strdup (abfd, file.name); 1262 1.1.1.3 christos } 1263 1.1.1.3 christos 1264 1.1.1.3 christos file.handle = input; 1265 1.1.1.3 christos input->abfd = abfd; 1266 1.1.1.8 christos input->ibfd = ibfd->my_archive != NULL ? ibfd : NULL; 1267 1.1.1.3 christos input->view_buffer.addr = NULL; 1268 1.1.1.3 christos input->view_buffer.filesize = 0; 1269 1.1.1.3 christos input->view_buffer.offset = 0; 1270 1.1.1.5 christos input->fd = file.fd; 1271 1.1.1.8 christos input->use_mmap = false; 1272 1.1.1.5 christos input->offset = file.offset; 1273 1.1.1.5 christos input->filesize = file.filesize; 1274 1.1.1.8 christos input->name = plugin_strdup (abfd, bfd_get_filename (ibfd)); 1275 1.1.1.3 christos 1276 1.1.1.3 christos claimed = 0; 1277 1.1.1.3 christos 1278 1.1.1.10 christos if (plugin_call_claim_file (&file, &claimed, &claim_file_handler_v2, 1279 1.1.1.10 christos known_used)) 1280 1.1.1.10 christos fatal (_("%P: %s: plugin reported error claiming file\n"), 1281 1.1 christos plugin_error_plugin ()); 1282 1.1.1.3 christos 1283 1.1.1.8 christos if (input->fd != -1 1284 1.1.1.8 christos && (!claimed || !bfd_plugin_target_p (ibfd->xvec))) 1285 1.1.1.3 christos { 1286 1.1.1.3 christos /* FIXME: fd belongs to us, not the plugin. GCC plugin, which 1287 1.1.1.3 christos doesn't need fd after plugin_call_claim_file, doesn't use 1288 1.1.1.3 christos BFD plugin target vector. Since GCC plugin doesn't call 1289 1.1.1.3 christos release_input_file, we close it here. LLVM plugin, which 1290 1.1.1.3 christos needs fd after plugin_call_claim_file and calls 1291 1.1.1.3 christos release_input_file after it is done, uses BFD plugin target 1292 1.1.1.3 christos vector. This scheme doesn't work when a plugin needs fd and 1293 1.1.1.3 christos doesn't use BFD plugin target vector neither. */ 1294 1.1.1.8 christos release_plugin_file_descriptor (input); 1295 1.1.1.3 christos } 1296 1.1.1.3 christos 1297 1.1 christos if (claimed) 1298 1.1 christos { 1299 1.1.1.10 christos /* Set plugin_format to bfd_plugin_yes_unused if KNOWN_USED is 1300 1.1.1.10 christos false for plugin claim_file_v2 to avoid including the unused 1301 1.1.1.10 christos LTO archive members in linker output. */ 1302 1.1.1.10 christos if (known_used || !claim_file_handler_v2) 1303 1.1.1.10 christos ibfd->plugin_format = bfd_plugin_yes; 1304 1.1.1.10 christos else 1305 1.1.1.10 christos ibfd->plugin_format = bfd_plugin_yes_unused; 1306 1.1.1.3 christos ibfd->plugin_dummy_bfd = abfd; 1307 1.1.1.3 christos bfd_make_readable (abfd); 1308 1.1.1.8 christos abfd->no_export = ibfd->no_export; 1309 1.1.1.8 christos return plugin_cleanup; 1310 1.1.1.3 christos } 1311 1.1.1.3 christos else 1312 1.1.1.3 christos { 1313 1.1.1.3 christos #if HAVE_MMAP 1314 1.1.1.3 christos if (input->use_mmap) 1315 1.1.1.3 christos { 1316 1.1.1.3 christos /* If plugin didn't claim the file, unmap the buffer. */ 1317 1.1.1.3 christos char *addr = input->view_buffer.addr; 1318 1.1.1.3 christos off_t size = input->view_buffer.filesize; 1319 1.1.1.3 christos # if HAVE_GETPAGESIZE 1320 1.1.1.3 christos off_t bias = input->view_buffer.offset % plugin_pagesize; 1321 1.1.1.3 christos size += bias; 1322 1.1.1.3 christos addr -= bias; 1323 1.1.1.3 christos # endif 1324 1.1.1.3 christos munmap (addr, size); 1325 1.1.1.3 christos } 1326 1.1.1.3 christos #endif 1327 1.1.1.3 christos 1328 1.1.1.3 christos /* If plugin didn't claim the file, we don't need the dummy bfd. 1329 1.1.1.11 christos Can't avoid speculatively creating it, alas. NB: Set input 1330 1.1.1.11 christos plugin_format to bfd_plugin_no only if known_used is set or 1331 1.1.1.11 christos the LDPT_REGISTER_CLAIM_FILE_HOOK_V2 linker plugin hook is 1332 1.1.1.11 christos unused since the V2 linker plugin hook doesn't claim the 1333 1.1.1.11 christos offload IR if known_used is unset. */ 1334 1.1.1.11 christos if (known_used || !claim_file_handler_v2) 1335 1.1.1.11 christos ibfd->plugin_format = bfd_plugin_no; 1336 1.1.1.3 christos bfd_close_all_done (abfd); 1337 1.1.1.3 christos return NULL; 1338 1.1.1.3 christos } 1339 1.1.1.3 christos } 1340 1.1.1.3 christos 1341 1.1.1.3 christos void 1342 1.1.1.3 christos plugin_maybe_claim (lang_input_statement_type *entry) 1343 1.1.1.3 christos { 1344 1.1.1.5 christos ASSERT (entry->header.type == lang_input_statement_enum); 1345 1.1.1.9 christos if (plugin_object_p (entry->the_bfd, true)) 1346 1.1.1.3 christos { 1347 1.1.1.3 christos bfd *abfd = entry->the_bfd->plugin_dummy_bfd; 1348 1.1.1.3 christos 1349 1.1.1.10 christos /* Check object only section. */ 1350 1.1.1.10 christos cmdline_check_object_only_section (entry->the_bfd, true); 1351 1.1.1.10 christos 1352 1.1 christos /* Discard the real file's BFD and substitute the dummy one. */ 1353 1.1 christos 1354 1.1.1.4 christos /* We can't call bfd_close on archives. BFD archive handling 1355 1.1.1.4 christos caches elements, and add_archive_element keeps pointers to 1356 1.1.1.4 christos the_bfd and the_bfd->filename in a lang_input_statement_type 1357 1.1.1.4 christos linker script statement. */ 1358 1.1 christos if (entry->the_bfd->my_archive == NULL) 1359 1.1 christos bfd_close (entry->the_bfd); 1360 1.1.1.3 christos entry->the_bfd = abfd; 1361 1.1.1.3 christos entry->flags.claimed = 1; 1362 1.1 christos } 1363 1.1 christos } 1364 1.1 christos 1365 1.1 christos /* Call 'all symbols read' hook for all plugins. */ 1366 1.1 christos int 1367 1.1 christos plugin_call_all_symbols_read (void) 1368 1.1 christos { 1369 1.1 christos plugin_t *curplug = plugins_list; 1370 1.1 christos 1371 1.1 christos /* Disable any further file-claiming. */ 1372 1.1.1.8 christos no_more_claiming = true; 1373 1.1 christos 1374 1.1 christos while (curplug) 1375 1.1 christos { 1376 1.1 christos if (curplug->all_symbols_read_handler) 1377 1.1 christos { 1378 1.1 christos enum ld_plugin_status rv; 1379 1.1 christos called_plugin = curplug; 1380 1.1 christos rv = (*curplug->all_symbols_read_handler) (); 1381 1.1 christos called_plugin = NULL; 1382 1.1 christos if (rv != LDPS_OK) 1383 1.1 christos set_plugin_error (curplug->name); 1384 1.1 christos } 1385 1.1 christos curplug = curplug->next; 1386 1.1 christos } 1387 1.1 christos return plugin_error_p () ? -1 : 0; 1388 1.1 christos } 1389 1.1 christos 1390 1.1 christos /* Call 'cleanup' hook for all plugins at exit. */ 1391 1.1 christos void 1392 1.1 christos plugin_call_cleanup (void) 1393 1.1 christos { 1394 1.1 christos plugin_t *curplug = plugins_list; 1395 1.1 christos while (curplug) 1396 1.1 christos { 1397 1.1 christos if (curplug->cleanup_handler && !curplug->cleanup_done) 1398 1.1 christos { 1399 1.1.1.10 christos if (!config.plugin_save_temps) 1400 1.1.1.10 christos { 1401 1.1.1.10 christos enum ld_plugin_status rv; 1402 1.1.1.10 christos curplug->cleanup_done = true; 1403 1.1.1.10 christos called_plugin = curplug; 1404 1.1.1.10 christos rv = (*curplug->cleanup_handler) (); 1405 1.1.1.10 christos called_plugin = NULL; 1406 1.1.1.10 christos if (rv != LDPS_OK) 1407 1.1.1.10 christos info_msg (_("%P: %s: error in plugin cleanup: %d (ignored)\n"), 1408 1.1.1.10 christos curplug->name, rv); 1409 1.1.1.10 christos } 1410 1.1 christos dlclose (curplug->dlhandle); 1411 1.1 christos } 1412 1.1 christos curplug = curplug->next; 1413 1.1 christos } 1414 1.1 christos } 1415 1.1 christos 1416 1.1 christos /* To determine which symbols should be resolved LDPR_PREVAILING_DEF 1417 1.1 christos and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as 1418 1.1 christos the linker adds them to the linker hash table. Mark those 1419 1.1.1.5 christos referenced from a non-IR file with non_ir_ref_regular or 1420 1.1.1.5 christos non_ir_ref_dynamic as appropriate. We have to notice_all symbols, 1421 1.1.1.5 christos because we won't necessarily know until later which ones will be 1422 1.1.1.5 christos contributed by IR files. */ 1423 1.1.1.8 christos static bool 1424 1.1 christos plugin_notice (struct bfd_link_info *info, 1425 1.1 christos struct bfd_link_hash_entry *h, 1426 1.1.1.3 christos struct bfd_link_hash_entry *inh, 1427 1.1 christos bfd *abfd, 1428 1.1 christos asection *section, 1429 1.1 christos bfd_vma value, 1430 1.1.1.3 christos flagword flags) 1431 1.1 christos { 1432 1.1.1.3 christos struct bfd_link_hash_entry *orig_h = h; 1433 1.1.1.3 christos 1434 1.1 christos if (h != NULL) 1435 1.1 christos { 1436 1.1 christos bfd *sym_bfd; 1437 1.1.1.8 christos bool ref = false; 1438 1.1 christos 1439 1.1.1.3 christos if (h->type == bfd_link_hash_warning) 1440 1.1.1.3 christos h = h->u.i.link; 1441 1.1.1.3 christos 1442 1.1.1.3 christos /* Nothing to do here if this def/ref is from an IR dummy BFD. */ 1443 1.1 christos if (is_ir_dummy_bfd (abfd)) 1444 1.1.1.3 christos ; 1445 1.1 christos 1446 1.1 christos /* Making an indirect symbol counts as a reference unless this 1447 1.1 christos is a brand new symbol. */ 1448 1.1.1.3 christos else if (bfd_is_ind_section (section) 1449 1.1.1.3 christos || (flags & BSF_INDIRECT) != 0) 1450 1.1 christos { 1451 1.1.1.3 christos /* ??? Some of this is questionable. See comments in 1452 1.1.1.3 christos _bfd_generic_link_add_one_symbol for case IND. */ 1453 1.1.1.5 christos if (h->type != bfd_link_hash_new 1454 1.1.1.5 christos || inh->type == bfd_link_hash_new) 1455 1.1 christos { 1456 1.1.1.5 christos if ((abfd->flags & DYNAMIC) == 0) 1457 1.1.1.8 christos inh->non_ir_ref_regular = true; 1458 1.1.1.5 christos else 1459 1.1.1.8 christos inh->non_ir_ref_dynamic = true; 1460 1.1 christos } 1461 1.1.1.5 christos 1462 1.1.1.5 christos if (h->type != bfd_link_hash_new) 1463 1.1.1.8 christos ref = true; 1464 1.1 christos } 1465 1.1 christos 1466 1.1 christos /* Nothing to do here for warning symbols. */ 1467 1.1 christos else if ((flags & BSF_WARNING) != 0) 1468 1.1 christos ; 1469 1.1 christos 1470 1.1 christos /* Nothing to do here for constructor symbols. */ 1471 1.1 christos else if ((flags & BSF_CONSTRUCTOR) != 0) 1472 1.1 christos ; 1473 1.1 christos 1474 1.1 christos /* If this is a ref, set non_ir_ref. */ 1475 1.1 christos else if (bfd_is_und_section (section)) 1476 1.1.1.3 christos { 1477 1.1.1.3 christos /* Replace the undefined dummy bfd with the real one. */ 1478 1.1.1.5 christos if ((h->type == bfd_link_hash_undefined 1479 1.1.1.5 christos || h->type == bfd_link_hash_undefweak) 1480 1.1.1.5 christos && (h->u.undef.abfd == NULL 1481 1.1.1.5 christos || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0)) 1482 1.1.1.5 christos h->u.undef.abfd = abfd; 1483 1.1.1.8 christos ref = true; 1484 1.1.1.3 christos } 1485 1.1 christos 1486 1.1.1.7 christos 1487 1.1.1.7 christos /* A common symbol should be merged with other commons or 1488 1.1.1.7 christos defs with the same name. In particular, a common ought 1489 1.1.1.7 christos to be overridden by a def in a -flto object. In that 1490 1.1.1.7 christos sense a common is also a ref. */ 1491 1.1.1.7 christos else if (bfd_is_com_section (section)) 1492 1.1 christos { 1493 1.1.1.7 christos if (h->type == bfd_link_hash_common 1494 1.1.1.7 christos && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)) 1495 1.1.1.4 christos { 1496 1.1.1.4 christos h->type = bfd_link_hash_undefweak; 1497 1.1.1.4 christos h->u.undef.abfd = sym_bfd; 1498 1.1.1.4 christos } 1499 1.1.1.8 christos ref = true; 1500 1.1.1.7 christos } 1501 1.1.1.5 christos 1502 1.1.1.7 christos /* Otherwise, it must be a new def. 1503 1.1.1.7 christos Ensure any symbol defined in an IR dummy BFD takes on a 1504 1.1.1.7 christos new value from a real BFD. Weak symbols are not normally 1505 1.1.1.7 christos overridden by a new weak definition, and strong symbols 1506 1.1.1.7 christos will normally cause multiple definition errors. Avoid 1507 1.1.1.8 christos this by making the symbol appear to be undefined. 1508 1.1.1.8 christos 1509 1.1.1.8 christos NB: We change the previous definition in the IR object to 1510 1.1.1.8 christos undefweak only after all LTO symbols have been read or for 1511 1.1.1.8 christos non-ELF targets. */ 1512 1.1.1.8 christos else if ((info->lto_all_symbols_read 1513 1.1.1.8 christos || bfd_get_flavour (abfd) != bfd_target_elf_flavour) 1514 1.1.1.8 christos && (((h->type == bfd_link_hash_defweak 1515 1.1.1.8 christos || h->type == bfd_link_hash_defined) 1516 1.1.1.8 christos && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner)) 1517 1.1.1.8 christos || (h->type == bfd_link_hash_common 1518 1.1.1.8 christos && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))) 1519 1.1.1.7 christos { 1520 1.1.1.7 christos h->type = bfd_link_hash_undefweak; 1521 1.1.1.7 christos h->u.undef.abfd = sym_bfd; 1522 1.1.1.5 christos } 1523 1.1.1.5 christos 1524 1.1.1.5 christos if (ref) 1525 1.1.1.5 christos { 1526 1.1.1.5 christos if ((abfd->flags & DYNAMIC) == 0) 1527 1.1.1.8 christos h->non_ir_ref_regular = true; 1528 1.1.1.5 christos else 1529 1.1.1.8 christos h->non_ir_ref_dynamic = true; 1530 1.1 christos } 1531 1.1 christos } 1532 1.1 christos 1533 1.1 christos /* Continue with cref/nocrossref/trace-sym processing. */ 1534 1.1.1.3 christos if (orig_h == NULL 1535 1.1 christos || orig_notice_all 1536 1.1 christos || (info->notice_hash != NULL 1537 1.1.1.3 christos && bfd_hash_lookup (info->notice_hash, orig_h->root.string, 1538 1.1.1.8 christos false, false) != NULL)) 1539 1.1.1.3 christos return (*orig_callbacks->notice) (info, orig_h, inh, 1540 1.1.1.3 christos abfd, section, value, flags); 1541 1.1.1.8 christos return true; 1542 1.1 christos } 1543