ldmain.c revision 89857
133965Sjdp/* Main program of GNU linker. 289857Sobrien Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 360484Sobrien Free Software Foundation, Inc. 433965Sjdp Written by Steve Chamberlain steve@cygnus.com 533965Sjdp 633965SjdpThis file is part of GLD, the Gnu Linker. 733965Sjdp 833965SjdpGLD is free software; you can redistribute it and/or modify 933965Sjdpit under the terms of the GNU General Public License as published by 1033965Sjdpthe Free Software Foundation; either version 2, or (at your option) 1133965Sjdpany later version. 1233965Sjdp 1333965SjdpGLD is distributed in the hope that it will be useful, 1433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965SjdpGNU General Public License for more details. 1733965Sjdp 1833965SjdpYou should have received a copy of the GNU General Public License 1933965Sjdpalong with GLD; see the file COPYING. If not, write to the Free 2033965SjdpSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2133965Sjdp02111-1307, USA. */ 2233965Sjdp 2333965Sjdp#include "bfd.h" 2433965Sjdp#include "sysdep.h" 2533965Sjdp#include <stdio.h> 2689857Sobrien#include "safe-ctype.h" 2733965Sjdp#include "libiberty.h" 2833965Sjdp#include "progress.h" 2933965Sjdp#include "bfdlink.h" 3061843Sobrien#include "filenames.h" 3133965Sjdp 3233965Sjdp#include "ld.h" 3333965Sjdp#include "ldmain.h" 3433965Sjdp#include "ldmisc.h" 3533965Sjdp#include "ldwrite.h" 3633965Sjdp#include "ldgram.h" 3733965Sjdp#include "ldexp.h" 3833965Sjdp#include "ldlang.h" 3933965Sjdp#include "ldlex.h" 4033965Sjdp#include "ldfile.h" 4177298Sobrien#include "ldemul.h" 4233965Sjdp#include "ldctor.h" 4333965Sjdp 4477298Sobrien/* Somewhere above, sys/stat.h got included . . . . */ 4533965Sjdp#if !defined(S_ISDIR) && defined(S_IFDIR) 4633965Sjdp#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 4733965Sjdp#endif 4833965Sjdp 4933965Sjdp#include <string.h> 5033965Sjdp 5133965Sjdp#ifdef HAVE_SBRK 5233965Sjdp#ifdef NEED_DECLARATION_SBRK 5333965Sjdpextern PTR sbrk (); 5433965Sjdp#endif 5533965Sjdp#endif 5633965Sjdp 5733965Sjdpstatic char *get_emulation PARAMS ((int, char **)); 5833965Sjdpstatic void set_scripts_dir PARAMS ((void)); 5933965Sjdp 6033965Sjdp/* EXPORTS */ 6133965Sjdp 6233965Sjdpchar *default_target; 6333965Sjdpconst char *output_filename = "a.out"; 6433965Sjdp 6533965Sjdp/* Name this program was invoked by. */ 6633965Sjdpchar *program_name; 6733965Sjdp 6877298Sobrien/* The file that we're creating. */ 6933965Sjdpbfd *output_bfd = 0; 7033965Sjdp 7133965Sjdp/* Set by -G argument, for MIPS ECOFF target. */ 7233965Sjdpint g_switch_value = 8; 7333965Sjdp 7433965Sjdp/* Nonzero means print names of input files as processed. */ 7533965Sjdpboolean trace_files; 7633965Sjdp 7733965Sjdp/* Nonzero means same, but note open failures, too. */ 7833965Sjdpboolean trace_file_tries; 7933965Sjdp 8033965Sjdp/* Nonzero means version number was printed, so exit successfully 8133965Sjdp instead of complaining if no input files are given. */ 8233965Sjdpboolean version_printed; 8333965Sjdp 8433965Sjdp/* Nonzero means link in every member of an archive. */ 8533965Sjdpboolean whole_archive; 8633965Sjdp 8760484Sobrien/* True if we should demangle symbol names. */ 8860484Sobrienboolean demangling; 8960484Sobrien 9033965Sjdpargs_type command_line; 9133965Sjdp 9233965Sjdpld_config_type config; 9333965Sjdp 9433965Sjdpstatic void remove_output PARAMS ((void)); 9533965Sjdpstatic boolean check_for_scripts_dir PARAMS ((char *dir)); 9633965Sjdpstatic boolean add_archive_element PARAMS ((struct bfd_link_info *, bfd *, 9733965Sjdp const char *)); 9833965Sjdpstatic boolean multiple_definition PARAMS ((struct bfd_link_info *, 9933965Sjdp const char *, 10033965Sjdp bfd *, asection *, bfd_vma, 10133965Sjdp bfd *, asection *, bfd_vma)); 10233965Sjdpstatic boolean multiple_common PARAMS ((struct bfd_link_info *, 10333965Sjdp const char *, bfd *, 10433965Sjdp enum bfd_link_hash_type, bfd_vma, 10533965Sjdp bfd *, enum bfd_link_hash_type, 10633965Sjdp bfd_vma)); 10733965Sjdpstatic boolean add_to_set PARAMS ((struct bfd_link_info *, 10833965Sjdp struct bfd_link_hash_entry *, 10933965Sjdp bfd_reloc_code_real_type, 11033965Sjdp bfd *, asection *, bfd_vma)); 11133965Sjdpstatic boolean constructor_callback PARAMS ((struct bfd_link_info *, 11233965Sjdp boolean constructor, 11333965Sjdp const char *name, 11433965Sjdp bfd *, asection *, bfd_vma)); 11533965Sjdpstatic boolean warning_callback PARAMS ((struct bfd_link_info *, 11633965Sjdp const char *, const char *, bfd *, 11733965Sjdp asection *, bfd_vma)); 11833965Sjdpstatic void warning_find_reloc PARAMS ((bfd *, asection *, PTR)); 11933965Sjdpstatic boolean undefined_symbol PARAMS ((struct bfd_link_info *, 12033965Sjdp const char *, bfd *, 12160484Sobrien asection *, bfd_vma, boolean)); 12233965Sjdpstatic boolean reloc_overflow PARAMS ((struct bfd_link_info *, const char *, 12333965Sjdp const char *, bfd_vma, 12433965Sjdp bfd *, asection *, bfd_vma)); 12533965Sjdpstatic boolean reloc_dangerous PARAMS ((struct bfd_link_info *, const char *, 12633965Sjdp bfd *, asection *, bfd_vma)); 12733965Sjdpstatic boolean unattached_reloc PARAMS ((struct bfd_link_info *, 12833965Sjdp const char *, bfd *, asection *, 12933965Sjdp bfd_vma)); 13033965Sjdpstatic boolean notice PARAMS ((struct bfd_link_info *, const char *, 13133965Sjdp bfd *, asection *, bfd_vma)); 13233965Sjdp 13377298Sobrienstatic struct bfd_link_callbacks link_callbacks = { 13433965Sjdp add_archive_element, 13533965Sjdp multiple_definition, 13633965Sjdp multiple_common, 13733965Sjdp add_to_set, 13833965Sjdp constructor_callback, 13933965Sjdp warning_callback, 14033965Sjdp undefined_symbol, 14133965Sjdp reloc_overflow, 14233965Sjdp reloc_dangerous, 14333965Sjdp unattached_reloc, 14433965Sjdp notice 14533965Sjdp}; 14633965Sjdp 14733965Sjdpstruct bfd_link_info link_info; 14833965Sjdp 14933965Sjdpstatic void 15033965Sjdpremove_output () 15133965Sjdp{ 15277298Sobrien if (output_filename) 15333965Sjdp { 15433965Sjdp if (output_bfd && output_bfd->iostream) 15577298Sobrien fclose ((FILE *) (output_bfd->iostream)); 15633965Sjdp if (delete_output_file_on_failure) 15733965Sjdp unlink (output_filename); 15833965Sjdp } 15933965Sjdp} 16033965Sjdp 16133965Sjdpint 16233965Sjdpmain (argc, argv) 16333965Sjdp int argc; 16433965Sjdp char **argv; 16533965Sjdp{ 16633965Sjdp char *emulation; 16733965Sjdp long start_time = get_run_time (); 16833965Sjdp 16960484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 17060484Sobrien setlocale (LC_MESSAGES, ""); 17160484Sobrien#endif 17289857Sobrien#if defined (HAVE_SETLOCALE) 17389857Sobrien setlocale (LC_CTYPE, ""); 17489857Sobrien#endif 17560484Sobrien bindtextdomain (PACKAGE, LOCALEDIR); 17660484Sobrien textdomain (PACKAGE); 17760484Sobrien 17833965Sjdp program_name = argv[0]; 17933965Sjdp xmalloc_set_program_name (program_name); 18033965Sjdp 18133965Sjdp START_PROGRESS (program_name, 0); 18233965Sjdp 18333965Sjdp bfd_init (); 18433965Sjdp 18533965Sjdp bfd_set_error_program_name (program_name); 18633965Sjdp 18733965Sjdp xatexit (remove_output); 18833965Sjdp 18933965Sjdp /* Set the default BFD target based on the configured target. Doing 19033965Sjdp this permits the linker to be configured for a particular target, 19133965Sjdp and linked against a shared BFD library which was configured for 19233965Sjdp a different target. The macro TARGET is defined by Makefile. */ 19333965Sjdp if (! bfd_set_default_target (TARGET)) 19433965Sjdp { 19560484Sobrien einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET); 19633965Sjdp xexit (1); 19733965Sjdp } 19833965Sjdp 19989857Sobrien#if YYDEBUG 20089857Sobrien { 20189857Sobrien extern int yydebug; 20289857Sobrien yydebug = 1; 20389857Sobrien } 20489857Sobrien#endif 20589857Sobrien 20633965Sjdp /* Initialize the data about options. */ 20733965Sjdp trace_files = trace_file_tries = version_printed = false; 20833965Sjdp whole_archive = false; 20933965Sjdp config.build_constructors = true; 21033965Sjdp config.dynamic_link = false; 21160484Sobrien config.has_shared = false; 21277298Sobrien config.split_by_reloc = (unsigned) -1; 21377298Sobrien config.split_by_file = (bfd_size_type) -1; 21433965Sjdp command_line.force_common_definition = false; 21589857Sobrien command_line.inhibit_common_definition = false; 21633965Sjdp command_line.interpreter = NULL; 21733965Sjdp command_line.rpath = NULL; 21838889Sjdp command_line.warn_mismatch = true; 21960484Sobrien command_line.check_section_addresses = true; 22033965Sjdp 22160484Sobrien /* We initialize DEMANGLING based on the environment variable 22260484Sobrien COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the 22360484Sobrien output of the linker, unless COLLECT_NO_DEMANGLE is set in the 22460484Sobrien environment. Acting the same way here lets us provide the same 22560484Sobrien interface by default. */ 22660484Sobrien demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL; 22760484Sobrien 22833965Sjdp link_info.callbacks = &link_callbacks; 22933965Sjdp link_info.relocateable = false; 23077298Sobrien link_info.emitrelocations = false; 23133965Sjdp link_info.shared = false; 23233965Sjdp link_info.symbolic = false; 23389857Sobrien link_info.export_dynamic = false; 23433965Sjdp link_info.static_link = false; 23533965Sjdp link_info.traditional_format = false; 23660484Sobrien link_info.optimize = false; 23760484Sobrien link_info.no_undefined = false; 23877298Sobrien link_info.allow_shlib_undefined = false; 23933965Sjdp link_info.strip = strip_none; 24089857Sobrien link_info.discard = discard_sec_merge; 24133965Sjdp link_info.keep_memory = true; 24233965Sjdp link_info.input_bfds = NULL; 24333965Sjdp link_info.create_object_symbols_section = NULL; 24433965Sjdp link_info.hash = NULL; 24533965Sjdp link_info.keep_hash = NULL; 24633965Sjdp link_info.notice_all = false; 24733965Sjdp link_info.notice_hash = NULL; 24833965Sjdp link_info.wrap_hash = NULL; 24960484Sobrien link_info.mpc860c0 = 0; 25060484Sobrien /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init 25160484Sobrien and _fini symbols. We are compatible. */ 25260484Sobrien link_info.init_function = "_init"; 25360484Sobrien link_info.fini_function = "_fini"; 25477298Sobrien link_info.new_dtags = false; 25589857Sobrien link_info.eh_frame_hdr = false; 25677298Sobrien link_info.flags = (bfd_vma) 0; 25777298Sobrien link_info.flags_1 = (bfd_vma) 0; 25889857Sobrien link_info.pei386_auto_import = false; 25989857Sobrien link_info.combreloc = false; 26089857Sobrien link_info.spare_dynamic_tags = 5; 26160484Sobrien 26233965Sjdp ldfile_add_arch (""); 26333965Sjdp 26433965Sjdp config.make_executable = true; 26533965Sjdp force_make_executable = false; 26633965Sjdp config.magic_demand_paged = true; 26733965Sjdp config.text_read_only = true; 26833965Sjdp 26933965Sjdp emulation = get_emulation (argc, argv); 27033965Sjdp ldemul_choose_mode (emulation); 27189857Sobrien default_target = ldemul_choose_target (argc, argv); 27233965Sjdp lang_init (); 27333965Sjdp ldemul_before_parse (); 27433965Sjdp lang_has_input_file = false; 27533965Sjdp parse_args (argc, argv); 27633965Sjdp 27733965Sjdp ldemul_set_symbols (); 27833965Sjdp 27933965Sjdp if (link_info.relocateable) 28033965Sjdp { 28160484Sobrien if (command_line.gc_sections) 28260484Sobrien einfo ("%P%F: --gc-sections and -r may not be used together\n"); 28360484Sobrien if (link_info.mpc860c0) 28460484Sobrien einfo (_("%P%F: -r and --mpc860c0 may not be used together\n")); 28560484Sobrien else if (command_line.relax) 28660484Sobrien einfo (_("%P%F: --relax and -r may not be used together\n")); 28733965Sjdp if (link_info.shared) 28860484Sobrien einfo (_("%P%F: -r and -shared may not be used together\n")); 28933965Sjdp } 29033965Sjdp 29189857Sobrien if (! link_info.shared) 29289857Sobrien { 29389857Sobrien if (command_line.filter_shlib) 29489857Sobrien einfo (_("%P%F: -F may not be used without -shared\n")); 29589857Sobrien if (command_line.auxiliary_filters) 29689857Sobrien einfo (_("%P%F: -f may not be used without -shared\n")); 29789857Sobrien } 29889857Sobrien 29933965Sjdp /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I 30033965Sjdp don't see how else this can be handled, since in this case we 30133965Sjdp must preserve all externally visible symbols. */ 30233965Sjdp if (link_info.relocateable && link_info.strip == strip_all) 30333965Sjdp { 30433965Sjdp link_info.strip = strip_debugger; 30589857Sobrien if (link_info.discard == discard_sec_merge) 30633965Sjdp link_info.discard = discard_all; 30733965Sjdp } 30833965Sjdp 30933965Sjdp /* This essentially adds another -L directory so this must be done after 31033965Sjdp the -L's in argv have been processed. */ 31133965Sjdp set_scripts_dir (); 31233965Sjdp 31389857Sobrien /* If we have not already opened and parsed a linker script 31489857Sobrien read the emulation's appropriate default script. */ 31589857Sobrien if (saved_script_handle == NULL) 31633965Sjdp { 31733965Sjdp int isfile; 31889857Sobrien char *s = ldemul_get_script (& isfile); 31933965Sjdp 32033965Sjdp if (isfile) 32133965Sjdp ldfile_open_command_file (s); 32233965Sjdp else 32389857Sobrien { 32433965Sjdp lex_string = s; 32533965Sjdp lex_redirect (s); 32633965Sjdp } 32733965Sjdp parser_input = input_script; 32833965Sjdp yyparse (); 32933965Sjdp lex_string = NULL; 33033965Sjdp } 33133965Sjdp 33289857Sobrien if (trace_file_tries) 33389857Sobrien { 33489857Sobrien if (saved_script_handle) 33589857Sobrien info_msg (_("using external linker script:")); 33689857Sobrien else 33789857Sobrien info_msg (_("using internal linker script:")); 33889857Sobrien info_msg ("\n==================================================\n"); 33989857Sobrien 34089857Sobrien if (saved_script_handle) 34189857Sobrien { 34289857Sobrien static const int ld_bufsz = 8193; 34389857Sobrien size_t n; 34489857Sobrien char *buf = xmalloc (ld_bufsz); 34589857Sobrien 34689857Sobrien rewind (saved_script_handle); 34789857Sobrien while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0) 34889857Sobrien { 34989857Sobrien buf [n] = 0; 35089857Sobrien info_msg (buf); 35189857Sobrien } 35289857Sobrien rewind (saved_script_handle); 35389857Sobrien free (buf); 35489857Sobrien } 35589857Sobrien else 35689857Sobrien { 35789857Sobrien int isfile; 35889857Sobrien 35989857Sobrien info_msg (ldemul_get_script (& isfile)); 36089857Sobrien } 36189857Sobrien 36289857Sobrien info_msg ("\n==================================================\n"); 36389857Sobrien } 36489857Sobrien 36533965Sjdp lang_final (); 36633965Sjdp 36733965Sjdp if (lang_has_input_file == false) 36833965Sjdp { 36933965Sjdp if (version_printed) 37033965Sjdp xexit (0); 37160484Sobrien einfo (_("%P%F: no input files\n")); 37233965Sjdp } 37333965Sjdp 37433965Sjdp if (trace_files) 37533965Sjdp { 37660484Sobrien info_msg (_("%P: mode %s\n"), emulation); 37733965Sjdp } 37833965Sjdp 37933965Sjdp ldemul_after_parse (); 38033965Sjdp 38133965Sjdp if (config.map_filename) 38233965Sjdp { 38333965Sjdp if (strcmp (config.map_filename, "-") == 0) 38433965Sjdp { 38533965Sjdp config.map_file = stdout; 38633965Sjdp } 38733965Sjdp else 38833965Sjdp { 38933965Sjdp config.map_file = fopen (config.map_filename, FOPEN_WT); 39033965Sjdp if (config.map_file == (FILE *) NULL) 39133965Sjdp { 39233965Sjdp bfd_set_error (bfd_error_system_call); 39360484Sobrien einfo (_("%P%F: cannot open map file %s: %E\n"), 39433965Sjdp config.map_filename); 39533965Sjdp } 39633965Sjdp } 39733965Sjdp } 39833965Sjdp 39933965Sjdp lang_process (); 40033965Sjdp 40133965Sjdp /* Print error messages for any missing symbols, for any warning 40277298Sobrien symbols, and possibly multiple definitions. */ 40333965Sjdp 40477298Sobrien if (! link_info.relocateable) 40533965Sjdp { 40677298Sobrien /* Look for a text section and switch the readonly attribute in it. */ 40733965Sjdp asection *found = bfd_get_section_by_name (output_bfd, ".text"); 40833965Sjdp 40933965Sjdp if (found != (asection *) NULL) 41033965Sjdp { 41177298Sobrien if (config.text_read_only) 41277298Sobrien found->flags |= SEC_READONLY; 41377298Sobrien else 41477298Sobrien found->flags &= ~SEC_READONLY; 41533965Sjdp } 41633965Sjdp } 41733965Sjdp 41833965Sjdp if (link_info.relocateable) 41933965Sjdp output_bfd->flags &= ~EXEC_P; 42033965Sjdp else 42133965Sjdp output_bfd->flags |= EXEC_P; 42233965Sjdp 42333965Sjdp ldwrite (); 42433965Sjdp 42533965Sjdp if (config.map_file != NULL) 42633965Sjdp lang_map (); 42733965Sjdp if (command_line.cref) 42833965Sjdp output_cref (config.map_file != NULL ? config.map_file : stdout); 42933965Sjdp if (nocrossref_list != NULL) 43033965Sjdp check_nocrossrefs (); 43133965Sjdp 43233965Sjdp /* Even if we're producing relocateable output, some non-fatal errors should 43333965Sjdp be reported in the exit status. (What non-fatal errors, if any, do we 43433965Sjdp want to ignore for relocateable output?) */ 43533965Sjdp 43633965Sjdp if (config.make_executable == false && force_make_executable == false) 43733965Sjdp { 43833965Sjdp if (trace_files == true) 43933965Sjdp { 44060484Sobrien einfo (_("%P: link errors found, deleting executable `%s'\n"), 44133965Sjdp output_filename); 44233965Sjdp } 44333965Sjdp 44433965Sjdp /* The file will be removed by remove_output. */ 44533965Sjdp 44633965Sjdp xexit (1); 44733965Sjdp } 44833965Sjdp else 44933965Sjdp { 45033965Sjdp if (! bfd_close (output_bfd)) 45160484Sobrien einfo (_("%F%B: final close failed: %E\n"), output_bfd); 45233965Sjdp 45333965Sjdp /* If the --force-exe-suffix is enabled, and we're making an 45477298Sobrien executable file and it doesn't end in .exe, copy it to one 45577298Sobrien which does. */ 45633965Sjdp if (! link_info.relocateable && command_line.force_exe_suffix) 45733965Sjdp { 45833965Sjdp int len = strlen (output_filename); 45977298Sobrien if (len < 4 46033965Sjdp || (strcasecmp (output_filename + len - 4, ".exe") != 0 46133965Sjdp && strcasecmp (output_filename + len - 4, ".dll") != 0)) 46233965Sjdp { 46333965Sjdp FILE *src; 46433965Sjdp FILE *dst; 46533965Sjdp const int bsize = 4096; 46633965Sjdp char *buf = xmalloc (bsize); 46733965Sjdp int l; 46833965Sjdp char *dst_name = xmalloc (len + 5); 46933965Sjdp strcpy (dst_name, output_filename); 47033965Sjdp strcat (dst_name, ".exe"); 47133965Sjdp src = fopen (output_filename, FOPEN_RB); 47233965Sjdp dst = fopen (dst_name, FOPEN_WB); 47333965Sjdp 47433965Sjdp if (!src) 47560484Sobrien einfo (_("%X%P: unable to open for source of copy `%s'\n"), output_filename); 47633965Sjdp if (!dst) 47760484Sobrien einfo (_("%X%P: unable to open for destination of copy `%s'\n"), dst_name); 47833965Sjdp while ((l = fread (buf, 1, bsize, src)) > 0) 47933965Sjdp { 48033965Sjdp int done = fwrite (buf, 1, l, dst); 48133965Sjdp if (done != l) 48233965Sjdp { 48360484Sobrien einfo (_("%P: Error writing file `%s'\n"), dst_name); 48433965Sjdp } 48533965Sjdp } 48633965Sjdp fclose (src); 48733965Sjdp if (fclose (dst) == EOF) 48833965Sjdp { 48960484Sobrien einfo (_("%P: Error closing file `%s'\n"), dst_name); 49033965Sjdp } 49133965Sjdp free (dst_name); 49233965Sjdp free (buf); 49333965Sjdp } 49433965Sjdp } 49533965Sjdp } 49633965Sjdp 49733965Sjdp END_PROGRESS (program_name); 49833965Sjdp 49933965Sjdp if (config.stats) 50033965Sjdp { 50133965Sjdp#ifdef HAVE_SBRK 50233965Sjdp char *lim = (char *) sbrk (0); 50333965Sjdp#endif 50433965Sjdp long run_time = get_run_time () - start_time; 50533965Sjdp 50660484Sobrien fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"), 50733965Sjdp program_name, run_time / 1000000, run_time % 1000000); 50833965Sjdp#ifdef HAVE_SBRK 50960484Sobrien fprintf (stderr, _("%s: data size %ld\n"), program_name, 51033965Sjdp (long) (lim - (char *) &environ)); 51133965Sjdp#endif 51233965Sjdp } 51333965Sjdp 51433965Sjdp /* Prevent remove_output from doing anything, after a successful link. */ 51533965Sjdp output_filename = NULL; 51633965Sjdp 51733965Sjdp xexit (0); 51833965Sjdp return 0; 51933965Sjdp} 52033965Sjdp 52133965Sjdp/* We need to find any explicitly given emulation in order to initialize the 52233965Sjdp state that's needed by the lex&yacc argument parser (parse_args). */ 52333965Sjdp 52433965Sjdpstatic char * 52533965Sjdpget_emulation (argc, argv) 52633965Sjdp int argc; 52733965Sjdp char **argv; 52833965Sjdp{ 52933965Sjdp char *emulation; 53033965Sjdp int i; 53133965Sjdp 53233965Sjdp emulation = getenv (EMULATION_ENVIRON); 53333965Sjdp if (emulation == NULL) 53433965Sjdp emulation = DEFAULT_EMULATION; 53533965Sjdp 53633965Sjdp for (i = 1; i < argc; i++) 53733965Sjdp { 53833965Sjdp if (!strncmp (argv[i], "-m", 2)) 53933965Sjdp { 54033965Sjdp if (argv[i][2] == '\0') 54133965Sjdp { 54233965Sjdp /* -m EMUL */ 54333965Sjdp if (i < argc - 1) 54433965Sjdp { 54533965Sjdp emulation = argv[i + 1]; 54633965Sjdp i++; 54733965Sjdp } 54833965Sjdp else 54933965Sjdp { 55077298Sobrien einfo (_("%P%F: missing argument to -m\n")); 55133965Sjdp } 55233965Sjdp } 55333965Sjdp else if (strcmp (argv[i], "-mips1") == 0 55433965Sjdp || strcmp (argv[i], "-mips2") == 0 55533965Sjdp || strcmp (argv[i], "-mips3") == 0 55689857Sobrien || strcmp (argv[i], "-mips32") == 0 55789857Sobrien || strcmp (argv[i], "-mips64") == 0 55889857Sobrien || strcmp (argv[i], "-mips4") == 0 55989857Sobrien || strcmp (argv[i], "-mips5") == 0) 56033965Sjdp { 56189857Sobrien /* FIXME: The arguments -mips1, -mips2, -mips3, etc. are 56233965Sjdp passed to the linker by some MIPS compilers. They 56333965Sjdp generally tell the linker to use a slightly different 56433965Sjdp library path. Perhaps someday these should be 56533965Sjdp implemented as emulations; until then, we just ignore 56633965Sjdp the arguments and hope that nobody ever creates 56733965Sjdp emulations named ips1, ips2 or ips3. */ 56833965Sjdp } 56933965Sjdp else if (strcmp (argv[i], "-m486") == 0) 57033965Sjdp { 57133965Sjdp /* FIXME: The argument -m486 is passed to the linker on 57233965Sjdp some Linux systems. Hope that nobody creates an 57333965Sjdp emulation named 486. */ 57433965Sjdp } 57533965Sjdp else 57633965Sjdp { 57733965Sjdp /* -mEMUL */ 57833965Sjdp emulation = &argv[i][2]; 57933965Sjdp } 58033965Sjdp } 58133965Sjdp } 58233965Sjdp 58333965Sjdp return emulation; 58433965Sjdp} 58533965Sjdp 58633965Sjdp/* If directory DIR contains an "ldscripts" subdirectory, 58733965Sjdp add DIR to the library search path and return true, 58833965Sjdp else return false. */ 58933965Sjdp 59033965Sjdpstatic boolean 59133965Sjdpcheck_for_scripts_dir (dir) 59233965Sjdp char *dir; 59333965Sjdp{ 59433965Sjdp size_t dirlen; 59533965Sjdp char *buf; 59633965Sjdp struct stat s; 59733965Sjdp boolean res; 59833965Sjdp 59933965Sjdp dirlen = strlen (dir); 60033965Sjdp /* sizeof counts the terminating NUL. */ 60177298Sobrien buf = (char *) xmalloc (dirlen + sizeof ("/ldscripts")); 60233965Sjdp sprintf (buf, "%s/ldscripts", dir); 60333965Sjdp 60433965Sjdp res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode); 60533965Sjdp free (buf); 60633965Sjdp if (res) 60733965Sjdp ldfile_add_library_path (dir, false); 60833965Sjdp return res; 60933965Sjdp} 61033965Sjdp 61133965Sjdp/* Set the default directory for finding script files. 61233965Sjdp Libraries will be searched for here too, but that's ok. 61333965Sjdp We look for the "ldscripts" directory in: 61433965Sjdp 61533965Sjdp SCRIPTDIR (passed from Makefile) 61633965Sjdp the dir where this program is (for using it from the build tree) 61733965Sjdp the dir where this program is/../lib (for installing the tool suite elsewhere) */ 61833965Sjdp 61933965Sjdpstatic void 62033965Sjdpset_scripts_dir () 62133965Sjdp{ 62233965Sjdp char *end, *dir; 62333965Sjdp size_t dirlen; 62433965Sjdp 62533965Sjdp if (check_for_scripts_dir (SCRIPTDIR)) 62677298Sobrien /* We've been installed normally. */ 62777298Sobrien return; 62833965Sjdp 62933965Sjdp /* Look for "ldscripts" in the dir where our binary is. */ 63033965Sjdp end = strrchr (program_name, '/'); 63161843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 63261843Sobrien { 63361843Sobrien /* We could have \foo\bar, or /foo\bar. */ 63461843Sobrien char *bslash = strrchr (program_name, '\\'); 63577298Sobrien if (end == NULL || (bslash != NULL && bslash > end)) 63661843Sobrien end = bslash; 63761843Sobrien } 63861843Sobrien#endif 63933965Sjdp 64033965Sjdp if (end == NULL) 64133965Sjdp { 64233965Sjdp /* Don't look for ldscripts in the current directory. There is 64333965Sjdp too much potential for confusion. */ 64433965Sjdp return; 64533965Sjdp } 64633965Sjdp 64733965Sjdp dirlen = end - program_name; 64833965Sjdp /* Make a copy of program_name in dir. 64933965Sjdp Leave room for later "/../lib". */ 65033965Sjdp dir = (char *) xmalloc (dirlen + 8); 65133965Sjdp strncpy (dir, program_name, dirlen); 65233965Sjdp dir[dirlen] = '\0'; 65333965Sjdp 65433965Sjdp if (check_for_scripts_dir (dir)) 65577298Sobrien /* Don't free dir. */ 65677298Sobrien return; 65733965Sjdp 65833965Sjdp /* Look for "ldscripts" in <the dir where our binary is>/../lib. */ 65933965Sjdp strcpy (dir + dirlen, "/../lib"); 66033965Sjdp if (check_for_scripts_dir (dir)) 66133965Sjdp return; 66233965Sjdp 66377298Sobrien /* Well, we tried. */ 66477298Sobrien free (dir); 66533965Sjdp} 66633965Sjdp 66733965Sjdpvoid 66833965Sjdpadd_ysym (name) 66933965Sjdp const char *name; 67033965Sjdp{ 67133965Sjdp if (link_info.notice_hash == (struct bfd_hash_table *) NULL) 67233965Sjdp { 67333965Sjdp link_info.notice_hash = ((struct bfd_hash_table *) 67433965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 67533965Sjdp if (! bfd_hash_table_init_n (link_info.notice_hash, 67633965Sjdp bfd_hash_newfunc, 67733965Sjdp 61)) 67860484Sobrien einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); 67977298Sobrien } 68033965Sjdp 68133965Sjdp if (bfd_hash_lookup (link_info.notice_hash, name, true, true) 68233965Sjdp == (struct bfd_hash_entry *) NULL) 68360484Sobrien einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); 68433965Sjdp} 68533965Sjdp 68633965Sjdp/* Record a symbol to be wrapped, from the --wrap option. */ 68733965Sjdp 68833965Sjdpvoid 68933965Sjdpadd_wrap (name) 69033965Sjdp const char *name; 69133965Sjdp{ 69233965Sjdp if (link_info.wrap_hash == NULL) 69333965Sjdp { 69433965Sjdp link_info.wrap_hash = ((struct bfd_hash_table *) 69533965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 69633965Sjdp if (! bfd_hash_table_init_n (link_info.wrap_hash, 69733965Sjdp bfd_hash_newfunc, 69833965Sjdp 61)) 69960484Sobrien einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); 70033965Sjdp } 70133965Sjdp if (bfd_hash_lookup (link_info.wrap_hash, name, true, true) == NULL) 70260484Sobrien einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); 70333965Sjdp} 70433965Sjdp 70533965Sjdp/* Handle the -retain-symbols-file option. */ 70633965Sjdp 70733965Sjdpvoid 70833965Sjdpadd_keepsyms_file (filename) 70933965Sjdp const char *filename; 71033965Sjdp{ 71133965Sjdp FILE *file; 71233965Sjdp char *buf; 71333965Sjdp size_t bufsize; 71433965Sjdp int c; 71533965Sjdp 71633965Sjdp if (link_info.strip == strip_some) 71760484Sobrien einfo (_("%X%P: error: duplicate retain-symbols-file\n")); 71833965Sjdp 71933965Sjdp file = fopen (filename, "r"); 72033965Sjdp if (file == (FILE *) NULL) 72133965Sjdp { 72233965Sjdp bfd_set_error (bfd_error_system_call); 72333965Sjdp einfo ("%X%P: %s: %E\n", filename); 72433965Sjdp return; 72533965Sjdp } 72633965Sjdp 72733965Sjdp link_info.keep_hash = ((struct bfd_hash_table *) 72833965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 72933965Sjdp if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc)) 73060484Sobrien einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); 73133965Sjdp 73233965Sjdp bufsize = 100; 73333965Sjdp buf = (char *) xmalloc (bufsize); 73433965Sjdp 73533965Sjdp c = getc (file); 73633965Sjdp while (c != EOF) 73733965Sjdp { 73889857Sobrien while (ISSPACE (c)) 73933965Sjdp c = getc (file); 74033965Sjdp 74133965Sjdp if (c != EOF) 74233965Sjdp { 74333965Sjdp size_t len = 0; 74433965Sjdp 74589857Sobrien while (! ISSPACE (c) && c != EOF) 74633965Sjdp { 74733965Sjdp buf[len] = c; 74833965Sjdp ++len; 74933965Sjdp if (len >= bufsize) 75033965Sjdp { 75133965Sjdp bufsize *= 2; 75233965Sjdp buf = xrealloc (buf, bufsize); 75333965Sjdp } 75433965Sjdp c = getc (file); 75533965Sjdp } 75633965Sjdp 75733965Sjdp buf[len] = '\0'; 75833965Sjdp 75933965Sjdp if (bfd_hash_lookup (link_info.keep_hash, buf, true, true) 76033965Sjdp == (struct bfd_hash_entry *) NULL) 76160484Sobrien einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n")); 76233965Sjdp } 76333965Sjdp } 76433965Sjdp 76533965Sjdp if (link_info.strip != strip_none) 76660484Sobrien einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n")); 76733965Sjdp 76833965Sjdp link_info.strip = strip_some; 76933965Sjdp} 77033965Sjdp 77133965Sjdp/* Callbacks from the BFD linker routines. */ 77233965Sjdp 77333965Sjdp/* This is called when BFD has decided to include an archive member in 77433965Sjdp a link. */ 77533965Sjdp 77633965Sjdpstatic boolean 77733965Sjdpadd_archive_element (info, abfd, name) 77860484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 77933965Sjdp bfd *abfd; 78033965Sjdp const char *name; 78133965Sjdp{ 78233965Sjdp lang_input_statement_type *input; 78333965Sjdp 78433965Sjdp input = ((lang_input_statement_type *) 78533965Sjdp xmalloc (sizeof (lang_input_statement_type))); 78633965Sjdp input->filename = abfd->filename; 78733965Sjdp input->local_sym_name = abfd->filename; 78833965Sjdp input->the_bfd = abfd; 78933965Sjdp input->asymbols = NULL; 79033965Sjdp input->next = NULL; 79133965Sjdp input->just_syms_flag = false; 79233965Sjdp input->loaded = false; 79333965Sjdp input->search_dirs_flag = false; 79433965Sjdp 79533965Sjdp /* FIXME: The following fields are not set: header.next, 79633965Sjdp header.type, closed, passive_position, symbol_count, 79733965Sjdp next_real_file, is_archive, target, real. This bit of code is 79833965Sjdp from the old decode_library_subfile function. I don't know 79933965Sjdp whether any of those fields matters. */ 80033965Sjdp 80133965Sjdp ldlang_add_file (input); 80233965Sjdp 80333965Sjdp if (config.map_file != (FILE *) NULL) 80433965Sjdp { 80533965Sjdp static boolean header_printed; 80633965Sjdp struct bfd_link_hash_entry *h; 80733965Sjdp bfd *from; 80833965Sjdp int len; 80933965Sjdp 81033965Sjdp h = bfd_link_hash_lookup (link_info.hash, name, false, false, true); 81133965Sjdp 81233965Sjdp if (h == NULL) 81333965Sjdp from = NULL; 81433965Sjdp else 81533965Sjdp { 81633965Sjdp switch (h->type) 81733965Sjdp { 81833965Sjdp default: 81933965Sjdp from = NULL; 82033965Sjdp break; 82133965Sjdp 82233965Sjdp case bfd_link_hash_defined: 82333965Sjdp case bfd_link_hash_defweak: 82433965Sjdp from = h->u.def.section->owner; 82533965Sjdp break; 82633965Sjdp 82733965Sjdp case bfd_link_hash_undefined: 82833965Sjdp case bfd_link_hash_undefweak: 82933965Sjdp from = h->u.undef.abfd; 83033965Sjdp break; 83133965Sjdp 83233965Sjdp case bfd_link_hash_common: 83333965Sjdp from = h->u.c.p->section->owner; 83433965Sjdp break; 83533965Sjdp } 83633965Sjdp } 83733965Sjdp 83833965Sjdp if (! header_printed) 83933965Sjdp { 84033965Sjdp char buf[100]; 84133965Sjdp 84289857Sobrien sprintf (buf, _("Archive member included because of file (symbol)\n\n")); 84333965Sjdp minfo ("%s", buf); 84433965Sjdp header_printed = true; 84533965Sjdp } 84633965Sjdp 84733965Sjdp if (bfd_my_archive (abfd) == NULL) 84833965Sjdp { 84933965Sjdp minfo ("%s", bfd_get_filename (abfd)); 85033965Sjdp len = strlen (bfd_get_filename (abfd)); 85133965Sjdp } 85233965Sjdp else 85333965Sjdp { 85433965Sjdp minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)), 85533965Sjdp bfd_get_filename (abfd)); 85633965Sjdp len = (strlen (bfd_get_filename (bfd_my_archive (abfd))) 85733965Sjdp + strlen (bfd_get_filename (abfd)) 85833965Sjdp + 2); 85933965Sjdp } 86033965Sjdp 86133965Sjdp if (len >= 29) 86233965Sjdp { 86333965Sjdp print_nl (); 86433965Sjdp len = 0; 86533965Sjdp } 86633965Sjdp while (len < 30) 86733965Sjdp { 86833965Sjdp print_space (); 86933965Sjdp ++len; 87033965Sjdp } 87133965Sjdp 87233965Sjdp if (from != NULL) 87333965Sjdp minfo ("%B ", from); 87433965Sjdp if (h != NULL) 87533965Sjdp minfo ("(%T)\n", h->root.string); 87633965Sjdp else 87733965Sjdp minfo ("(%s)\n", name); 87833965Sjdp } 87933965Sjdp 88033965Sjdp if (trace_files || trace_file_tries) 88133965Sjdp info_msg ("%I\n", input); 88233965Sjdp 88333965Sjdp return true; 88433965Sjdp} 88533965Sjdp 88633965Sjdp/* This is called when BFD has discovered a symbol which is defined 88733965Sjdp multiple times. */ 88833965Sjdp 88933965Sjdpstatic boolean 89033965Sjdpmultiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval) 89160484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 89233965Sjdp const char *name; 89333965Sjdp bfd *obfd; 89433965Sjdp asection *osec; 89533965Sjdp bfd_vma oval; 89633965Sjdp bfd *nbfd; 89733965Sjdp asection *nsec; 89833965Sjdp bfd_vma nval; 89933965Sjdp{ 90033965Sjdp /* If either section has the output_section field set to 90133965Sjdp bfd_abs_section_ptr, it means that the section is being 90233965Sjdp discarded, and this is not really a multiple definition at all. 90333965Sjdp FIXME: It would be cleaner to somehow ignore symbols defined in 90433965Sjdp sections which are being discarded. */ 90533965Sjdp if ((osec->output_section != NULL 90633965Sjdp && ! bfd_is_abs_section (osec) 90733965Sjdp && bfd_is_abs_section (osec->output_section)) 90833965Sjdp || (nsec->output_section != NULL 90933965Sjdp && ! bfd_is_abs_section (nsec) 91033965Sjdp && bfd_is_abs_section (nsec->output_section))) 91133965Sjdp return true; 91233965Sjdp 91360484Sobrien einfo (_("%X%C: multiple definition of `%T'\n"), 91433965Sjdp nbfd, nsec, nval, name); 91533965Sjdp if (obfd != (bfd *) NULL) 91660484Sobrien einfo (_("%D: first defined here\n"), obfd, osec, oval); 91777298Sobrien 91877298Sobrien if (command_line.relax) 91977298Sobrien { 92077298Sobrien einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n")); 92177298Sobrien command_line.relax = 0; 92277298Sobrien } 92377298Sobrien 92433965Sjdp return true; 92533965Sjdp} 92633965Sjdp 92733965Sjdp/* This is called when there is a definition of a common symbol, or 92833965Sjdp when a common symbol is found for a symbol that is already defined, 92933965Sjdp or when two common symbols are found. We only do something if 93033965Sjdp -warn-common was used. */ 93133965Sjdp 93233965Sjdpstatic boolean 93333965Sjdpmultiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize) 93460484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 93533965Sjdp const char *name; 93633965Sjdp bfd *obfd; 93733965Sjdp enum bfd_link_hash_type otype; 93833965Sjdp bfd_vma osize; 93933965Sjdp bfd *nbfd; 94033965Sjdp enum bfd_link_hash_type ntype; 94133965Sjdp bfd_vma nsize; 94233965Sjdp{ 94333965Sjdp if (! config.warn_common) 94433965Sjdp return true; 94533965Sjdp 94633965Sjdp if (ntype == bfd_link_hash_defined 94733965Sjdp || ntype == bfd_link_hash_defweak 94833965Sjdp || ntype == bfd_link_hash_indirect) 94933965Sjdp { 95033965Sjdp ASSERT (otype == bfd_link_hash_common); 95160484Sobrien einfo (_("%B: warning: definition of `%T' overriding common\n"), 95233965Sjdp nbfd, name); 95333965Sjdp if (obfd != NULL) 95460484Sobrien einfo (_("%B: warning: common is here\n"), obfd); 95533965Sjdp } 95633965Sjdp else if (otype == bfd_link_hash_defined 95733965Sjdp || otype == bfd_link_hash_defweak 95833965Sjdp || otype == bfd_link_hash_indirect) 95933965Sjdp { 96033965Sjdp ASSERT (ntype == bfd_link_hash_common); 96160484Sobrien einfo (_("%B: warning: common of `%T' overridden by definition\n"), 96233965Sjdp nbfd, name); 96333965Sjdp if (obfd != NULL) 96460484Sobrien einfo (_("%B: warning: defined here\n"), obfd); 96533965Sjdp } 96633965Sjdp else 96733965Sjdp { 96833965Sjdp ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common); 96933965Sjdp if (osize > nsize) 97033965Sjdp { 97160484Sobrien einfo (_("%B: warning: common of `%T' overridden by larger common\n"), 97233965Sjdp nbfd, name); 97333965Sjdp if (obfd != NULL) 97460484Sobrien einfo (_("%B: warning: larger common is here\n"), obfd); 97533965Sjdp } 97633965Sjdp else if (nsize > osize) 97733965Sjdp { 97860484Sobrien einfo (_("%B: warning: common of `%T' overriding smaller common\n"), 97933965Sjdp nbfd, name); 98033965Sjdp if (obfd != NULL) 98160484Sobrien einfo (_("%B: warning: smaller common is here\n"), obfd); 98233965Sjdp } 98333965Sjdp else 98433965Sjdp { 98560484Sobrien einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name); 98633965Sjdp if (obfd != NULL) 98760484Sobrien einfo (_("%B: warning: previous common is here\n"), obfd); 98833965Sjdp } 98933965Sjdp } 99033965Sjdp 99133965Sjdp return true; 99233965Sjdp} 99333965Sjdp 99433965Sjdp/* This is called when BFD has discovered a set element. H is the 99533965Sjdp entry in the linker hash table for the set. SECTION and VALUE 99633965Sjdp represent a value which should be added to the set. */ 99733965Sjdp 99833965Sjdpstatic boolean 99933965Sjdpadd_to_set (info, h, reloc, abfd, section, value) 100060484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 100133965Sjdp struct bfd_link_hash_entry *h; 100233965Sjdp bfd_reloc_code_real_type reloc; 100333965Sjdp bfd *abfd; 100433965Sjdp asection *section; 100533965Sjdp bfd_vma value; 100633965Sjdp{ 100733965Sjdp if (config.warn_constructors) 100860484Sobrien einfo (_("%P: warning: global constructor %s used\n"), 100933965Sjdp h->root.string); 101033965Sjdp 101133965Sjdp if (! config.build_constructors) 101233965Sjdp return true; 101333965Sjdp 101433965Sjdp ldctor_add_set_entry (h, reloc, (const char *) NULL, section, value); 101533965Sjdp 101633965Sjdp if (h->type == bfd_link_hash_new) 101733965Sjdp { 101833965Sjdp h->type = bfd_link_hash_undefined; 101933965Sjdp h->u.undef.abfd = abfd; 102033965Sjdp /* We don't call bfd_link_add_undef to add this to the list of 102133965Sjdp undefined symbols because we are going to define it 102233965Sjdp ourselves. */ 102333965Sjdp } 102433965Sjdp 102533965Sjdp return true; 102633965Sjdp} 102733965Sjdp 102833965Sjdp/* This is called when BFD has discovered a constructor. This is only 102933965Sjdp called for some object file formats--those which do not handle 103033965Sjdp constructors in some more clever fashion. This is similar to 103133965Sjdp adding an element to a set, but less general. */ 103233965Sjdp 103333965Sjdpstatic boolean 103433965Sjdpconstructor_callback (info, constructor, name, abfd, section, value) 103533965Sjdp struct bfd_link_info *info; 103633965Sjdp boolean constructor; 103733965Sjdp const char *name; 103833965Sjdp bfd *abfd; 103933965Sjdp asection *section; 104033965Sjdp bfd_vma value; 104133965Sjdp{ 104233965Sjdp char *s; 104333965Sjdp struct bfd_link_hash_entry *h; 104433965Sjdp char set_name[1 + sizeof "__CTOR_LIST__"]; 104533965Sjdp 104633965Sjdp if (config.warn_constructors) 104760484Sobrien einfo (_("%P: warning: global constructor %s used\n"), name); 104833965Sjdp 104933965Sjdp if (! config.build_constructors) 105033965Sjdp return true; 105133965Sjdp 105233965Sjdp /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a 105333965Sjdp useful error message. */ 105433965Sjdp if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL 105533965Sjdp && (link_info.relocateable 105633965Sjdp || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL)) 105760484Sobrien einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n")); 105833965Sjdp 105933965Sjdp s = set_name; 106033965Sjdp if (bfd_get_symbol_leading_char (abfd) != '\0') 106133965Sjdp *s++ = bfd_get_symbol_leading_char (abfd); 106233965Sjdp if (constructor) 106333965Sjdp strcpy (s, "__CTOR_LIST__"); 106433965Sjdp else 106533965Sjdp strcpy (s, "__DTOR_LIST__"); 106633965Sjdp 106733965Sjdp h = bfd_link_hash_lookup (info->hash, set_name, true, true, true); 106833965Sjdp if (h == (struct bfd_link_hash_entry *) NULL) 106960484Sobrien einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); 107033965Sjdp if (h->type == bfd_link_hash_new) 107133965Sjdp { 107233965Sjdp h->type = bfd_link_hash_undefined; 107333965Sjdp h->u.undef.abfd = abfd; 107433965Sjdp /* We don't call bfd_link_add_undef to add this to the list of 107533965Sjdp undefined symbols because we are going to define it 107633965Sjdp ourselves. */ 107733965Sjdp } 107833965Sjdp 107933965Sjdp ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value); 108033965Sjdp return true; 108133965Sjdp} 108233965Sjdp 108333965Sjdp/* A structure used by warning_callback to pass information through 108433965Sjdp bfd_map_over_sections. */ 108533965Sjdp 108677298Sobrienstruct warning_callback_info { 108733965Sjdp boolean found; 108833965Sjdp const char *warning; 108933965Sjdp const char *symbol; 109033965Sjdp asymbol **asymbols; 109133965Sjdp}; 109233965Sjdp 109333965Sjdp/* This is called when there is a reference to a warning symbol. */ 109433965Sjdp 109533965Sjdpstatic boolean 109633965Sjdpwarning_callback (info, warning, symbol, abfd, section, address) 109760484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 109833965Sjdp const char *warning; 109933965Sjdp const char *symbol; 110033965Sjdp bfd *abfd; 110133965Sjdp asection *section; 110233965Sjdp bfd_vma address; 110333965Sjdp{ 110433965Sjdp /* This is a hack to support warn_multiple_gp. FIXME: This should 110533965Sjdp have a cleaner interface, but what? */ 110633965Sjdp if (! config.warn_multiple_gp 110733965Sjdp && strcmp (warning, "using multiple gp values") == 0) 110833965Sjdp return true; 110933965Sjdp 111033965Sjdp if (section != NULL) 111133965Sjdp einfo ("%C: %s\n", abfd, section, address, warning); 111233965Sjdp else if (abfd == NULL) 111333965Sjdp einfo ("%P: %s\n", warning); 111433965Sjdp else if (symbol == NULL) 111533965Sjdp einfo ("%B: %s\n", abfd, warning); 111633965Sjdp else 111733965Sjdp { 111833965Sjdp lang_input_statement_type *entry; 111933965Sjdp asymbol **asymbols; 112033965Sjdp struct warning_callback_info info; 112133965Sjdp 112233965Sjdp /* Look through the relocs to see if we can find a plausible 112333965Sjdp address. */ 112433965Sjdp 112533965Sjdp entry = (lang_input_statement_type *) abfd->usrdata; 112633965Sjdp if (entry != NULL && entry->asymbols != NULL) 112733965Sjdp asymbols = entry->asymbols; 112833965Sjdp else 112933965Sjdp { 113033965Sjdp long symsize; 113133965Sjdp long symbol_count; 113233965Sjdp 113333965Sjdp symsize = bfd_get_symtab_upper_bound (abfd); 113433965Sjdp if (symsize < 0) 113560484Sobrien einfo (_("%B%F: could not read symbols: %E\n"), abfd); 113633965Sjdp asymbols = (asymbol **) xmalloc (symsize); 113733965Sjdp symbol_count = bfd_canonicalize_symtab (abfd, asymbols); 113833965Sjdp if (symbol_count < 0) 113960484Sobrien einfo (_("%B%F: could not read symbols: %E\n"), abfd); 114033965Sjdp if (entry != NULL) 114133965Sjdp { 114233965Sjdp entry->asymbols = asymbols; 114333965Sjdp entry->symbol_count = symbol_count; 114433965Sjdp } 114533965Sjdp } 114633965Sjdp 114733965Sjdp info.found = false; 114833965Sjdp info.warning = warning; 114933965Sjdp info.symbol = symbol; 115033965Sjdp info.asymbols = asymbols; 115133965Sjdp bfd_map_over_sections (abfd, warning_find_reloc, (PTR) &info); 115233965Sjdp 115333965Sjdp if (! info.found) 115433965Sjdp einfo ("%B: %s\n", abfd, warning); 115533965Sjdp 115633965Sjdp if (entry == NULL) 115733965Sjdp free (asymbols); 115833965Sjdp } 115933965Sjdp 116033965Sjdp return true; 116133965Sjdp} 116233965Sjdp 116333965Sjdp/* This is called by warning_callback for each section. It checks the 116433965Sjdp relocs of the section to see if it can find a reference to the 116533965Sjdp symbol which triggered the warning. If it can, it uses the reloc 116633965Sjdp to give an error message with a file and line number. */ 116733965Sjdp 116833965Sjdpstatic void 116933965Sjdpwarning_find_reloc (abfd, sec, iarg) 117033965Sjdp bfd *abfd; 117133965Sjdp asection *sec; 117233965Sjdp PTR iarg; 117333965Sjdp{ 117433965Sjdp struct warning_callback_info *info = (struct warning_callback_info *) iarg; 117533965Sjdp long relsize; 117633965Sjdp arelent **relpp; 117733965Sjdp long relcount; 117833965Sjdp arelent **p, **pend; 117933965Sjdp 118033965Sjdp if (info->found) 118133965Sjdp return; 118233965Sjdp 118333965Sjdp relsize = bfd_get_reloc_upper_bound (abfd, sec); 118433965Sjdp if (relsize < 0) 118560484Sobrien einfo (_("%B%F: could not read relocs: %E\n"), abfd); 118633965Sjdp if (relsize == 0) 118733965Sjdp return; 118833965Sjdp 118933965Sjdp relpp = (arelent **) xmalloc (relsize); 119033965Sjdp relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols); 119133965Sjdp if (relcount < 0) 119260484Sobrien einfo (_("%B%F: could not read relocs: %E\n"), abfd); 119333965Sjdp 119433965Sjdp p = relpp; 119533965Sjdp pend = p + relcount; 119633965Sjdp for (; p < pend && *p != NULL; p++) 119733965Sjdp { 119833965Sjdp arelent *q = *p; 119933965Sjdp 120033965Sjdp if (q->sym_ptr_ptr != NULL 120133965Sjdp && *q->sym_ptr_ptr != NULL 120233965Sjdp && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0) 120333965Sjdp { 120433965Sjdp /* We found a reloc for the symbol we are looking for. */ 120533965Sjdp einfo ("%C: %s\n", abfd, sec, q->address, info->warning); 120633965Sjdp info->found = true; 120733965Sjdp break; 120833965Sjdp } 120933965Sjdp } 121033965Sjdp 121133965Sjdp free (relpp); 121233965Sjdp} 121333965Sjdp 121433965Sjdp/* This is called when an undefined symbol is found. */ 121533965Sjdp 121633965Sjdpstatic boolean 121760484Sobrienundefined_symbol (info, name, abfd, section, address, fatal) 121860484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 121933965Sjdp const char *name; 122033965Sjdp bfd *abfd; 122133965Sjdp asection *section; 122233965Sjdp bfd_vma address; 122377298Sobrien boolean fatal ATTRIBUTE_UNUSED; 122433965Sjdp{ 122533965Sjdp static char *error_name; 122633965Sjdp static unsigned int error_count; 122733965Sjdp 122833965Sjdp#define MAX_ERRORS_IN_A_ROW 5 122933965Sjdp 123033965Sjdp if (config.warn_once) 123133965Sjdp { 123233965Sjdp static struct bfd_hash_table *hash; 123333965Sjdp 123433965Sjdp /* Only warn once about a particular undefined symbol. */ 123533965Sjdp 123633965Sjdp if (hash == NULL) 123733965Sjdp { 123833965Sjdp hash = ((struct bfd_hash_table *) 123933965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 124033965Sjdp if (! bfd_hash_table_init (hash, bfd_hash_newfunc)) 124160484Sobrien einfo (_("%F%P: bfd_hash_table_init failed: %E\n")); 124233965Sjdp } 124333965Sjdp 124433965Sjdp if (bfd_hash_lookup (hash, name, false, false) != NULL) 124533965Sjdp return true; 124633965Sjdp 124733965Sjdp if (bfd_hash_lookup (hash, name, true, true) == NULL) 124860484Sobrien einfo (_("%F%P: bfd_hash_lookup failed: %E\n")); 124933965Sjdp } 125033965Sjdp 125133965Sjdp /* We never print more than a reasonable number of errors in a row 125233965Sjdp for a single symbol. */ 125333965Sjdp if (error_name != (char *) NULL 125433965Sjdp && strcmp (name, error_name) == 0) 125533965Sjdp ++error_count; 125633965Sjdp else 125733965Sjdp { 125833965Sjdp error_count = 0; 125933965Sjdp if (error_name != (char *) NULL) 126033965Sjdp free (error_name); 126178828Sobrien error_name = xstrdup (name); 126233965Sjdp } 126333965Sjdp 126433965Sjdp if (section != NULL) 126533965Sjdp { 126633965Sjdp if (error_count < MAX_ERRORS_IN_A_ROW) 126760484Sobrien { 126860484Sobrien einfo (_("%C: undefined reference to `%T'\n"), 126960484Sobrien abfd, section, address, name); 127060484Sobrien if (fatal) 127160484Sobrien einfo ("%X"); 127260484Sobrien } 127333965Sjdp else if (error_count == MAX_ERRORS_IN_A_ROW) 127460484Sobrien einfo (_("%D: more undefined references to `%T' follow\n"), 127533965Sjdp abfd, section, address, name); 127633965Sjdp } 127733965Sjdp else 127833965Sjdp { 127933965Sjdp if (error_count < MAX_ERRORS_IN_A_ROW) 128060484Sobrien { 128160484Sobrien einfo (_("%B: undefined reference to `%T'\n"), 128260484Sobrien abfd, name); 128360484Sobrien if (fatal) 128460484Sobrien einfo ("%X"); 128560484Sobrien } 128633965Sjdp else if (error_count == MAX_ERRORS_IN_A_ROW) 128760484Sobrien einfo (_("%B: more undefined references to `%T' follow\n"), 128833965Sjdp abfd, name); 128933965Sjdp } 129033965Sjdp 129133965Sjdp return true; 129233965Sjdp} 129333965Sjdp 129433965Sjdp/* This is called when a reloc overflows. */ 129533965Sjdp 129633965Sjdpstatic boolean 129733965Sjdpreloc_overflow (info, name, reloc_name, addend, abfd, section, address) 129860484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 129933965Sjdp const char *name; 130033965Sjdp const char *reloc_name; 130133965Sjdp bfd_vma addend; 130233965Sjdp bfd *abfd; 130333965Sjdp asection *section; 130433965Sjdp bfd_vma address; 130533965Sjdp{ 130633965Sjdp if (abfd == (bfd *) NULL) 130760484Sobrien einfo (_("%P%X: generated")); 130833965Sjdp else 130933965Sjdp einfo ("%X%C:", abfd, section, address); 131060484Sobrien einfo (_(" relocation truncated to fit: %s %T"), reloc_name, name); 131133965Sjdp if (addend != 0) 131233965Sjdp einfo ("+%v", addend); 131333965Sjdp einfo ("\n"); 131433965Sjdp return true; 131533965Sjdp} 131633965Sjdp 131733965Sjdp/* This is called when a dangerous relocation is made. */ 131833965Sjdp 131933965Sjdpstatic boolean 132033965Sjdpreloc_dangerous (info, message, abfd, section, address) 132160484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 132233965Sjdp const char *message; 132333965Sjdp bfd *abfd; 132433965Sjdp asection *section; 132533965Sjdp bfd_vma address; 132633965Sjdp{ 132733965Sjdp if (abfd == (bfd *) NULL) 132860484Sobrien einfo (_("%P%X: generated")); 132933965Sjdp else 133033965Sjdp einfo ("%X%C:", abfd, section, address); 133160484Sobrien einfo (_("dangerous relocation: %s\n"), message); 133233965Sjdp return true; 133333965Sjdp} 133433965Sjdp 133533965Sjdp/* This is called when a reloc is being generated attached to a symbol 133633965Sjdp that is not being output. */ 133733965Sjdp 133833965Sjdpstatic boolean 133933965Sjdpunattached_reloc (info, name, abfd, section, address) 134060484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 134133965Sjdp const char *name; 134233965Sjdp bfd *abfd; 134333965Sjdp asection *section; 134433965Sjdp bfd_vma address; 134533965Sjdp{ 134633965Sjdp if (abfd == (bfd *) NULL) 134760484Sobrien einfo (_("%P%X: generated")); 134833965Sjdp else 134933965Sjdp einfo ("%X%C:", abfd, section, address); 135060484Sobrien einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name); 135133965Sjdp return true; 135233965Sjdp} 135333965Sjdp 135433965Sjdp/* This is called if link_info.notice_all is set, or when a symbol in 135533965Sjdp link_info.notice_hash is found. Symbols are put in notice_hash 135633965Sjdp using the -y option. */ 135733965Sjdp 135833965Sjdpstatic boolean 135933965Sjdpnotice (info, name, abfd, section, value) 136033965Sjdp struct bfd_link_info *info; 136133965Sjdp const char *name; 136233965Sjdp bfd *abfd; 136333965Sjdp asection *section; 136433965Sjdp bfd_vma value; 136533965Sjdp{ 136633965Sjdp if (! info->notice_all 136733965Sjdp || (info->notice_hash != NULL 136833965Sjdp && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL)) 136960484Sobrien { 137060484Sobrien if (bfd_is_und_section (section)) 137160484Sobrien einfo ("%B: reference to %s\n", abfd, name); 137260484Sobrien else 137360484Sobrien einfo ("%B: definition of %s\n", abfd, name); 137460484Sobrien } 137533965Sjdp 137633965Sjdp if (command_line.cref || nocrossref_list != NULL) 137733965Sjdp add_cref (name, abfd, section, value); 137833965Sjdp 137933965Sjdp return true; 138033965Sjdp} 1381