ldmain.c revision 61843
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 "ldemul.h" 4033965Sjdp#include "ldlex.h" 4133965Sjdp#include "ldfile.h" 4233965Sjdp#include "ldctor.h" 4333965Sjdp 4433965Sjdp/* 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 6833965Sjdp/* 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 13333965Sjdpstatic struct bfd_link_callbacks link_callbacks = 13433965Sjdp{ 13533965Sjdp add_archive_element, 13633965Sjdp multiple_definition, 13733965Sjdp multiple_common, 13833965Sjdp add_to_set, 13933965Sjdp constructor_callback, 14033965Sjdp warning_callback, 14133965Sjdp undefined_symbol, 14233965Sjdp reloc_overflow, 14333965Sjdp reloc_dangerous, 14433965Sjdp unattached_reloc, 14533965Sjdp notice 14633965Sjdp}; 14733965Sjdp 14833965Sjdpstruct bfd_link_info link_info; 14933965Sjdp 15033965Sjdpstatic void 15133965Sjdpremove_output () 15233965Sjdp{ 15333965Sjdp if (output_filename) 15433965Sjdp { 15533965Sjdp if (output_bfd && output_bfd->iostream) 15633965Sjdp fclose((FILE *)(output_bfd->iostream)); 15733965Sjdp if (delete_output_file_on_failure) 15833965Sjdp unlink (output_filename); 15933965Sjdp } 16033965Sjdp} 16133965Sjdp 16233965Sjdpint 16333965Sjdpmain (argc, argv) 16433965Sjdp int argc; 16533965Sjdp char **argv; 16633965Sjdp{ 16733965Sjdp char *emulation; 16833965Sjdp long start_time = get_run_time (); 16933965Sjdp 17060484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 17160484Sobrien setlocale (LC_MESSAGES, ""); 17260484Sobrien#endif 17360484Sobrien bindtextdomain (PACKAGE, LOCALEDIR); 17460484Sobrien textdomain (PACKAGE); 17560484Sobrien 17633965Sjdp program_name = argv[0]; 17733965Sjdp xmalloc_set_program_name (program_name); 17833965Sjdp 17933965Sjdp START_PROGRESS (program_name, 0); 18033965Sjdp 18133965Sjdp bfd_init (); 18233965Sjdp 18333965Sjdp bfd_set_error_program_name (program_name); 18433965Sjdp 18533965Sjdp xatexit (remove_output); 18633965Sjdp 18733965Sjdp /* Set the default BFD target based on the configured target. Doing 18833965Sjdp this permits the linker to be configured for a particular target, 18933965Sjdp and linked against a shared BFD library which was configured for 19033965Sjdp a different target. The macro TARGET is defined by Makefile. */ 19133965Sjdp if (! bfd_set_default_target (TARGET)) 19233965Sjdp { 19360484Sobrien einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET); 19433965Sjdp xexit (1); 19533965Sjdp } 19633965Sjdp 19733965Sjdp /* Initialize the data about options. */ 19833965Sjdp trace_files = trace_file_tries = version_printed = false; 19933965Sjdp whole_archive = false; 20033965Sjdp config.build_constructors = true; 20133965Sjdp config.dynamic_link = false; 20260484Sobrien config.has_shared = false; 20333965Sjdp command_line.force_common_definition = false; 20433965Sjdp command_line.interpreter = NULL; 20533965Sjdp command_line.rpath = NULL; 20638889Sjdp command_line.warn_mismatch = true; 20760484Sobrien command_line.check_section_addresses = true; 20833965Sjdp 20960484Sobrien /* We initialize DEMANGLING based on the environment variable 21060484Sobrien COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the 21160484Sobrien output of the linker, unless COLLECT_NO_DEMANGLE is set in the 21260484Sobrien environment. Acting the same way here lets us provide the same 21360484Sobrien interface by default. */ 21460484Sobrien demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL; 21560484Sobrien 21633965Sjdp link_info.callbacks = &link_callbacks; 21733965Sjdp link_info.relocateable = false; 21833965Sjdp link_info.shared = false; 21933965Sjdp link_info.symbolic = false; 22033965Sjdp link_info.static_link = false; 22133965Sjdp link_info.traditional_format = false; 22260484Sobrien link_info.optimize = false; 22360484Sobrien link_info.no_undefined = false; 22433965Sjdp link_info.strip = strip_none; 22533965Sjdp link_info.discard = discard_none; 22633965Sjdp link_info.keep_memory = true; 22733965Sjdp link_info.input_bfds = NULL; 22833965Sjdp link_info.create_object_symbols_section = NULL; 22933965Sjdp link_info.hash = NULL; 23033965Sjdp link_info.keep_hash = NULL; 23133965Sjdp link_info.notice_all = false; 23233965Sjdp link_info.notice_hash = NULL; 23333965Sjdp link_info.wrap_hash = NULL; 23460484Sobrien link_info.mpc860c0 = 0; 23560484Sobrien /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init 23660484Sobrien and _fini symbols. We are compatible. */ 23760484Sobrien link_info.init_function = "_init"; 23860484Sobrien link_info.fini_function = "_fini"; 23960484Sobrien 24033965Sjdp ldfile_add_arch (""); 24133965Sjdp 24233965Sjdp config.make_executable = true; 24333965Sjdp force_make_executable = false; 24433965Sjdp config.magic_demand_paged = true; 24533965Sjdp config.text_read_only = true; 24633965Sjdp config.make_executable = true; 24733965Sjdp 24833965Sjdp emulation = get_emulation (argc, argv); 24933965Sjdp ldemul_choose_mode (emulation); 25033965Sjdp default_target = ldemul_choose_target (); 25133965Sjdp lang_init (); 25233965Sjdp ldemul_before_parse (); 25333965Sjdp lang_has_input_file = false; 25433965Sjdp parse_args (argc, argv); 25533965Sjdp 25633965Sjdp ldemul_set_symbols (); 25733965Sjdp 25833965Sjdp if (link_info.relocateable) 25933965Sjdp { 26060484Sobrien if (command_line.gc_sections) 26160484Sobrien einfo ("%P%F: --gc-sections and -r may not be used together\n"); 26260484Sobrien if (link_info.mpc860c0) 26360484Sobrien einfo (_("%P%F: -r and --mpc860c0 may not be used together\n")); 26460484Sobrien else if (command_line.relax) 26560484Sobrien einfo (_("%P%F: --relax and -r may not be used together\n")); 26633965Sjdp if (link_info.shared) 26760484Sobrien einfo (_("%P%F: -r and -shared may not be used together\n")); 26833965Sjdp } 26933965Sjdp 27033965Sjdp /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I 27133965Sjdp don't see how else this can be handled, since in this case we 27233965Sjdp must preserve all externally visible symbols. */ 27333965Sjdp if (link_info.relocateable && link_info.strip == strip_all) 27433965Sjdp { 27533965Sjdp link_info.strip = strip_debugger; 27633965Sjdp if (link_info.discard == discard_none) 27733965Sjdp link_info.discard = discard_all; 27833965Sjdp } 27933965Sjdp 28033965Sjdp /* This essentially adds another -L directory so this must be done after 28133965Sjdp the -L's in argv have been processed. */ 28233965Sjdp set_scripts_dir (); 28333965Sjdp 28433965Sjdp if (had_script == false) 28533965Sjdp { 28633965Sjdp /* Read the emulation's appropriate default script. */ 28733965Sjdp int isfile; 28833965Sjdp char *s = ldemul_get_script (&isfile); 28933965Sjdp 29033965Sjdp if (isfile) 29133965Sjdp ldfile_open_command_file (s); 29233965Sjdp else 29333965Sjdp { 29433965Sjdp if (trace_file_tries) 29533965Sjdp { 29660484Sobrien info_msg (_("using internal linker script:\n")); 29733965Sjdp info_msg ("==================================================\n"); 29833965Sjdp info_msg (s); 29933965Sjdp info_msg ("\n==================================================\n"); 30033965Sjdp } 30133965Sjdp lex_string = s; 30233965Sjdp lex_redirect (s); 30333965Sjdp } 30433965Sjdp parser_input = input_script; 30533965Sjdp yyparse (); 30633965Sjdp lex_string = NULL; 30733965Sjdp } 30833965Sjdp 30933965Sjdp lang_final (); 31033965Sjdp 31133965Sjdp if (lang_has_input_file == false) 31233965Sjdp { 31333965Sjdp if (version_printed) 31433965Sjdp xexit (0); 31560484Sobrien einfo (_("%P%F: no input files\n")); 31633965Sjdp } 31733965Sjdp 31833965Sjdp if (trace_files) 31933965Sjdp { 32060484Sobrien info_msg (_("%P: mode %s\n"), emulation); 32133965Sjdp } 32233965Sjdp 32333965Sjdp ldemul_after_parse (); 32433965Sjdp 32533965Sjdp 32633965Sjdp if (config.map_filename) 32733965Sjdp { 32833965Sjdp if (strcmp (config.map_filename, "-") == 0) 32933965Sjdp { 33033965Sjdp config.map_file = stdout; 33133965Sjdp } 33233965Sjdp else 33333965Sjdp { 33433965Sjdp config.map_file = fopen (config.map_filename, FOPEN_WT); 33533965Sjdp if (config.map_file == (FILE *) NULL) 33633965Sjdp { 33733965Sjdp bfd_set_error (bfd_error_system_call); 33860484Sobrien einfo (_("%P%F: cannot open map file %s: %E\n"), 33933965Sjdp config.map_filename); 34033965Sjdp } 34133965Sjdp } 34233965Sjdp } 34333965Sjdp 34433965Sjdp 34533965Sjdp lang_process (); 34633965Sjdp 34733965Sjdp /* Print error messages for any missing symbols, for any warning 34833965Sjdp symbols, and possibly multiple definitions */ 34933965Sjdp 35033965Sjdp 35133965Sjdp if (config.text_read_only) 35233965Sjdp { 35333965Sjdp /* Look for a text section and mark the readonly attribute in it */ 35433965Sjdp asection *found = bfd_get_section_by_name (output_bfd, ".text"); 35533965Sjdp 35633965Sjdp if (found != (asection *) NULL) 35733965Sjdp { 35833965Sjdp found->flags |= SEC_READONLY; 35933965Sjdp } 36033965Sjdp } 36133965Sjdp 36233965Sjdp if (link_info.relocateable) 36333965Sjdp output_bfd->flags &= ~EXEC_P; 36433965Sjdp else 36533965Sjdp output_bfd->flags |= EXEC_P; 36633965Sjdp 36733965Sjdp ldwrite (); 36833965Sjdp 36933965Sjdp if (config.map_file != NULL) 37033965Sjdp lang_map (); 37133965Sjdp if (command_line.cref) 37233965Sjdp output_cref (config.map_file != NULL ? config.map_file : stdout); 37333965Sjdp if (nocrossref_list != NULL) 37433965Sjdp check_nocrossrefs (); 37533965Sjdp 37633965Sjdp /* Even if we're producing relocateable output, some non-fatal errors should 37733965Sjdp be reported in the exit status. (What non-fatal errors, if any, do we 37833965Sjdp want to ignore for relocateable output?) */ 37933965Sjdp 38033965Sjdp if (config.make_executable == false && force_make_executable == false) 38133965Sjdp { 38233965Sjdp if (trace_files == true) 38333965Sjdp { 38460484Sobrien einfo (_("%P: link errors found, deleting executable `%s'\n"), 38533965Sjdp output_filename); 38633965Sjdp } 38733965Sjdp 38833965Sjdp /* The file will be removed by remove_output. */ 38933965Sjdp 39033965Sjdp xexit (1); 39133965Sjdp } 39233965Sjdp else 39333965Sjdp { 39433965Sjdp if (! bfd_close (output_bfd)) 39560484Sobrien einfo (_("%F%B: final close failed: %E\n"), output_bfd); 39633965Sjdp 39733965Sjdp /* If the --force-exe-suffix is enabled, and we're making an 39833965Sjdp executable file and it doesn't end in .exe, copy it to one which does. */ 39933965Sjdp 40033965Sjdp if (! link_info.relocateable && command_line.force_exe_suffix) 40133965Sjdp { 40233965Sjdp int len = strlen (output_filename); 40333965Sjdp if (len < 4 40433965Sjdp || (strcasecmp (output_filename + len - 4, ".exe") != 0 40533965Sjdp && strcasecmp (output_filename + len - 4, ".dll") != 0)) 40633965Sjdp { 40733965Sjdp FILE *src; 40833965Sjdp FILE *dst; 40933965Sjdp const int bsize = 4096; 41033965Sjdp char *buf = xmalloc (bsize); 41133965Sjdp int l; 41233965Sjdp char *dst_name = xmalloc (len + 5); 41333965Sjdp strcpy (dst_name, output_filename); 41433965Sjdp strcat (dst_name, ".exe"); 41533965Sjdp src = fopen (output_filename, FOPEN_RB); 41633965Sjdp dst = fopen (dst_name, FOPEN_WB); 41733965Sjdp 41833965Sjdp if (!src) 41960484Sobrien einfo (_("%X%P: unable to open for source of copy `%s'\n"), output_filename); 42033965Sjdp if (!dst) 42160484Sobrien einfo (_("%X%P: unable to open for destination of copy `%s'\n"), dst_name); 42233965Sjdp while ((l = fread (buf, 1, bsize, src)) > 0) 42333965Sjdp { 42433965Sjdp int done = fwrite (buf, 1, l, dst); 42533965Sjdp if (done != l) 42633965Sjdp { 42760484Sobrien einfo (_("%P: Error writing file `%s'\n"), dst_name); 42833965Sjdp } 42933965Sjdp } 43033965Sjdp fclose (src); 43133965Sjdp if (fclose (dst) == EOF) 43233965Sjdp { 43360484Sobrien einfo (_("%P: Error closing file `%s'\n"), dst_name); 43433965Sjdp } 43533965Sjdp free (dst_name); 43633965Sjdp free (buf); 43733965Sjdp } 43833965Sjdp } 43933965Sjdp } 44033965Sjdp 44133965Sjdp END_PROGRESS (program_name); 44233965Sjdp 44333965Sjdp if (config.stats) 44433965Sjdp { 44533965Sjdp#ifdef HAVE_SBRK 44633965Sjdp char *lim = (char *) sbrk (0); 44733965Sjdp#endif 44833965Sjdp long run_time = get_run_time () - start_time; 44933965Sjdp 45060484Sobrien fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"), 45133965Sjdp program_name, run_time / 1000000, run_time % 1000000); 45233965Sjdp#ifdef HAVE_SBRK 45360484Sobrien fprintf (stderr, _("%s: data size %ld\n"), program_name, 45433965Sjdp (long) (lim - (char *) &environ)); 45533965Sjdp#endif 45633965Sjdp } 45733965Sjdp 45833965Sjdp /* Prevent remove_output from doing anything, after a successful link. */ 45933965Sjdp output_filename = NULL; 46033965Sjdp 46133965Sjdp xexit (0); 46233965Sjdp return 0; 46333965Sjdp} 46433965Sjdp 46533965Sjdp/* We need to find any explicitly given emulation in order to initialize the 46633965Sjdp state that's needed by the lex&yacc argument parser (parse_args). */ 46733965Sjdp 46833965Sjdpstatic char * 46933965Sjdpget_emulation (argc, argv) 47033965Sjdp int argc; 47133965Sjdp char **argv; 47233965Sjdp{ 47333965Sjdp char *emulation; 47433965Sjdp int i; 47533965Sjdp 47633965Sjdp emulation = getenv (EMULATION_ENVIRON); 47733965Sjdp if (emulation == NULL) 47833965Sjdp emulation = DEFAULT_EMULATION; 47933965Sjdp 48033965Sjdp for (i = 1; i < argc; i++) 48133965Sjdp { 48233965Sjdp if (!strncmp (argv[i], "-m", 2)) 48333965Sjdp { 48433965Sjdp if (argv[i][2] == '\0') 48533965Sjdp { 48633965Sjdp /* -m EMUL */ 48733965Sjdp if (i < argc - 1) 48833965Sjdp { 48933965Sjdp emulation = argv[i + 1]; 49033965Sjdp i++; 49133965Sjdp } 49233965Sjdp else 49333965Sjdp { 49460484Sobrien einfo(_("%P%F: missing argument to -m\n")); 49533965Sjdp } 49633965Sjdp } 49733965Sjdp else if (strcmp (argv[i], "-mips1") == 0 49833965Sjdp || strcmp (argv[i], "-mips2") == 0 49933965Sjdp || strcmp (argv[i], "-mips3") == 0 50033965Sjdp || strcmp (argv[i], "-mips4") == 0) 50133965Sjdp { 50233965Sjdp /* FIXME: The arguments -mips1, -mips2 and -mips3 are 50333965Sjdp passed to the linker by some MIPS compilers. They 50433965Sjdp generally tell the linker to use a slightly different 50533965Sjdp library path. Perhaps someday these should be 50633965Sjdp implemented as emulations; until then, we just ignore 50733965Sjdp the arguments and hope that nobody ever creates 50833965Sjdp emulations named ips1, ips2 or ips3. */ 50933965Sjdp } 51033965Sjdp else if (strcmp (argv[i], "-m486") == 0) 51133965Sjdp { 51233965Sjdp /* FIXME: The argument -m486 is passed to the linker on 51333965Sjdp some Linux systems. Hope that nobody creates an 51433965Sjdp emulation named 486. */ 51533965Sjdp } 51633965Sjdp else 51733965Sjdp { 51833965Sjdp /* -mEMUL */ 51933965Sjdp emulation = &argv[i][2]; 52033965Sjdp } 52133965Sjdp } 52233965Sjdp } 52333965Sjdp 52433965Sjdp return emulation; 52533965Sjdp} 52633965Sjdp 52733965Sjdp/* If directory DIR contains an "ldscripts" subdirectory, 52833965Sjdp add DIR to the library search path and return true, 52933965Sjdp else return false. */ 53033965Sjdp 53133965Sjdpstatic boolean 53233965Sjdpcheck_for_scripts_dir (dir) 53333965Sjdp char *dir; 53433965Sjdp{ 53533965Sjdp size_t dirlen; 53633965Sjdp char *buf; 53733965Sjdp struct stat s; 53833965Sjdp boolean res; 53933965Sjdp 54033965Sjdp dirlen = strlen (dir); 54133965Sjdp /* sizeof counts the terminating NUL. */ 54233965Sjdp buf = (char *) xmalloc (dirlen + sizeof("/ldscripts")); 54333965Sjdp sprintf (buf, "%s/ldscripts", dir); 54433965Sjdp 54533965Sjdp res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode); 54633965Sjdp free (buf); 54733965Sjdp if (res) 54833965Sjdp ldfile_add_library_path (dir, false); 54933965Sjdp return res; 55033965Sjdp} 55133965Sjdp 55233965Sjdp/* Set the default directory for finding script files. 55333965Sjdp Libraries will be searched for here too, but that's ok. 55433965Sjdp We look for the "ldscripts" directory in: 55533965Sjdp 55633965Sjdp SCRIPTDIR (passed from Makefile) 55733965Sjdp the dir where this program is (for using it from the build tree) 55833965Sjdp the dir where this program is/../lib (for installing the tool suite elsewhere) */ 55933965Sjdp 56033965Sjdpstatic void 56133965Sjdpset_scripts_dir () 56233965Sjdp{ 56333965Sjdp char *end, *dir; 56433965Sjdp size_t dirlen; 56533965Sjdp 56633965Sjdp if (check_for_scripts_dir (SCRIPTDIR)) 56733965Sjdp return; /* We've been installed normally. */ 56833965Sjdp 56933965Sjdp /* Look for "ldscripts" in the dir where our binary is. */ 57033965Sjdp end = strrchr (program_name, '/'); 57161843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 57261843Sobrien { 57361843Sobrien /* We could have \foo\bar, or /foo\bar. */ 57461843Sobrien char *bslash = strrchr (program_name, '\\'); 57561843Sobrien if (bslash > end) 57661843Sobrien end = bslash; 57761843Sobrien } 57861843Sobrien#endif 57933965Sjdp 58033965Sjdp if (end == NULL) 58133965Sjdp { 58233965Sjdp /* Don't look for ldscripts in the current directory. There is 58333965Sjdp too much potential for confusion. */ 58433965Sjdp return; 58533965Sjdp } 58633965Sjdp 58733965Sjdp dirlen = end - program_name; 58833965Sjdp /* Make a copy of program_name in dir. 58933965Sjdp Leave room for later "/../lib". */ 59033965Sjdp dir = (char *) xmalloc (dirlen + 8); 59133965Sjdp strncpy (dir, program_name, dirlen); 59233965Sjdp dir[dirlen] = '\0'; 59333965Sjdp 59433965Sjdp if (check_for_scripts_dir (dir)) 59533965Sjdp return; /* Don't free dir. */ 59633965Sjdp 59733965Sjdp /* Look for "ldscripts" in <the dir where our binary is>/../lib. */ 59833965Sjdp strcpy (dir + dirlen, "/../lib"); 59933965Sjdp if (check_for_scripts_dir (dir)) 60033965Sjdp return; 60133965Sjdp 60233965Sjdp free (dir); /* Well, we tried. */ 60333965Sjdp} 60433965Sjdp 60533965Sjdpvoid 60633965Sjdpadd_ysym (name) 60733965Sjdp const char *name; 60833965Sjdp{ 60933965Sjdp if (link_info.notice_hash == (struct bfd_hash_table *) NULL) 61033965Sjdp { 61133965Sjdp link_info.notice_hash = ((struct bfd_hash_table *) 61233965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 61333965Sjdp if (! bfd_hash_table_init_n (link_info.notice_hash, 61433965Sjdp bfd_hash_newfunc, 61533965Sjdp 61)) 61660484Sobrien einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); 61733965Sjdp } 61833965Sjdp 61933965Sjdp if (bfd_hash_lookup (link_info.notice_hash, name, true, true) 62033965Sjdp == (struct bfd_hash_entry *) NULL) 62160484Sobrien einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); 62233965Sjdp} 62333965Sjdp 62433965Sjdp/* Record a symbol to be wrapped, from the --wrap option. */ 62533965Sjdp 62633965Sjdpvoid 62733965Sjdpadd_wrap (name) 62833965Sjdp const char *name; 62933965Sjdp{ 63033965Sjdp if (link_info.wrap_hash == NULL) 63133965Sjdp { 63233965Sjdp link_info.wrap_hash = ((struct bfd_hash_table *) 63333965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 63433965Sjdp if (! bfd_hash_table_init_n (link_info.wrap_hash, 63533965Sjdp bfd_hash_newfunc, 63633965Sjdp 61)) 63760484Sobrien einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); 63833965Sjdp } 63933965Sjdp if (bfd_hash_lookup (link_info.wrap_hash, name, true, true) == NULL) 64060484Sobrien einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); 64133965Sjdp} 64233965Sjdp 64333965Sjdp/* Handle the -retain-symbols-file option. */ 64433965Sjdp 64533965Sjdpvoid 64633965Sjdpadd_keepsyms_file (filename) 64733965Sjdp const char *filename; 64833965Sjdp{ 64933965Sjdp FILE *file; 65033965Sjdp char *buf; 65133965Sjdp size_t bufsize; 65233965Sjdp int c; 65333965Sjdp 65433965Sjdp if (link_info.strip == strip_some) 65560484Sobrien einfo (_("%X%P: error: duplicate retain-symbols-file\n")); 65633965Sjdp 65733965Sjdp file = fopen (filename, "r"); 65833965Sjdp if (file == (FILE *) NULL) 65933965Sjdp { 66033965Sjdp bfd_set_error (bfd_error_system_call); 66133965Sjdp einfo ("%X%P: %s: %E\n", filename); 66233965Sjdp return; 66333965Sjdp } 66433965Sjdp 66533965Sjdp link_info.keep_hash = ((struct bfd_hash_table *) 66633965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 66733965Sjdp if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc)) 66860484Sobrien einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); 66933965Sjdp 67033965Sjdp bufsize = 100; 67133965Sjdp buf = (char *) xmalloc (bufsize); 67233965Sjdp 67333965Sjdp c = getc (file); 67433965Sjdp while (c != EOF) 67533965Sjdp { 67633965Sjdp while (isspace (c)) 67733965Sjdp c = getc (file); 67833965Sjdp 67933965Sjdp if (c != EOF) 68033965Sjdp { 68133965Sjdp size_t len = 0; 68233965Sjdp 68333965Sjdp while (! isspace (c) && c != EOF) 68433965Sjdp { 68533965Sjdp buf[len] = c; 68633965Sjdp ++len; 68733965Sjdp if (len >= bufsize) 68833965Sjdp { 68933965Sjdp bufsize *= 2; 69033965Sjdp buf = xrealloc (buf, bufsize); 69133965Sjdp } 69233965Sjdp c = getc (file); 69333965Sjdp } 69433965Sjdp 69533965Sjdp buf[len] = '\0'; 69633965Sjdp 69733965Sjdp if (bfd_hash_lookup (link_info.keep_hash, buf, true, true) 69833965Sjdp == (struct bfd_hash_entry *) NULL) 69960484Sobrien einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n")); 70033965Sjdp } 70133965Sjdp } 70233965Sjdp 70333965Sjdp if (link_info.strip != strip_none) 70460484Sobrien einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n")); 70533965Sjdp 70633965Sjdp link_info.strip = strip_some; 70733965Sjdp} 70833965Sjdp 70933965Sjdp/* Callbacks from the BFD linker routines. */ 71033965Sjdp 71133965Sjdp/* This is called when BFD has decided to include an archive member in 71233965Sjdp a link. */ 71333965Sjdp 71433965Sjdp/*ARGSUSED*/ 71533965Sjdpstatic boolean 71633965Sjdpadd_archive_element (info, abfd, name) 71760484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 71833965Sjdp bfd *abfd; 71933965Sjdp const char *name; 72033965Sjdp{ 72133965Sjdp lang_input_statement_type *input; 72233965Sjdp 72333965Sjdp input = ((lang_input_statement_type *) 72433965Sjdp xmalloc (sizeof (lang_input_statement_type))); 72533965Sjdp input->filename = abfd->filename; 72633965Sjdp input->local_sym_name = abfd->filename; 72733965Sjdp input->the_bfd = abfd; 72833965Sjdp input->asymbols = NULL; 72933965Sjdp input->next = NULL; 73033965Sjdp input->just_syms_flag = false; 73133965Sjdp input->loaded = false; 73233965Sjdp input->search_dirs_flag = false; 73333965Sjdp 73433965Sjdp /* FIXME: The following fields are not set: header.next, 73533965Sjdp header.type, closed, passive_position, symbol_count, 73633965Sjdp next_real_file, is_archive, target, real. This bit of code is 73733965Sjdp from the old decode_library_subfile function. I don't know 73833965Sjdp whether any of those fields matters. */ 73933965Sjdp 74033965Sjdp ldlang_add_file (input); 74133965Sjdp 74233965Sjdp if (config.map_file != (FILE *) NULL) 74333965Sjdp { 74433965Sjdp static boolean header_printed; 74533965Sjdp struct bfd_link_hash_entry *h; 74633965Sjdp bfd *from; 74733965Sjdp int len; 74833965Sjdp 74933965Sjdp h = bfd_link_hash_lookup (link_info.hash, name, false, false, true); 75033965Sjdp 75133965Sjdp if (h == NULL) 75233965Sjdp from = NULL; 75333965Sjdp else 75433965Sjdp { 75533965Sjdp switch (h->type) 75633965Sjdp { 75733965Sjdp default: 75833965Sjdp from = NULL; 75933965Sjdp break; 76033965Sjdp 76133965Sjdp case bfd_link_hash_defined: 76233965Sjdp case bfd_link_hash_defweak: 76333965Sjdp from = h->u.def.section->owner; 76433965Sjdp break; 76533965Sjdp 76633965Sjdp case bfd_link_hash_undefined: 76733965Sjdp case bfd_link_hash_undefweak: 76833965Sjdp from = h->u.undef.abfd; 76933965Sjdp break; 77033965Sjdp 77133965Sjdp case bfd_link_hash_common: 77233965Sjdp from = h->u.c.p->section->owner; 77333965Sjdp break; 77433965Sjdp } 77533965Sjdp } 77633965Sjdp 77733965Sjdp if (! header_printed) 77833965Sjdp { 77933965Sjdp char buf[100]; 78033965Sjdp 78160484Sobrien sprintf (buf, "%-29s %s\n\n", _("Archive member included"), 78260484Sobrien _("because of file (symbol)")); 78333965Sjdp minfo ("%s", buf); 78433965Sjdp header_printed = true; 78533965Sjdp } 78633965Sjdp 78733965Sjdp if (bfd_my_archive (abfd) == NULL) 78833965Sjdp { 78933965Sjdp minfo ("%s", bfd_get_filename (abfd)); 79033965Sjdp len = strlen (bfd_get_filename (abfd)); 79133965Sjdp } 79233965Sjdp else 79333965Sjdp { 79433965Sjdp minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)), 79533965Sjdp bfd_get_filename (abfd)); 79633965Sjdp len = (strlen (bfd_get_filename (bfd_my_archive (abfd))) 79733965Sjdp + strlen (bfd_get_filename (abfd)) 79833965Sjdp + 2); 79933965Sjdp } 80033965Sjdp 80133965Sjdp if (len >= 29) 80233965Sjdp { 80333965Sjdp print_nl (); 80433965Sjdp len = 0; 80533965Sjdp } 80633965Sjdp while (len < 30) 80733965Sjdp { 80833965Sjdp print_space (); 80933965Sjdp ++len; 81033965Sjdp } 81133965Sjdp 81233965Sjdp if (from != NULL) 81333965Sjdp minfo ("%B ", from); 81433965Sjdp if (h != NULL) 81533965Sjdp minfo ("(%T)\n", h->root.string); 81633965Sjdp else 81733965Sjdp minfo ("(%s)\n", name); 81833965Sjdp } 81933965Sjdp 82033965Sjdp if (trace_files || trace_file_tries) 82133965Sjdp info_msg ("%I\n", input); 82233965Sjdp 82333965Sjdp return true; 82433965Sjdp} 82533965Sjdp 82633965Sjdp/* This is called when BFD has discovered a symbol which is defined 82733965Sjdp multiple times. */ 82833965Sjdp 82933965Sjdp/*ARGSUSED*/ 83033965Sjdpstatic boolean 83133965Sjdpmultiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval) 83260484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 83333965Sjdp const char *name; 83433965Sjdp bfd *obfd; 83533965Sjdp asection *osec; 83633965Sjdp bfd_vma oval; 83733965Sjdp bfd *nbfd; 83833965Sjdp asection *nsec; 83933965Sjdp bfd_vma nval; 84033965Sjdp{ 84133965Sjdp /* If either section has the output_section field set to 84233965Sjdp bfd_abs_section_ptr, it means that the section is being 84333965Sjdp discarded, and this is not really a multiple definition at all. 84433965Sjdp FIXME: It would be cleaner to somehow ignore symbols defined in 84533965Sjdp sections which are being discarded. */ 84633965Sjdp if ((osec->output_section != NULL 84733965Sjdp && ! bfd_is_abs_section (osec) 84833965Sjdp && bfd_is_abs_section (osec->output_section)) 84933965Sjdp || (nsec->output_section != NULL 85033965Sjdp && ! bfd_is_abs_section (nsec) 85133965Sjdp && bfd_is_abs_section (nsec->output_section))) 85233965Sjdp return true; 85333965Sjdp 85460484Sobrien einfo (_("%X%C: multiple definition of `%T'\n"), 85533965Sjdp nbfd, nsec, nval, name); 85633965Sjdp if (obfd != (bfd *) NULL) 85760484Sobrien einfo (_("%D: first defined here\n"), obfd, osec, oval); 85833965Sjdp return true; 85933965Sjdp} 86033965Sjdp 86133965Sjdp/* This is called when there is a definition of a common symbol, or 86233965Sjdp when a common symbol is found for a symbol that is already defined, 86333965Sjdp or when two common symbols are found. We only do something if 86433965Sjdp -warn-common was used. */ 86533965Sjdp 86633965Sjdp/*ARGSUSED*/ 86733965Sjdpstatic boolean 86833965Sjdpmultiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize) 86960484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 87033965Sjdp const char *name; 87133965Sjdp bfd *obfd; 87233965Sjdp enum bfd_link_hash_type otype; 87333965Sjdp bfd_vma osize; 87433965Sjdp bfd *nbfd; 87533965Sjdp enum bfd_link_hash_type ntype; 87633965Sjdp bfd_vma nsize; 87733965Sjdp{ 87833965Sjdp if (! config.warn_common) 87933965Sjdp return true; 88033965Sjdp 88133965Sjdp if (ntype == bfd_link_hash_defined 88233965Sjdp || ntype == bfd_link_hash_defweak 88333965Sjdp || ntype == bfd_link_hash_indirect) 88433965Sjdp { 88533965Sjdp ASSERT (otype == bfd_link_hash_common); 88660484Sobrien einfo (_("%B: warning: definition of `%T' overriding common\n"), 88733965Sjdp nbfd, name); 88833965Sjdp if (obfd != NULL) 88960484Sobrien einfo (_("%B: warning: common is here\n"), obfd); 89033965Sjdp } 89133965Sjdp else if (otype == bfd_link_hash_defined 89233965Sjdp || otype == bfd_link_hash_defweak 89333965Sjdp || otype == bfd_link_hash_indirect) 89433965Sjdp { 89533965Sjdp ASSERT (ntype == bfd_link_hash_common); 89660484Sobrien einfo (_("%B: warning: common of `%T' overridden by definition\n"), 89733965Sjdp nbfd, name); 89833965Sjdp if (obfd != NULL) 89960484Sobrien einfo (_("%B: warning: defined here\n"), obfd); 90033965Sjdp } 90133965Sjdp else 90233965Sjdp { 90333965Sjdp ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common); 90433965Sjdp if (osize > nsize) 90533965Sjdp { 90660484Sobrien einfo (_("%B: warning: common of `%T' overridden by larger common\n"), 90733965Sjdp nbfd, name); 90833965Sjdp if (obfd != NULL) 90960484Sobrien einfo (_("%B: warning: larger common is here\n"), obfd); 91033965Sjdp } 91133965Sjdp else if (nsize > osize) 91233965Sjdp { 91360484Sobrien einfo (_("%B: warning: common of `%T' overriding smaller common\n"), 91433965Sjdp nbfd, name); 91533965Sjdp if (obfd != NULL) 91660484Sobrien einfo (_("%B: warning: smaller common is here\n"), obfd); 91733965Sjdp } 91833965Sjdp else 91933965Sjdp { 92060484Sobrien einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name); 92133965Sjdp if (obfd != NULL) 92260484Sobrien einfo (_("%B: warning: previous common is here\n"), obfd); 92333965Sjdp } 92433965Sjdp } 92533965Sjdp 92633965Sjdp return true; 92733965Sjdp} 92833965Sjdp 92933965Sjdp/* This is called when BFD has discovered a set element. H is the 93033965Sjdp entry in the linker hash table for the set. SECTION and VALUE 93133965Sjdp represent a value which should be added to the set. */ 93233965Sjdp 93333965Sjdp/*ARGSUSED*/ 93433965Sjdpstatic boolean 93533965Sjdpadd_to_set (info, h, reloc, abfd, section, value) 93660484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 93733965Sjdp struct bfd_link_hash_entry *h; 93833965Sjdp bfd_reloc_code_real_type reloc; 93933965Sjdp bfd *abfd; 94033965Sjdp asection *section; 94133965Sjdp bfd_vma value; 94233965Sjdp{ 94333965Sjdp if (config.warn_constructors) 94460484Sobrien einfo (_("%P: warning: global constructor %s used\n"), 94533965Sjdp h->root.string); 94633965Sjdp 94733965Sjdp if (! config.build_constructors) 94833965Sjdp return true; 94933965Sjdp 95033965Sjdp ldctor_add_set_entry (h, reloc, (const char *) NULL, section, value); 95133965Sjdp 95233965Sjdp if (h->type == bfd_link_hash_new) 95333965Sjdp { 95433965Sjdp h->type = bfd_link_hash_undefined; 95533965Sjdp h->u.undef.abfd = abfd; 95633965Sjdp /* We don't call bfd_link_add_undef to add this to the list of 95733965Sjdp undefined symbols because we are going to define it 95833965Sjdp ourselves. */ 95933965Sjdp } 96033965Sjdp 96133965Sjdp return true; 96233965Sjdp} 96333965Sjdp 96433965Sjdp/* This is called when BFD has discovered a constructor. This is only 96533965Sjdp called for some object file formats--those which do not handle 96633965Sjdp constructors in some more clever fashion. This is similar to 96733965Sjdp adding an element to a set, but less general. */ 96833965Sjdp 96933965Sjdpstatic boolean 97033965Sjdpconstructor_callback (info, constructor, name, abfd, section, value) 97133965Sjdp struct bfd_link_info *info; 97233965Sjdp boolean constructor; 97333965Sjdp const char *name; 97433965Sjdp bfd *abfd; 97533965Sjdp asection *section; 97633965Sjdp bfd_vma value; 97733965Sjdp{ 97833965Sjdp char *s; 97933965Sjdp struct bfd_link_hash_entry *h; 98033965Sjdp char set_name[1 + sizeof "__CTOR_LIST__"]; 98133965Sjdp 98233965Sjdp if (config.warn_constructors) 98360484Sobrien einfo (_("%P: warning: global constructor %s used\n"), name); 98433965Sjdp 98533965Sjdp if (! config.build_constructors) 98633965Sjdp return true; 98733965Sjdp 98833965Sjdp /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a 98933965Sjdp useful error message. */ 99033965Sjdp if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL 99133965Sjdp && (link_info.relocateable 99233965Sjdp || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL)) 99360484Sobrien einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n")); 99433965Sjdp 99533965Sjdp s = set_name; 99633965Sjdp if (bfd_get_symbol_leading_char (abfd) != '\0') 99733965Sjdp *s++ = bfd_get_symbol_leading_char (abfd); 99833965Sjdp if (constructor) 99933965Sjdp strcpy (s, "__CTOR_LIST__"); 100033965Sjdp else 100133965Sjdp strcpy (s, "__DTOR_LIST__"); 100233965Sjdp 100333965Sjdp h = bfd_link_hash_lookup (info->hash, set_name, true, true, true); 100433965Sjdp if (h == (struct bfd_link_hash_entry *) NULL) 100560484Sobrien einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); 100633965Sjdp if (h->type == bfd_link_hash_new) 100733965Sjdp { 100833965Sjdp h->type = bfd_link_hash_undefined; 100933965Sjdp h->u.undef.abfd = abfd; 101033965Sjdp /* We don't call bfd_link_add_undef to add this to the list of 101133965Sjdp undefined symbols because we are going to define it 101233965Sjdp ourselves. */ 101333965Sjdp } 101433965Sjdp 101533965Sjdp ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value); 101633965Sjdp return true; 101733965Sjdp} 101833965Sjdp 101933965Sjdp/* A structure used by warning_callback to pass information through 102033965Sjdp bfd_map_over_sections. */ 102133965Sjdp 102233965Sjdpstruct warning_callback_info 102333965Sjdp{ 102433965Sjdp boolean found; 102533965Sjdp const char *warning; 102633965Sjdp const char *symbol; 102733965Sjdp asymbol **asymbols; 102833965Sjdp}; 102933965Sjdp 103033965Sjdp/* This is called when there is a reference to a warning symbol. */ 103133965Sjdp 103233965Sjdp/*ARGSUSED*/ 103333965Sjdpstatic boolean 103433965Sjdpwarning_callback (info, warning, symbol, abfd, section, address) 103560484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 103633965Sjdp const char *warning; 103733965Sjdp const char *symbol; 103833965Sjdp bfd *abfd; 103933965Sjdp asection *section; 104033965Sjdp bfd_vma address; 104133965Sjdp{ 104233965Sjdp /* This is a hack to support warn_multiple_gp. FIXME: This should 104333965Sjdp have a cleaner interface, but what? */ 104433965Sjdp if (! config.warn_multiple_gp 104533965Sjdp && strcmp (warning, "using multiple gp values") == 0) 104633965Sjdp return true; 104733965Sjdp 104833965Sjdp if (section != NULL) 104933965Sjdp einfo ("%C: %s\n", abfd, section, address, warning); 105033965Sjdp else if (abfd == NULL) 105133965Sjdp einfo ("%P: %s\n", warning); 105233965Sjdp else if (symbol == NULL) 105333965Sjdp einfo ("%B: %s\n", abfd, warning); 105433965Sjdp else 105533965Sjdp { 105633965Sjdp lang_input_statement_type *entry; 105733965Sjdp asymbol **asymbols; 105833965Sjdp struct warning_callback_info info; 105933965Sjdp 106033965Sjdp /* Look through the relocs to see if we can find a plausible 106133965Sjdp address. */ 106233965Sjdp 106333965Sjdp entry = (lang_input_statement_type *) abfd->usrdata; 106433965Sjdp if (entry != NULL && entry->asymbols != NULL) 106533965Sjdp asymbols = entry->asymbols; 106633965Sjdp else 106733965Sjdp { 106833965Sjdp long symsize; 106933965Sjdp long symbol_count; 107033965Sjdp 107133965Sjdp symsize = bfd_get_symtab_upper_bound (abfd); 107233965Sjdp if (symsize < 0) 107360484Sobrien einfo (_("%B%F: could not read symbols: %E\n"), abfd); 107433965Sjdp asymbols = (asymbol **) xmalloc (symsize); 107533965Sjdp symbol_count = bfd_canonicalize_symtab (abfd, asymbols); 107633965Sjdp if (symbol_count < 0) 107760484Sobrien einfo (_("%B%F: could not read symbols: %E\n"), abfd); 107833965Sjdp if (entry != NULL) 107933965Sjdp { 108033965Sjdp entry->asymbols = asymbols; 108133965Sjdp entry->symbol_count = symbol_count; 108233965Sjdp } 108333965Sjdp } 108433965Sjdp 108533965Sjdp info.found = false; 108633965Sjdp info.warning = warning; 108733965Sjdp info.symbol = symbol; 108833965Sjdp info.asymbols = asymbols; 108933965Sjdp bfd_map_over_sections (abfd, warning_find_reloc, (PTR) &info); 109033965Sjdp 109133965Sjdp if (! info.found) 109233965Sjdp einfo ("%B: %s\n", abfd, warning); 109333965Sjdp 109433965Sjdp if (entry == NULL) 109533965Sjdp free (asymbols); 109633965Sjdp } 109733965Sjdp 109833965Sjdp return true; 109933965Sjdp} 110033965Sjdp 110133965Sjdp/* This is called by warning_callback for each section. It checks the 110233965Sjdp relocs of the section to see if it can find a reference to the 110333965Sjdp symbol which triggered the warning. If it can, it uses the reloc 110433965Sjdp to give an error message with a file and line number. */ 110533965Sjdp 110633965Sjdpstatic void 110733965Sjdpwarning_find_reloc (abfd, sec, iarg) 110833965Sjdp bfd *abfd; 110933965Sjdp asection *sec; 111033965Sjdp PTR iarg; 111133965Sjdp{ 111233965Sjdp struct warning_callback_info *info = (struct warning_callback_info *) iarg; 111333965Sjdp long relsize; 111433965Sjdp arelent **relpp; 111533965Sjdp long relcount; 111633965Sjdp arelent **p, **pend; 111733965Sjdp 111833965Sjdp if (info->found) 111933965Sjdp return; 112033965Sjdp 112133965Sjdp relsize = bfd_get_reloc_upper_bound (abfd, sec); 112233965Sjdp if (relsize < 0) 112360484Sobrien einfo (_("%B%F: could not read relocs: %E\n"), abfd); 112433965Sjdp if (relsize == 0) 112533965Sjdp return; 112633965Sjdp 112733965Sjdp relpp = (arelent **) xmalloc (relsize); 112833965Sjdp relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols); 112933965Sjdp if (relcount < 0) 113060484Sobrien einfo (_("%B%F: could not read relocs: %E\n"), abfd); 113133965Sjdp 113233965Sjdp p = relpp; 113333965Sjdp pend = p + relcount; 113433965Sjdp for (; p < pend && *p != NULL; p++) 113533965Sjdp { 113633965Sjdp arelent *q = *p; 113733965Sjdp 113833965Sjdp if (q->sym_ptr_ptr != NULL 113933965Sjdp && *q->sym_ptr_ptr != NULL 114033965Sjdp && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0) 114133965Sjdp { 114233965Sjdp /* We found a reloc for the symbol we are looking for. */ 114333965Sjdp einfo ("%C: %s\n", abfd, sec, q->address, info->warning); 114433965Sjdp info->found = true; 114533965Sjdp break; 114633965Sjdp } 114733965Sjdp } 114833965Sjdp 114933965Sjdp free (relpp); 115033965Sjdp} 115133965Sjdp 115233965Sjdp/* This is called when an undefined symbol is found. */ 115333965Sjdp 115433965Sjdp/*ARGSUSED*/ 115533965Sjdpstatic boolean 115660484Sobrienundefined_symbol (info, name, abfd, section, address, fatal) 115760484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 115833965Sjdp const char *name; 115933965Sjdp bfd *abfd; 116033965Sjdp asection *section; 116133965Sjdp bfd_vma address; 116260484Sobrien boolean fatal; 116333965Sjdp{ 116433965Sjdp static char *error_name; 116533965Sjdp static unsigned int error_count; 116633965Sjdp 116733965Sjdp#define MAX_ERRORS_IN_A_ROW 5 116833965Sjdp 116933965Sjdp if (config.warn_once) 117033965Sjdp { 117133965Sjdp static struct bfd_hash_table *hash; 117233965Sjdp 117333965Sjdp /* Only warn once about a particular undefined symbol. */ 117433965Sjdp 117533965Sjdp if (hash == NULL) 117633965Sjdp { 117733965Sjdp hash = ((struct bfd_hash_table *) 117833965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 117933965Sjdp if (! bfd_hash_table_init (hash, bfd_hash_newfunc)) 118060484Sobrien einfo (_("%F%P: bfd_hash_table_init failed: %E\n")); 118133965Sjdp } 118233965Sjdp 118333965Sjdp if (bfd_hash_lookup (hash, name, false, false) != NULL) 118433965Sjdp return true; 118533965Sjdp 118633965Sjdp if (bfd_hash_lookup (hash, name, true, true) == NULL) 118760484Sobrien einfo (_("%F%P: bfd_hash_lookup failed: %E\n")); 118833965Sjdp } 118933965Sjdp 119033965Sjdp /* We never print more than a reasonable number of errors in a row 119133965Sjdp for a single symbol. */ 119233965Sjdp if (error_name != (char *) NULL 119333965Sjdp && strcmp (name, error_name) == 0) 119433965Sjdp ++error_count; 119533965Sjdp else 119633965Sjdp { 119733965Sjdp error_count = 0; 119833965Sjdp if (error_name != (char *) NULL) 119933965Sjdp free (error_name); 120033965Sjdp error_name = buystring (name); 120133965Sjdp } 120233965Sjdp 120333965Sjdp if (section != NULL) 120433965Sjdp { 120533965Sjdp if (error_count < MAX_ERRORS_IN_A_ROW) 120660484Sobrien { 120760484Sobrien einfo (_("%C: undefined reference to `%T'\n"), 120860484Sobrien abfd, section, address, name); 120960484Sobrien if (fatal) 121060484Sobrien einfo ("%X"); 121160484Sobrien } 121233965Sjdp else if (error_count == MAX_ERRORS_IN_A_ROW) 121360484Sobrien einfo (_("%D: more undefined references to `%T' follow\n"), 121433965Sjdp abfd, section, address, name); 121533965Sjdp } 121633965Sjdp else 121733965Sjdp { 121833965Sjdp if (error_count < MAX_ERRORS_IN_A_ROW) 121960484Sobrien { 122060484Sobrien einfo (_("%B: undefined reference to `%T'\n"), 122160484Sobrien abfd, name); 122260484Sobrien if (fatal) 122360484Sobrien einfo ("%X"); 122460484Sobrien } 122533965Sjdp else if (error_count == MAX_ERRORS_IN_A_ROW) 122660484Sobrien einfo (_("%B: more undefined references to `%T' follow\n"), 122733965Sjdp abfd, name); 122833965Sjdp } 122933965Sjdp 123033965Sjdp return true; 123133965Sjdp} 123233965Sjdp 123333965Sjdp/* This is called when a reloc overflows. */ 123433965Sjdp 123533965Sjdp/*ARGSUSED*/ 123633965Sjdpstatic boolean 123733965Sjdpreloc_overflow (info, name, reloc_name, addend, abfd, section, address) 123860484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 123933965Sjdp const char *name; 124033965Sjdp const char *reloc_name; 124133965Sjdp bfd_vma addend; 124233965Sjdp bfd *abfd; 124333965Sjdp asection *section; 124433965Sjdp bfd_vma address; 124533965Sjdp{ 124633965Sjdp if (abfd == (bfd *) NULL) 124760484Sobrien einfo (_("%P%X: generated")); 124833965Sjdp else 124933965Sjdp einfo ("%X%C:", abfd, section, address); 125060484Sobrien einfo (_(" relocation truncated to fit: %s %T"), reloc_name, name); 125133965Sjdp if (addend != 0) 125233965Sjdp einfo ("+%v", addend); 125333965Sjdp einfo ("\n"); 125433965Sjdp return true; 125533965Sjdp} 125633965Sjdp 125733965Sjdp/* This is called when a dangerous relocation is made. */ 125833965Sjdp 125933965Sjdp/*ARGSUSED*/ 126033965Sjdpstatic boolean 126133965Sjdpreloc_dangerous (info, message, abfd, section, address) 126260484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 126333965Sjdp const char *message; 126433965Sjdp bfd *abfd; 126533965Sjdp asection *section; 126633965Sjdp bfd_vma address; 126733965Sjdp{ 126833965Sjdp if (abfd == (bfd *) NULL) 126960484Sobrien einfo (_("%P%X: generated")); 127033965Sjdp else 127133965Sjdp einfo ("%X%C:", abfd, section, address); 127260484Sobrien einfo (_("dangerous relocation: %s\n"), message); 127333965Sjdp return true; 127433965Sjdp} 127533965Sjdp 127633965Sjdp/* This is called when a reloc is being generated attached to a symbol 127733965Sjdp that is not being output. */ 127833965Sjdp 127933965Sjdp/*ARGSUSED*/ 128033965Sjdpstatic boolean 128133965Sjdpunattached_reloc (info, name, abfd, section, address) 128260484Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED; 128333965Sjdp const char *name; 128433965Sjdp bfd *abfd; 128533965Sjdp asection *section; 128633965Sjdp bfd_vma address; 128733965Sjdp{ 128833965Sjdp if (abfd == (bfd *) NULL) 128960484Sobrien einfo (_("%P%X: generated")); 129033965Sjdp else 129133965Sjdp einfo ("%X%C:", abfd, section, address); 129260484Sobrien einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name); 129333965Sjdp return true; 129433965Sjdp} 129533965Sjdp 129633965Sjdp/* This is called if link_info.notice_all is set, or when a symbol in 129733965Sjdp link_info.notice_hash is found. Symbols are put in notice_hash 129833965Sjdp using the -y option. */ 129933965Sjdp 130033965Sjdpstatic boolean 130133965Sjdpnotice (info, name, abfd, section, value) 130233965Sjdp struct bfd_link_info *info; 130333965Sjdp const char *name; 130433965Sjdp bfd *abfd; 130533965Sjdp asection *section; 130633965Sjdp bfd_vma value; 130733965Sjdp{ 130833965Sjdp if (! info->notice_all 130933965Sjdp || (info->notice_hash != NULL 131033965Sjdp && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL)) 131160484Sobrien { 131260484Sobrien if (bfd_is_und_section (section)) 131360484Sobrien einfo ("%B: reference to %s\n", abfd, name); 131460484Sobrien else 131560484Sobrien einfo ("%B: definition of %s\n", abfd, name); 131660484Sobrien } 131733965Sjdp 131833965Sjdp if (command_line.cref || nocrossref_list != NULL) 131933965Sjdp add_cref (name, abfd, section, value); 132033965Sjdp 132133965Sjdp return true; 132233965Sjdp} 1323