ldmain.c revision 77298
133965Sjdp/* Main program of GNU linker. 261843Sobrien Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000 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> 2633965Sjdp#include <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 17260484Sobrien bindtextdomain (PACKAGE, LOCALEDIR); 17360484Sobrien textdomain (PACKAGE); 17460484Sobrien 17533965Sjdp program_name = argv[0]; 17633965Sjdp xmalloc_set_program_name (program_name); 17733965Sjdp 17833965Sjdp START_PROGRESS (program_name, 0); 17933965Sjdp 18033965Sjdp bfd_init (); 18133965Sjdp 18233965Sjdp bfd_set_error_program_name (program_name); 18333965Sjdp 18433965Sjdp xatexit (remove_output); 18533965Sjdp 18633965Sjdp /* Set the default BFD target based on the configured target. Doing 18733965Sjdp this permits the linker to be configured for a particular target, 18833965Sjdp and linked against a shared BFD library which was configured for 18933965Sjdp a different target. The macro TARGET is defined by Makefile. */ 19033965Sjdp if (! bfd_set_default_target (TARGET)) 19133965Sjdp { 19260484Sobrien einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET); 19333965Sjdp xexit (1); 19433965Sjdp } 19533965Sjdp 19633965Sjdp /* Initialize the data about options. */ 19733965Sjdp trace_files = trace_file_tries = version_printed = false; 19833965Sjdp whole_archive = false; 19933965Sjdp config.build_constructors = true; 20033965Sjdp config.dynamic_link = false; 20160484Sobrien config.has_shared = false; 20277298Sobrien config.split_by_reloc = (unsigned) -1; 20377298Sobrien config.split_by_file = (bfd_size_type) -1; 20433965Sjdp command_line.force_common_definition = false; 20533965Sjdp command_line.interpreter = NULL; 20633965Sjdp command_line.rpath = NULL; 20738889Sjdp command_line.warn_mismatch = true; 20860484Sobrien command_line.check_section_addresses = true; 20933965Sjdp 21060484Sobrien /* We initialize DEMANGLING based on the environment variable 21160484Sobrien COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the 21260484Sobrien output of the linker, unless COLLECT_NO_DEMANGLE is set in the 21360484Sobrien environment. Acting the same way here lets us provide the same 21460484Sobrien interface by default. */ 21560484Sobrien demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL; 21660484Sobrien 21733965Sjdp link_info.callbacks = &link_callbacks; 21833965Sjdp link_info.relocateable = false; 21977298Sobrien link_info.emitrelocations = false; 22033965Sjdp link_info.shared = false; 22133965Sjdp link_info.symbolic = false; 22233965Sjdp link_info.static_link = false; 22333965Sjdp link_info.traditional_format = false; 22460484Sobrien link_info.optimize = false; 22560484Sobrien link_info.no_undefined = false; 22677298Sobrien link_info.allow_shlib_undefined = false; 22733965Sjdp link_info.strip = strip_none; 22833965Sjdp link_info.discard = discard_none; 22933965Sjdp link_info.keep_memory = true; 23033965Sjdp link_info.input_bfds = NULL; 23133965Sjdp link_info.create_object_symbols_section = NULL; 23233965Sjdp link_info.hash = NULL; 23333965Sjdp link_info.keep_hash = NULL; 23433965Sjdp link_info.notice_all = false; 23533965Sjdp link_info.notice_hash = NULL; 23633965Sjdp link_info.wrap_hash = NULL; 23760484Sobrien link_info.mpc860c0 = 0; 23860484Sobrien /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init 23960484Sobrien and _fini symbols. We are compatible. */ 24060484Sobrien link_info.init_function = "_init"; 24160484Sobrien link_info.fini_function = "_fini"; 24277298Sobrien link_info.new_dtags = false; 24377298Sobrien link_info.flags = (bfd_vma) 0; 24477298Sobrien link_info.flags_1 = (bfd_vma) 0; 24560484Sobrien 24633965Sjdp ldfile_add_arch (""); 24733965Sjdp 24833965Sjdp config.make_executable = true; 24933965Sjdp force_make_executable = false; 25033965Sjdp config.magic_demand_paged = true; 25133965Sjdp config.text_read_only = true; 25233965Sjdp 25333965Sjdp emulation = get_emulation (argc, argv); 25433965Sjdp ldemul_choose_mode (emulation); 25533965Sjdp default_target = ldemul_choose_target (); 25633965Sjdp lang_init (); 25733965Sjdp ldemul_before_parse (); 25833965Sjdp lang_has_input_file = false; 25933965Sjdp parse_args (argc, argv); 26033965Sjdp 26133965Sjdp ldemul_set_symbols (); 26233965Sjdp 26333965Sjdp if (link_info.relocateable) 26433965Sjdp { 26560484Sobrien if (command_line.gc_sections) 26660484Sobrien einfo ("%P%F: --gc-sections and -r may not be used together\n"); 26760484Sobrien if (link_info.mpc860c0) 26860484Sobrien einfo (_("%P%F: -r and --mpc860c0 may not be used together\n")); 26960484Sobrien else if (command_line.relax) 27060484Sobrien einfo (_("%P%F: --relax and -r may not be used together\n")); 27133965Sjdp if (link_info.shared) 27260484Sobrien einfo (_("%P%F: -r and -shared may not be used together\n")); 27333965Sjdp } 27433965Sjdp 27533965Sjdp /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I 27633965Sjdp don't see how else this can be handled, since in this case we 27733965Sjdp must preserve all externally visible symbols. */ 27833965Sjdp if (link_info.relocateable && link_info.strip == strip_all) 27933965Sjdp { 28033965Sjdp link_info.strip = strip_debugger; 28133965Sjdp if (link_info.discard == discard_none) 28233965Sjdp link_info.discard = discard_all; 28333965Sjdp } 28433965Sjdp 28533965Sjdp /* This essentially adds another -L directory so this must be done after 28633965Sjdp the -L's in argv have been processed. */ 28733965Sjdp set_scripts_dir (); 28833965Sjdp 28933965Sjdp if (had_script == false) 29033965Sjdp { 29133965Sjdp /* Read the emulation's appropriate default script. */ 29233965Sjdp int isfile; 29333965Sjdp char *s = ldemul_get_script (&isfile); 29433965Sjdp 29533965Sjdp if (isfile) 29633965Sjdp ldfile_open_command_file (s); 29733965Sjdp else 29833965Sjdp { 29933965Sjdp if (trace_file_tries) 30033965Sjdp { 30160484Sobrien info_msg (_("using internal linker script:\n")); 30233965Sjdp info_msg ("==================================================\n"); 30333965Sjdp info_msg (s); 30433965Sjdp info_msg ("\n==================================================\n"); 30533965Sjdp } 30633965Sjdp lex_string = s; 30733965Sjdp lex_redirect (s); 30833965Sjdp } 30933965Sjdp parser_input = input_script; 31033965Sjdp yyparse (); 31133965Sjdp lex_string = NULL; 31233965Sjdp } 31333965Sjdp 31433965Sjdp lang_final (); 31533965Sjdp 31633965Sjdp if (lang_has_input_file == false) 31733965Sjdp { 31833965Sjdp if (version_printed) 31933965Sjdp xexit (0); 32060484Sobrien einfo (_("%P%F: no input files\n")); 32133965Sjdp } 32233965Sjdp 32333965Sjdp if (trace_files) 32433965Sjdp { 32560484Sobrien info_msg (_("%P: mode %s\n"), emulation); 32633965Sjdp } 32733965Sjdp 32833965Sjdp ldemul_after_parse (); 32933965Sjdp 33033965Sjdp if (config.map_filename) 33133965Sjdp { 33233965Sjdp if (strcmp (config.map_filename, "-") == 0) 33333965Sjdp { 33433965Sjdp config.map_file = stdout; 33533965Sjdp } 33633965Sjdp else 33733965Sjdp { 33833965Sjdp config.map_file = fopen (config.map_filename, FOPEN_WT); 33933965Sjdp if (config.map_file == (FILE *) NULL) 34033965Sjdp { 34133965Sjdp bfd_set_error (bfd_error_system_call); 34260484Sobrien einfo (_("%P%F: cannot open map file %s: %E\n"), 34333965Sjdp config.map_filename); 34433965Sjdp } 34533965Sjdp } 34633965Sjdp } 34733965Sjdp 34833965Sjdp lang_process (); 34933965Sjdp 35033965Sjdp /* Print error messages for any missing symbols, for any warning 35177298Sobrien symbols, and possibly multiple definitions. */ 35233965Sjdp 35377298Sobrien if (! link_info.relocateable) 35433965Sjdp { 35577298Sobrien /* Look for a text section and switch the readonly attribute in it. */ 35633965Sjdp asection *found = bfd_get_section_by_name (output_bfd, ".text"); 35733965Sjdp 35833965Sjdp if (found != (asection *) NULL) 35933965Sjdp { 36077298Sobrien if (config.text_read_only) 36177298Sobrien found->flags |= SEC_READONLY; 36277298Sobrien else 36377298Sobrien found->flags &= ~SEC_READONLY; 36433965Sjdp } 36533965Sjdp } 36633965Sjdp 36733965Sjdp if (link_info.relocateable) 36833965Sjdp output_bfd->flags &= ~EXEC_P; 36933965Sjdp else 37033965Sjdp output_bfd->flags |= EXEC_P; 37133965Sjdp 37233965Sjdp ldwrite (); 37333965Sjdp 37433965Sjdp if (config.map_file != NULL) 37533965Sjdp lang_map (); 37633965Sjdp if (command_line.cref) 37733965Sjdp output_cref (config.map_file != NULL ? config.map_file : stdout); 37833965Sjdp if (nocrossref_list != NULL) 37933965Sjdp check_nocrossrefs (); 38033965Sjdp 38133965Sjdp /* Even if we're producing relocateable output, some non-fatal errors should 38233965Sjdp be reported in the exit status. (What non-fatal errors, if any, do we 38333965Sjdp want to ignore for relocateable output?) */ 38433965Sjdp 38533965Sjdp if (config.make_executable == false && force_make_executable == false) 38633965Sjdp { 38733965Sjdp if (trace_files == true) 38833965Sjdp { 38960484Sobrien einfo (_("%P: link errors found, deleting executable `%s'\n"), 39033965Sjdp output_filename); 39133965Sjdp } 39233965Sjdp 39333965Sjdp /* The file will be removed by remove_output. */ 39433965Sjdp 39533965Sjdp xexit (1); 39633965Sjdp } 39733965Sjdp else 39833965Sjdp { 39933965Sjdp if (! bfd_close (output_bfd)) 40060484Sobrien einfo (_("%F%B: final close failed: %E\n"), output_bfd); 40133965Sjdp 40233965Sjdp /* If the --force-exe-suffix is enabled, and we're making an 40377298Sobrien executable file and it doesn't end in .exe, copy it to one 40477298Sobrien which does. */ 40533965Sjdp if (! link_info.relocateable && command_line.force_exe_suffix) 40633965Sjdp { 40733965Sjdp int len = strlen (output_filename); 40877298Sobrien if (len < 4 40933965Sjdp || (strcasecmp (output_filename + len - 4, ".exe") != 0 41033965Sjdp && strcasecmp (output_filename + len - 4, ".dll") != 0)) 41133965Sjdp { 41233965Sjdp FILE *src; 41333965Sjdp FILE *dst; 41433965Sjdp const int bsize = 4096; 41533965Sjdp char *buf = xmalloc (bsize); 41633965Sjdp int l; 41733965Sjdp char *dst_name = xmalloc (len + 5); 41833965Sjdp strcpy (dst_name, output_filename); 41933965Sjdp strcat (dst_name, ".exe"); 42033965Sjdp src = fopen (output_filename, FOPEN_RB); 42133965Sjdp dst = fopen (dst_name, FOPEN_WB); 42233965Sjdp 42333965Sjdp if (!src) 42460484Sobrien einfo (_("%X%P: unable to open for source of copy `%s'\n"), output_filename); 42533965Sjdp if (!dst) 42660484Sobrien einfo (_("%X%P: unable to open for destination of copy `%s'\n"), dst_name); 42733965Sjdp while ((l = fread (buf, 1, bsize, src)) > 0) 42833965Sjdp { 42933965Sjdp int done = fwrite (buf, 1, l, dst); 43033965Sjdp if (done != l) 43133965Sjdp { 43260484Sobrien einfo (_("%P: Error writing file `%s'\n"), dst_name); 43333965Sjdp } 43433965Sjdp } 43533965Sjdp fclose (src); 43633965Sjdp if (fclose (dst) == EOF) 43733965Sjdp { 43860484Sobrien einfo (_("%P: Error closing file `%s'\n"), dst_name); 43933965Sjdp } 44033965Sjdp free (dst_name); 44133965Sjdp free (buf); 44233965Sjdp } 44333965Sjdp } 44433965Sjdp } 44533965Sjdp 44633965Sjdp END_PROGRESS (program_name); 44733965Sjdp 44833965Sjdp if (config.stats) 44933965Sjdp { 45033965Sjdp#ifdef HAVE_SBRK 45133965Sjdp char *lim = (char *) sbrk (0); 45233965Sjdp#endif 45333965Sjdp long run_time = get_run_time () - start_time; 45433965Sjdp 45560484Sobrien fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"), 45633965Sjdp program_name, run_time / 1000000, run_time % 1000000); 45733965Sjdp#ifdef HAVE_SBRK 45860484Sobrien fprintf (stderr, _("%s: data size %ld\n"), program_name, 45933965Sjdp (long) (lim - (char *) &environ)); 46033965Sjdp#endif 46133965Sjdp } 46233965Sjdp 46333965Sjdp /* Prevent remove_output from doing anything, after a successful link. */ 46433965Sjdp output_filename = NULL; 46533965Sjdp 46633965Sjdp xexit (0); 46733965Sjdp return 0; 46833965Sjdp} 46933965Sjdp 47033965Sjdp/* We need to find any explicitly given emulation in order to initialize the 47133965Sjdp state that's needed by the lex&yacc argument parser (parse_args). */ 47233965Sjdp 47333965Sjdpstatic char * 47433965Sjdpget_emulation (argc, argv) 47533965Sjdp int argc; 47633965Sjdp char **argv; 47733965Sjdp{ 47833965Sjdp char *emulation; 47933965Sjdp int i; 48033965Sjdp 48133965Sjdp emulation = getenv (EMULATION_ENVIRON); 48233965Sjdp if (emulation == NULL) 48333965Sjdp emulation = DEFAULT_EMULATION; 48433965Sjdp 48533965Sjdp for (i = 1; i < argc; i++) 48633965Sjdp { 48733965Sjdp if (!strncmp (argv[i], "-m", 2)) 48833965Sjdp { 48933965Sjdp if (argv[i][2] == '\0') 49033965Sjdp { 49133965Sjdp /* -m EMUL */ 49233965Sjdp if (i < argc - 1) 49333965Sjdp { 49433965Sjdp emulation = argv[i + 1]; 49533965Sjdp i++; 49633965Sjdp } 49733965Sjdp else 49833965Sjdp { 49977298Sobrien einfo (_("%P%F: missing argument to -m\n")); 50033965Sjdp } 50133965Sjdp } 50233965Sjdp else if (strcmp (argv[i], "-mips1") == 0 50333965Sjdp || strcmp (argv[i], "-mips2") == 0 50433965Sjdp || strcmp (argv[i], "-mips3") == 0 50533965Sjdp || strcmp (argv[i], "-mips4") == 0) 50633965Sjdp { 50733965Sjdp /* FIXME: The arguments -mips1, -mips2 and -mips3 are 50833965Sjdp passed to the linker by some MIPS compilers. They 50933965Sjdp generally tell the linker to use a slightly different 51033965Sjdp library path. Perhaps someday these should be 51133965Sjdp implemented as emulations; until then, we just ignore 51233965Sjdp the arguments and hope that nobody ever creates 51333965Sjdp emulations named ips1, ips2 or ips3. */ 51433965Sjdp } 51533965Sjdp else if (strcmp (argv[i], "-m486") == 0) 51633965Sjdp { 51733965Sjdp /* FIXME: The argument -m486 is passed to the linker on 51833965Sjdp some Linux systems. Hope that nobody creates an 51933965Sjdp emulation named 486. */ 52033965Sjdp } 52133965Sjdp else 52233965Sjdp { 52333965Sjdp /* -mEMUL */ 52433965Sjdp emulation = &argv[i][2]; 52533965Sjdp } 52633965Sjdp } 52733965Sjdp } 52833965Sjdp 52933965Sjdp return emulation; 53033965Sjdp} 53133965Sjdp 53233965Sjdp/* If directory DIR contains an "ldscripts" subdirectory, 53333965Sjdp add DIR to the library search path and return true, 53433965Sjdp else return false. */ 53533965Sjdp 53633965Sjdpstatic boolean 53733965Sjdpcheck_for_scripts_dir (dir) 53833965Sjdp char *dir; 53933965Sjdp{ 54033965Sjdp size_t dirlen; 54133965Sjdp char *buf; 54233965Sjdp struct stat s; 54333965Sjdp boolean res; 54433965Sjdp 54533965Sjdp dirlen = strlen (dir); 54633965Sjdp /* sizeof counts the terminating NUL. */ 54777298Sobrien buf = (char *) xmalloc (dirlen + sizeof ("/ldscripts")); 54833965Sjdp sprintf (buf, "%s/ldscripts", dir); 54933965Sjdp 55033965Sjdp res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode); 55133965Sjdp free (buf); 55233965Sjdp if (res) 55333965Sjdp ldfile_add_library_path (dir, false); 55433965Sjdp return res; 55533965Sjdp} 55633965Sjdp 55733965Sjdp/* Set the default directory for finding script files. 55833965Sjdp Libraries will be searched for here too, but that's ok. 55933965Sjdp We look for the "ldscripts" directory in: 56033965Sjdp 56133965Sjdp SCRIPTDIR (passed from Makefile) 56233965Sjdp the dir where this program is (for using it from the build tree) 56333965Sjdp the dir where this program is/../lib (for installing the tool suite elsewhere) */ 56433965Sjdp 56533965Sjdpstatic void 56633965Sjdpset_scripts_dir () 56733965Sjdp{ 56833965Sjdp char *end, *dir; 56933965Sjdp size_t dirlen; 57033965Sjdp 57133965Sjdp if (check_for_scripts_dir (SCRIPTDIR)) 57277298Sobrien /* We've been installed normally. */ 57377298Sobrien return; 57433965Sjdp 57533965Sjdp /* Look for "ldscripts" in the dir where our binary is. */ 57633965Sjdp end = strrchr (program_name, '/'); 57761843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 57861843Sobrien { 57961843Sobrien /* We could have \foo\bar, or /foo\bar. */ 58061843Sobrien char *bslash = strrchr (program_name, '\\'); 58177298Sobrien if (end == NULL || (bslash != NULL && bslash > end)) 58261843Sobrien end = bslash; 58361843Sobrien } 58461843Sobrien#endif 58533965Sjdp 58633965Sjdp if (end == NULL) 58733965Sjdp { 58833965Sjdp /* Don't look for ldscripts in the current directory. There is 58933965Sjdp too much potential for confusion. */ 59033965Sjdp return; 59133965Sjdp } 59233965Sjdp 59333965Sjdp dirlen = end - program_name; 59433965Sjdp /* Make a copy of program_name in dir. 59533965Sjdp Leave room for later "/../lib". */ 59633965Sjdp dir = (char *) xmalloc (dirlen + 8); 59733965Sjdp strncpy (dir, program_name, dirlen); 59833965Sjdp dir[dirlen] = '\0'; 59933965Sjdp 60033965Sjdp if (check_for_scripts_dir (dir)) 60177298Sobrien /* Don't free dir. */ 60277298Sobrien return; 60333965Sjdp 60433965Sjdp /* Look for "ldscripts" in <the dir where our binary is>/../lib. */ 60533965Sjdp strcpy (dir + dirlen, "/../lib"); 60633965Sjdp if (check_for_scripts_dir (dir)) 60733965Sjdp return; 60833965Sjdp 60977298Sobrien /* Well, we tried. */ 61077298Sobrien free (dir); 61133965Sjdp} 61233965Sjdp 61333965Sjdpvoid 61433965Sjdpadd_ysym (name) 61533965Sjdp const char *name; 61633965Sjdp{ 61733965Sjdp if (link_info.notice_hash == (struct bfd_hash_table *) NULL) 61833965Sjdp { 61933965Sjdp link_info.notice_hash = ((struct bfd_hash_table *) 62033965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 62133965Sjdp if (! bfd_hash_table_init_n (link_info.notice_hash, 62233965Sjdp bfd_hash_newfunc, 62333965Sjdp 61)) 62460484Sobrien einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); 62577298Sobrien } 62633965Sjdp 62733965Sjdp if (bfd_hash_lookup (link_info.notice_hash, name, true, true) 62833965Sjdp == (struct bfd_hash_entry *) NULL) 62960484Sobrien einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); 63033965Sjdp} 63133965Sjdp 63233965Sjdp/* Record a symbol to be wrapped, from the --wrap option. */ 63333965Sjdp 63433965Sjdpvoid 63533965Sjdpadd_wrap (name) 63633965Sjdp const char *name; 63733965Sjdp{ 63833965Sjdp if (link_info.wrap_hash == NULL) 63933965Sjdp { 64033965Sjdp link_info.wrap_hash = ((struct bfd_hash_table *) 64133965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 64233965Sjdp if (! bfd_hash_table_init_n (link_info.wrap_hash, 64333965Sjdp bfd_hash_newfunc, 64433965Sjdp 61)) 64560484Sobrien einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); 64633965Sjdp } 64733965Sjdp if (bfd_hash_lookup (link_info.wrap_hash, name, true, true) == NULL) 64860484Sobrien einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); 64933965Sjdp} 65033965Sjdp 65133965Sjdp/* Handle the -retain-symbols-file option. */ 65233965Sjdp 65333965Sjdpvoid 65433965Sjdpadd_keepsyms_file (filename) 65533965Sjdp const char *filename; 65633965Sjdp{ 65733965Sjdp FILE *file; 65833965Sjdp char *buf; 65933965Sjdp size_t bufsize; 66033965Sjdp int c; 66133965Sjdp 66233965Sjdp if (link_info.strip == strip_some) 66360484Sobrien einfo (_("%X%P: error: duplicate retain-symbols-file\n")); 66433965Sjdp 66533965Sjdp file = fopen (filename, "r"); 66633965Sjdp if (file == (FILE *) NULL) 66733965Sjdp { 66833965Sjdp bfd_set_error (bfd_error_system_call); 66933965Sjdp einfo ("%X%P: %s: %E\n", filename); 67033965Sjdp return; 67133965Sjdp } 67233965Sjdp 67333965Sjdp link_info.keep_hash = ((struct bfd_hash_table *) 67433965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 67533965Sjdp if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc)) 67660484Sobrien einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); 67733965Sjdp 67833965Sjdp bufsize = 100; 67933965Sjdp buf = (char *) xmalloc (bufsize); 68033965Sjdp 68133965Sjdp c = getc (file); 68233965Sjdp while (c != EOF) 68333965Sjdp { 68433965Sjdp while (isspace (c)) 68533965Sjdp c = getc (file); 68633965Sjdp 68733965Sjdp if (c != EOF) 68833965Sjdp { 68933965Sjdp size_t len = 0; 69033965Sjdp 69133965Sjdp while (! isspace (c) && c != EOF) 69233965Sjdp { 69333965Sjdp buf[len] = c; 69433965Sjdp ++len; 69533965Sjdp if (len >= bufsize) 69633965Sjdp { 69733965Sjdp bufsize *= 2; 69833965Sjdp buf = xrealloc (buf, bufsize); 69933965Sjdp } 70033965Sjdp c = getc (file); 70133965Sjdp } 70233965Sjdp 70333965Sjdp buf[len] = '\0'; 70433965Sjdp 70533965Sjdp if (bfd_hash_lookup (link_info.keep_hash, buf, true, true) 70633965Sjdp == (struct bfd_hash_entry *) NULL) 70760484Sobrien einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n")); 70833965Sjdp } 70933965Sjdp } 71033965Sjdp 71133965Sjdp if (link_info.strip != strip_none) 71260484Sobrien einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n")); 71333965Sjdp 71433965Sjdp link_info.strip = strip_some; 71533965Sjdp} 71633965Sjdp 71733965Sjdp/* Callbacks from the BFD linker routines. */ 71833965Sjdp 71933965Sjdp/* This is called when BFD has decided to include an archive member in 72033965Sjdp a link. */ 72133965Sjdp 72233965Sjdpstatic boolean 72333965Sjdpadd_archive_element (info, abfd, name) 72460484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 72533965Sjdp bfd *abfd; 72633965Sjdp const char *name; 72733965Sjdp{ 72833965Sjdp lang_input_statement_type *input; 72933965Sjdp 73033965Sjdp input = ((lang_input_statement_type *) 73133965Sjdp xmalloc (sizeof (lang_input_statement_type))); 73233965Sjdp input->filename = abfd->filename; 73333965Sjdp input->local_sym_name = abfd->filename; 73433965Sjdp input->the_bfd = abfd; 73533965Sjdp input->asymbols = NULL; 73633965Sjdp input->next = NULL; 73733965Sjdp input->just_syms_flag = false; 73833965Sjdp input->loaded = false; 73933965Sjdp input->search_dirs_flag = false; 74033965Sjdp 74133965Sjdp /* FIXME: The following fields are not set: header.next, 74233965Sjdp header.type, closed, passive_position, symbol_count, 74333965Sjdp next_real_file, is_archive, target, real. This bit of code is 74433965Sjdp from the old decode_library_subfile function. I don't know 74533965Sjdp whether any of those fields matters. */ 74633965Sjdp 74733965Sjdp ldlang_add_file (input); 74833965Sjdp 74933965Sjdp if (config.map_file != (FILE *) NULL) 75033965Sjdp { 75133965Sjdp static boolean header_printed; 75233965Sjdp struct bfd_link_hash_entry *h; 75333965Sjdp bfd *from; 75433965Sjdp int len; 75533965Sjdp 75633965Sjdp h = bfd_link_hash_lookup (link_info.hash, name, false, false, true); 75733965Sjdp 75833965Sjdp if (h == NULL) 75933965Sjdp from = NULL; 76033965Sjdp else 76133965Sjdp { 76233965Sjdp switch (h->type) 76333965Sjdp { 76433965Sjdp default: 76533965Sjdp from = NULL; 76633965Sjdp break; 76733965Sjdp 76833965Sjdp case bfd_link_hash_defined: 76933965Sjdp case bfd_link_hash_defweak: 77033965Sjdp from = h->u.def.section->owner; 77133965Sjdp break; 77233965Sjdp 77333965Sjdp case bfd_link_hash_undefined: 77433965Sjdp case bfd_link_hash_undefweak: 77533965Sjdp from = h->u.undef.abfd; 77633965Sjdp break; 77733965Sjdp 77833965Sjdp case bfd_link_hash_common: 77933965Sjdp from = h->u.c.p->section->owner; 78033965Sjdp break; 78133965Sjdp } 78233965Sjdp } 78333965Sjdp 78433965Sjdp if (! header_printed) 78533965Sjdp { 78633965Sjdp char buf[100]; 78733965Sjdp 78860484Sobrien sprintf (buf, "%-29s %s\n\n", _("Archive member included"), 78960484Sobrien _("because of file (symbol)")); 79033965Sjdp minfo ("%s", buf); 79133965Sjdp header_printed = true; 79233965Sjdp } 79333965Sjdp 79433965Sjdp if (bfd_my_archive (abfd) == NULL) 79533965Sjdp { 79633965Sjdp minfo ("%s", bfd_get_filename (abfd)); 79733965Sjdp len = strlen (bfd_get_filename (abfd)); 79833965Sjdp } 79933965Sjdp else 80033965Sjdp { 80133965Sjdp minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)), 80233965Sjdp bfd_get_filename (abfd)); 80333965Sjdp len = (strlen (bfd_get_filename (bfd_my_archive (abfd))) 80433965Sjdp + strlen (bfd_get_filename (abfd)) 80533965Sjdp + 2); 80633965Sjdp } 80733965Sjdp 80833965Sjdp if (len >= 29) 80933965Sjdp { 81033965Sjdp print_nl (); 81133965Sjdp len = 0; 81233965Sjdp } 81333965Sjdp while (len < 30) 81433965Sjdp { 81533965Sjdp print_space (); 81633965Sjdp ++len; 81733965Sjdp } 81833965Sjdp 81933965Sjdp if (from != NULL) 82033965Sjdp minfo ("%B ", from); 82133965Sjdp if (h != NULL) 82233965Sjdp minfo ("(%T)\n", h->root.string); 82333965Sjdp else 82433965Sjdp minfo ("(%s)\n", name); 82533965Sjdp } 82633965Sjdp 82733965Sjdp if (trace_files || trace_file_tries) 82833965Sjdp info_msg ("%I\n", input); 82933965Sjdp 83033965Sjdp return true; 83133965Sjdp} 83233965Sjdp 83333965Sjdp/* This is called when BFD has discovered a symbol which is defined 83433965Sjdp multiple times. */ 83533965Sjdp 83633965Sjdpstatic boolean 83733965Sjdpmultiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval) 83860484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 83933965Sjdp const char *name; 84033965Sjdp bfd *obfd; 84133965Sjdp asection *osec; 84233965Sjdp bfd_vma oval; 84333965Sjdp bfd *nbfd; 84433965Sjdp asection *nsec; 84533965Sjdp bfd_vma nval; 84633965Sjdp{ 84733965Sjdp /* If either section has the output_section field set to 84833965Sjdp bfd_abs_section_ptr, it means that the section is being 84933965Sjdp discarded, and this is not really a multiple definition at all. 85033965Sjdp FIXME: It would be cleaner to somehow ignore symbols defined in 85133965Sjdp sections which are being discarded. */ 85233965Sjdp if ((osec->output_section != NULL 85333965Sjdp && ! bfd_is_abs_section (osec) 85433965Sjdp && bfd_is_abs_section (osec->output_section)) 85533965Sjdp || (nsec->output_section != NULL 85633965Sjdp && ! bfd_is_abs_section (nsec) 85733965Sjdp && bfd_is_abs_section (nsec->output_section))) 85833965Sjdp return true; 85933965Sjdp 86060484Sobrien einfo (_("%X%C: multiple definition of `%T'\n"), 86133965Sjdp nbfd, nsec, nval, name); 86233965Sjdp if (obfd != (bfd *) NULL) 86360484Sobrien einfo (_("%D: first defined here\n"), obfd, osec, oval); 86477298Sobrien 86577298Sobrien if (command_line.relax) 86677298Sobrien { 86777298Sobrien einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n")); 86877298Sobrien command_line.relax = 0; 86977298Sobrien } 87077298Sobrien 87133965Sjdp return true; 87233965Sjdp} 87333965Sjdp 87433965Sjdp/* This is called when there is a definition of a common symbol, or 87533965Sjdp when a common symbol is found for a symbol that is already defined, 87633965Sjdp or when two common symbols are found. We only do something if 87733965Sjdp -warn-common was used. */ 87833965Sjdp 87933965Sjdpstatic boolean 88033965Sjdpmultiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize) 88160484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 88233965Sjdp const char *name; 88333965Sjdp bfd *obfd; 88433965Sjdp enum bfd_link_hash_type otype; 88533965Sjdp bfd_vma osize; 88633965Sjdp bfd *nbfd; 88733965Sjdp enum bfd_link_hash_type ntype; 88833965Sjdp bfd_vma nsize; 88933965Sjdp{ 89033965Sjdp if (! config.warn_common) 89133965Sjdp return true; 89233965Sjdp 89333965Sjdp if (ntype == bfd_link_hash_defined 89433965Sjdp || ntype == bfd_link_hash_defweak 89533965Sjdp || ntype == bfd_link_hash_indirect) 89633965Sjdp { 89733965Sjdp ASSERT (otype == bfd_link_hash_common); 89860484Sobrien einfo (_("%B: warning: definition of `%T' overriding common\n"), 89933965Sjdp nbfd, name); 90033965Sjdp if (obfd != NULL) 90160484Sobrien einfo (_("%B: warning: common is here\n"), obfd); 90233965Sjdp } 90333965Sjdp else if (otype == bfd_link_hash_defined 90433965Sjdp || otype == bfd_link_hash_defweak 90533965Sjdp || otype == bfd_link_hash_indirect) 90633965Sjdp { 90733965Sjdp ASSERT (ntype == bfd_link_hash_common); 90860484Sobrien einfo (_("%B: warning: common of `%T' overridden by definition\n"), 90933965Sjdp nbfd, name); 91033965Sjdp if (obfd != NULL) 91160484Sobrien einfo (_("%B: warning: defined here\n"), obfd); 91233965Sjdp } 91333965Sjdp else 91433965Sjdp { 91533965Sjdp ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common); 91633965Sjdp if (osize > nsize) 91733965Sjdp { 91860484Sobrien einfo (_("%B: warning: common of `%T' overridden by larger common\n"), 91933965Sjdp nbfd, name); 92033965Sjdp if (obfd != NULL) 92160484Sobrien einfo (_("%B: warning: larger common is here\n"), obfd); 92233965Sjdp } 92333965Sjdp else if (nsize > osize) 92433965Sjdp { 92560484Sobrien einfo (_("%B: warning: common of `%T' overriding smaller common\n"), 92633965Sjdp nbfd, name); 92733965Sjdp if (obfd != NULL) 92860484Sobrien einfo (_("%B: warning: smaller common is here\n"), obfd); 92933965Sjdp } 93033965Sjdp else 93133965Sjdp { 93260484Sobrien einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name); 93333965Sjdp if (obfd != NULL) 93460484Sobrien einfo (_("%B: warning: previous common is here\n"), obfd); 93533965Sjdp } 93633965Sjdp } 93733965Sjdp 93833965Sjdp return true; 93933965Sjdp} 94033965Sjdp 94133965Sjdp/* This is called when BFD has discovered a set element. H is the 94233965Sjdp entry in the linker hash table for the set. SECTION and VALUE 94333965Sjdp represent a value which should be added to the set. */ 94433965Sjdp 94533965Sjdpstatic boolean 94633965Sjdpadd_to_set (info, h, reloc, abfd, section, value) 94760484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 94833965Sjdp struct bfd_link_hash_entry *h; 94933965Sjdp bfd_reloc_code_real_type reloc; 95033965Sjdp bfd *abfd; 95133965Sjdp asection *section; 95233965Sjdp bfd_vma value; 95333965Sjdp{ 95433965Sjdp if (config.warn_constructors) 95560484Sobrien einfo (_("%P: warning: global constructor %s used\n"), 95633965Sjdp h->root.string); 95733965Sjdp 95833965Sjdp if (! config.build_constructors) 95933965Sjdp return true; 96033965Sjdp 96133965Sjdp ldctor_add_set_entry (h, reloc, (const char *) NULL, section, value); 96233965Sjdp 96333965Sjdp if (h->type == bfd_link_hash_new) 96433965Sjdp { 96533965Sjdp h->type = bfd_link_hash_undefined; 96633965Sjdp h->u.undef.abfd = abfd; 96733965Sjdp /* We don't call bfd_link_add_undef to add this to the list of 96833965Sjdp undefined symbols because we are going to define it 96933965Sjdp ourselves. */ 97033965Sjdp } 97133965Sjdp 97233965Sjdp return true; 97333965Sjdp} 97433965Sjdp 97533965Sjdp/* This is called when BFD has discovered a constructor. This is only 97633965Sjdp called for some object file formats--those which do not handle 97733965Sjdp constructors in some more clever fashion. This is similar to 97833965Sjdp adding an element to a set, but less general. */ 97933965Sjdp 98033965Sjdpstatic boolean 98133965Sjdpconstructor_callback (info, constructor, name, abfd, section, value) 98233965Sjdp struct bfd_link_info *info; 98333965Sjdp boolean constructor; 98433965Sjdp const char *name; 98533965Sjdp bfd *abfd; 98633965Sjdp asection *section; 98733965Sjdp bfd_vma value; 98833965Sjdp{ 98933965Sjdp char *s; 99033965Sjdp struct bfd_link_hash_entry *h; 99133965Sjdp char set_name[1 + sizeof "__CTOR_LIST__"]; 99233965Sjdp 99333965Sjdp if (config.warn_constructors) 99460484Sobrien einfo (_("%P: warning: global constructor %s used\n"), name); 99533965Sjdp 99633965Sjdp if (! config.build_constructors) 99733965Sjdp return true; 99833965Sjdp 99933965Sjdp /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a 100033965Sjdp useful error message. */ 100133965Sjdp if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL 100233965Sjdp && (link_info.relocateable 100333965Sjdp || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL)) 100460484Sobrien einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n")); 100533965Sjdp 100633965Sjdp s = set_name; 100733965Sjdp if (bfd_get_symbol_leading_char (abfd) != '\0') 100833965Sjdp *s++ = bfd_get_symbol_leading_char (abfd); 100933965Sjdp if (constructor) 101033965Sjdp strcpy (s, "__CTOR_LIST__"); 101133965Sjdp else 101233965Sjdp strcpy (s, "__DTOR_LIST__"); 101333965Sjdp 101433965Sjdp h = bfd_link_hash_lookup (info->hash, set_name, true, true, true); 101533965Sjdp if (h == (struct bfd_link_hash_entry *) NULL) 101660484Sobrien einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); 101733965Sjdp if (h->type == bfd_link_hash_new) 101833965Sjdp { 101933965Sjdp h->type = bfd_link_hash_undefined; 102033965Sjdp h->u.undef.abfd = abfd; 102133965Sjdp /* We don't call bfd_link_add_undef to add this to the list of 102233965Sjdp undefined symbols because we are going to define it 102333965Sjdp ourselves. */ 102433965Sjdp } 102533965Sjdp 102633965Sjdp ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value); 102733965Sjdp return true; 102833965Sjdp} 102933965Sjdp 103033965Sjdp/* A structure used by warning_callback to pass information through 103133965Sjdp bfd_map_over_sections. */ 103233965Sjdp 103377298Sobrienstruct warning_callback_info { 103433965Sjdp boolean found; 103533965Sjdp const char *warning; 103633965Sjdp const char *symbol; 103733965Sjdp asymbol **asymbols; 103833965Sjdp}; 103933965Sjdp 104033965Sjdp/* This is called when there is a reference to a warning symbol. */ 104133965Sjdp 104233965Sjdpstatic boolean 104333965Sjdpwarning_callback (info, warning, symbol, abfd, section, address) 104460484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 104533965Sjdp const char *warning; 104633965Sjdp const char *symbol; 104733965Sjdp bfd *abfd; 104833965Sjdp asection *section; 104933965Sjdp bfd_vma address; 105033965Sjdp{ 105133965Sjdp /* This is a hack to support warn_multiple_gp. FIXME: This should 105233965Sjdp have a cleaner interface, but what? */ 105333965Sjdp if (! config.warn_multiple_gp 105433965Sjdp && strcmp (warning, "using multiple gp values") == 0) 105533965Sjdp return true; 105633965Sjdp 105733965Sjdp if (section != NULL) 105833965Sjdp einfo ("%C: %s\n", abfd, section, address, warning); 105933965Sjdp else if (abfd == NULL) 106033965Sjdp einfo ("%P: %s\n", warning); 106133965Sjdp else if (symbol == NULL) 106233965Sjdp einfo ("%B: %s\n", abfd, warning); 106333965Sjdp else 106433965Sjdp { 106533965Sjdp lang_input_statement_type *entry; 106633965Sjdp asymbol **asymbols; 106733965Sjdp struct warning_callback_info info; 106833965Sjdp 106933965Sjdp /* Look through the relocs to see if we can find a plausible 107033965Sjdp address. */ 107133965Sjdp 107233965Sjdp entry = (lang_input_statement_type *) abfd->usrdata; 107333965Sjdp if (entry != NULL && entry->asymbols != NULL) 107433965Sjdp asymbols = entry->asymbols; 107533965Sjdp else 107633965Sjdp { 107733965Sjdp long symsize; 107833965Sjdp long symbol_count; 107933965Sjdp 108033965Sjdp symsize = bfd_get_symtab_upper_bound (abfd); 108133965Sjdp if (symsize < 0) 108260484Sobrien einfo (_("%B%F: could not read symbols: %E\n"), abfd); 108333965Sjdp asymbols = (asymbol **) xmalloc (symsize); 108433965Sjdp symbol_count = bfd_canonicalize_symtab (abfd, asymbols); 108533965Sjdp if (symbol_count < 0) 108660484Sobrien einfo (_("%B%F: could not read symbols: %E\n"), abfd); 108733965Sjdp if (entry != NULL) 108833965Sjdp { 108933965Sjdp entry->asymbols = asymbols; 109033965Sjdp entry->symbol_count = symbol_count; 109133965Sjdp } 109233965Sjdp } 109333965Sjdp 109433965Sjdp info.found = false; 109533965Sjdp info.warning = warning; 109633965Sjdp info.symbol = symbol; 109733965Sjdp info.asymbols = asymbols; 109833965Sjdp bfd_map_over_sections (abfd, warning_find_reloc, (PTR) &info); 109933965Sjdp 110033965Sjdp if (! info.found) 110133965Sjdp einfo ("%B: %s\n", abfd, warning); 110233965Sjdp 110333965Sjdp if (entry == NULL) 110433965Sjdp free (asymbols); 110533965Sjdp } 110633965Sjdp 110733965Sjdp return true; 110833965Sjdp} 110933965Sjdp 111033965Sjdp/* This is called by warning_callback for each section. It checks the 111133965Sjdp relocs of the section to see if it can find a reference to the 111233965Sjdp symbol which triggered the warning. If it can, it uses the reloc 111333965Sjdp to give an error message with a file and line number. */ 111433965Sjdp 111533965Sjdpstatic void 111633965Sjdpwarning_find_reloc (abfd, sec, iarg) 111733965Sjdp bfd *abfd; 111833965Sjdp asection *sec; 111933965Sjdp PTR iarg; 112033965Sjdp{ 112133965Sjdp struct warning_callback_info *info = (struct warning_callback_info *) iarg; 112233965Sjdp long relsize; 112333965Sjdp arelent **relpp; 112433965Sjdp long relcount; 112533965Sjdp arelent **p, **pend; 112633965Sjdp 112733965Sjdp if (info->found) 112833965Sjdp return; 112933965Sjdp 113033965Sjdp relsize = bfd_get_reloc_upper_bound (abfd, sec); 113133965Sjdp if (relsize < 0) 113260484Sobrien einfo (_("%B%F: could not read relocs: %E\n"), abfd); 113333965Sjdp if (relsize == 0) 113433965Sjdp return; 113533965Sjdp 113633965Sjdp relpp = (arelent **) xmalloc (relsize); 113733965Sjdp relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols); 113833965Sjdp if (relcount < 0) 113960484Sobrien einfo (_("%B%F: could not read relocs: %E\n"), abfd); 114033965Sjdp 114133965Sjdp p = relpp; 114233965Sjdp pend = p + relcount; 114333965Sjdp for (; p < pend && *p != NULL; p++) 114433965Sjdp { 114533965Sjdp arelent *q = *p; 114633965Sjdp 114733965Sjdp if (q->sym_ptr_ptr != NULL 114833965Sjdp && *q->sym_ptr_ptr != NULL 114933965Sjdp && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0) 115033965Sjdp { 115133965Sjdp /* We found a reloc for the symbol we are looking for. */ 115233965Sjdp einfo ("%C: %s\n", abfd, sec, q->address, info->warning); 115333965Sjdp info->found = true; 115433965Sjdp break; 115533965Sjdp } 115633965Sjdp } 115733965Sjdp 115833965Sjdp free (relpp); 115933965Sjdp} 116033965Sjdp 116133965Sjdp/* This is called when an undefined symbol is found. */ 116233965Sjdp 116333965Sjdpstatic boolean 116460484Sobrienundefined_symbol (info, name, abfd, section, address, fatal) 116560484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 116633965Sjdp const char *name; 116733965Sjdp bfd *abfd; 116833965Sjdp asection *section; 116933965Sjdp bfd_vma address; 117077298Sobrien boolean fatal ATTRIBUTE_UNUSED; 117133965Sjdp{ 117233965Sjdp static char *error_name; 117333965Sjdp static unsigned int error_count; 117433965Sjdp 117533965Sjdp#define MAX_ERRORS_IN_A_ROW 5 117633965Sjdp 117733965Sjdp if (config.warn_once) 117833965Sjdp { 117933965Sjdp static struct bfd_hash_table *hash; 118033965Sjdp 118133965Sjdp /* Only warn once about a particular undefined symbol. */ 118233965Sjdp 118333965Sjdp if (hash == NULL) 118433965Sjdp { 118533965Sjdp hash = ((struct bfd_hash_table *) 118633965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 118733965Sjdp if (! bfd_hash_table_init (hash, bfd_hash_newfunc)) 118860484Sobrien einfo (_("%F%P: bfd_hash_table_init failed: %E\n")); 118933965Sjdp } 119033965Sjdp 119133965Sjdp if (bfd_hash_lookup (hash, name, false, false) != NULL) 119233965Sjdp return true; 119333965Sjdp 119433965Sjdp if (bfd_hash_lookup (hash, name, true, true) == NULL) 119560484Sobrien einfo (_("%F%P: bfd_hash_lookup failed: %E\n")); 119633965Sjdp } 119733965Sjdp 119833965Sjdp /* We never print more than a reasonable number of errors in a row 119933965Sjdp for a single symbol. */ 120033965Sjdp if (error_name != (char *) NULL 120133965Sjdp && strcmp (name, error_name) == 0) 120233965Sjdp ++error_count; 120333965Sjdp else 120433965Sjdp { 120533965Sjdp error_count = 0; 120633965Sjdp if (error_name != (char *) NULL) 120733965Sjdp free (error_name); 120833965Sjdp error_name = buystring (name); 120933965Sjdp } 121033965Sjdp 121133965Sjdp if (section != NULL) 121233965Sjdp { 121333965Sjdp if (error_count < MAX_ERRORS_IN_A_ROW) 121460484Sobrien { 121560484Sobrien einfo (_("%C: undefined reference to `%T'\n"), 121660484Sobrien abfd, section, address, name); 121760484Sobrien if (fatal) 121860484Sobrien einfo ("%X"); 121960484Sobrien } 122033965Sjdp else if (error_count == MAX_ERRORS_IN_A_ROW) 122160484Sobrien einfo (_("%D: more undefined references to `%T' follow\n"), 122233965Sjdp abfd, section, address, name); 122333965Sjdp } 122433965Sjdp else 122533965Sjdp { 122633965Sjdp if (error_count < MAX_ERRORS_IN_A_ROW) 122760484Sobrien { 122860484Sobrien einfo (_("%B: undefined reference to `%T'\n"), 122960484Sobrien abfd, name); 123060484Sobrien if (fatal) 123160484Sobrien einfo ("%X"); 123260484Sobrien } 123333965Sjdp else if (error_count == MAX_ERRORS_IN_A_ROW) 123460484Sobrien einfo (_("%B: more undefined references to `%T' follow\n"), 123533965Sjdp abfd, name); 123633965Sjdp } 123733965Sjdp 123833965Sjdp return true; 123933965Sjdp} 124033965Sjdp 124133965Sjdp/* This is called when a reloc overflows. */ 124233965Sjdp 124333965Sjdpstatic boolean 124433965Sjdpreloc_overflow (info, name, reloc_name, addend, abfd, section, address) 124560484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 124633965Sjdp const char *name; 124733965Sjdp const char *reloc_name; 124833965Sjdp bfd_vma addend; 124933965Sjdp bfd *abfd; 125033965Sjdp asection *section; 125133965Sjdp bfd_vma address; 125233965Sjdp{ 125333965Sjdp if (abfd == (bfd *) NULL) 125460484Sobrien einfo (_("%P%X: generated")); 125533965Sjdp else 125633965Sjdp einfo ("%X%C:", abfd, section, address); 125760484Sobrien einfo (_(" relocation truncated to fit: %s %T"), reloc_name, name); 125833965Sjdp if (addend != 0) 125933965Sjdp einfo ("+%v", addend); 126033965Sjdp einfo ("\n"); 126133965Sjdp return true; 126233965Sjdp} 126333965Sjdp 126433965Sjdp/* This is called when a dangerous relocation is made. */ 126533965Sjdp 126633965Sjdpstatic boolean 126733965Sjdpreloc_dangerous (info, message, abfd, section, address) 126860484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 126933965Sjdp const char *message; 127033965Sjdp bfd *abfd; 127133965Sjdp asection *section; 127233965Sjdp bfd_vma address; 127333965Sjdp{ 127433965Sjdp if (abfd == (bfd *) NULL) 127560484Sobrien einfo (_("%P%X: generated")); 127633965Sjdp else 127733965Sjdp einfo ("%X%C:", abfd, section, address); 127860484Sobrien einfo (_("dangerous relocation: %s\n"), message); 127933965Sjdp return true; 128033965Sjdp} 128133965Sjdp 128233965Sjdp/* This is called when a reloc is being generated attached to a symbol 128333965Sjdp that is not being output. */ 128433965Sjdp 128533965Sjdpstatic boolean 128633965Sjdpunattached_reloc (info, name, abfd, section, address) 128760484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 128833965Sjdp const char *name; 128933965Sjdp bfd *abfd; 129033965Sjdp asection *section; 129133965Sjdp bfd_vma address; 129233965Sjdp{ 129333965Sjdp if (abfd == (bfd *) NULL) 129460484Sobrien einfo (_("%P%X: generated")); 129533965Sjdp else 129633965Sjdp einfo ("%X%C:", abfd, section, address); 129760484Sobrien einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name); 129833965Sjdp return true; 129933965Sjdp} 130033965Sjdp 130133965Sjdp/* This is called if link_info.notice_all is set, or when a symbol in 130233965Sjdp link_info.notice_hash is found. Symbols are put in notice_hash 130333965Sjdp using the -y option. */ 130433965Sjdp 130533965Sjdpstatic boolean 130633965Sjdpnotice (info, name, abfd, section, value) 130733965Sjdp struct bfd_link_info *info; 130833965Sjdp const char *name; 130933965Sjdp bfd *abfd; 131033965Sjdp asection *section; 131133965Sjdp bfd_vma value; 131233965Sjdp{ 131333965Sjdp if (! info->notice_all 131433965Sjdp || (info->notice_hash != NULL 131533965Sjdp && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL)) 131660484Sobrien { 131760484Sobrien if (bfd_is_und_section (section)) 131860484Sobrien einfo ("%B: reference to %s\n", abfd, name); 131960484Sobrien else 132060484Sobrien einfo ("%B: definition of %s\n", abfd, name); 132160484Sobrien } 132233965Sjdp 132333965Sjdp if (command_line.cref || nocrossref_list != NULL) 132433965Sjdp add_cref (name, abfd, section, value); 132533965Sjdp 132633965Sjdp return true; 132733965Sjdp} 1328