ldmain.c revision 33965
133965Sjdp/* Main program of GNU linker. 233965Sjdp Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. 333965Sjdp Written by Steve Chamberlain steve@cygnus.com 433965Sjdp 533965SjdpThis file is part of GLD, the Gnu Linker. 633965Sjdp 733965SjdpGLD is free software; you can redistribute it and/or modify 833965Sjdpit under the terms of the GNU General Public License as published by 933965Sjdpthe Free Software Foundation; either version 2, or (at your option) 1033965Sjdpany later version. 1133965Sjdp 1233965SjdpGLD is distributed in the hope that it will be useful, 1333965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1433965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965SjdpGNU General Public License for more details. 1633965Sjdp 1733965SjdpYou should have received a copy of the GNU General Public License 1833965Sjdpalong with GLD; see the file COPYING. If not, write to the Free 1933965SjdpSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2033965Sjdp02111-1307, USA. */ 2133965Sjdp 2233965Sjdp#include "bfd.h" 2333965Sjdp#include "sysdep.h" 2433965Sjdp#include <stdio.h> 2533965Sjdp#include <ctype.h> 2633965Sjdp#include "libiberty.h" 2733965Sjdp#include "progress.h" 2833965Sjdp#include "bfdlink.h" 2933965Sjdp 3033965Sjdp#include "ld.h" 3133965Sjdp#include "ldmain.h" 3233965Sjdp#include "ldmisc.h" 3333965Sjdp#include "ldwrite.h" 3433965Sjdp#include "ldgram.h" 3533965Sjdp#include "ldexp.h" 3633965Sjdp#include "ldlang.h" 3733965Sjdp#include "ldemul.h" 3833965Sjdp#include "ldlex.h" 3933965Sjdp#include "ldfile.h" 4033965Sjdp#include "ldctor.h" 4133965Sjdp 4233965Sjdp/* Somewhere above, sys/stat.h got included . . . . */ 4333965Sjdp#if !defined(S_ISDIR) && defined(S_IFDIR) 4433965Sjdp#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 4533965Sjdp#endif 4633965Sjdp 4733965Sjdp#include <string.h> 4833965Sjdp 4933965Sjdp#ifdef HAVE_SBRK 5033965Sjdp#ifdef NEED_DECLARATION_SBRK 5133965Sjdpextern PTR sbrk (); 5233965Sjdp#endif 5333965Sjdp#endif 5433965Sjdp 5533965Sjdpstatic char *get_emulation PARAMS ((int, char **)); 5633965Sjdpstatic void set_scripts_dir PARAMS ((void)); 5733965Sjdp 5833965Sjdp/* EXPORTS */ 5933965Sjdp 6033965Sjdpchar *default_target; 6133965Sjdpconst char *output_filename = "a.out"; 6233965Sjdp 6333965Sjdp/* Name this program was invoked by. */ 6433965Sjdpchar *program_name; 6533965Sjdp 6633965Sjdp/* The file that we're creating */ 6733965Sjdpbfd *output_bfd = 0; 6833965Sjdp 6933965Sjdp/* Set by -G argument, for MIPS ECOFF target. */ 7033965Sjdpint g_switch_value = 8; 7133965Sjdp 7233965Sjdp/* Nonzero means print names of input files as processed. */ 7333965Sjdpboolean trace_files; 7433965Sjdp 7533965Sjdp/* Nonzero means same, but note open failures, too. */ 7633965Sjdpboolean trace_file_tries; 7733965Sjdp 7833965Sjdp/* Nonzero means version number was printed, so exit successfully 7933965Sjdp instead of complaining if no input files are given. */ 8033965Sjdpboolean version_printed; 8133965Sjdp 8233965Sjdp/* Nonzero means link in every member of an archive. */ 8333965Sjdpboolean whole_archive; 8433965Sjdp 8533965Sjdpargs_type command_line; 8633965Sjdp 8733965Sjdpld_config_type config; 8833965Sjdp 8933965Sjdpstatic void remove_output PARAMS ((void)); 9033965Sjdpstatic boolean check_for_scripts_dir PARAMS ((char *dir)); 9133965Sjdpstatic boolean add_archive_element PARAMS ((struct bfd_link_info *, bfd *, 9233965Sjdp const char *)); 9333965Sjdpstatic boolean multiple_definition PARAMS ((struct bfd_link_info *, 9433965Sjdp const char *, 9533965Sjdp bfd *, asection *, bfd_vma, 9633965Sjdp bfd *, asection *, bfd_vma)); 9733965Sjdpstatic boolean multiple_common PARAMS ((struct bfd_link_info *, 9833965Sjdp const char *, bfd *, 9933965Sjdp enum bfd_link_hash_type, bfd_vma, 10033965Sjdp bfd *, enum bfd_link_hash_type, 10133965Sjdp bfd_vma)); 10233965Sjdpstatic boolean add_to_set PARAMS ((struct bfd_link_info *, 10333965Sjdp struct bfd_link_hash_entry *, 10433965Sjdp bfd_reloc_code_real_type, 10533965Sjdp bfd *, asection *, bfd_vma)); 10633965Sjdpstatic boolean constructor_callback PARAMS ((struct bfd_link_info *, 10733965Sjdp boolean constructor, 10833965Sjdp const char *name, 10933965Sjdp bfd *, asection *, bfd_vma)); 11033965Sjdpstatic boolean warning_callback PARAMS ((struct bfd_link_info *, 11133965Sjdp const char *, const char *, bfd *, 11233965Sjdp asection *, bfd_vma)); 11333965Sjdpstatic void warning_find_reloc PARAMS ((bfd *, asection *, PTR)); 11433965Sjdpstatic boolean undefined_symbol PARAMS ((struct bfd_link_info *, 11533965Sjdp const char *, bfd *, 11633965Sjdp asection *, bfd_vma)); 11733965Sjdpstatic boolean reloc_overflow PARAMS ((struct bfd_link_info *, const char *, 11833965Sjdp const char *, bfd_vma, 11933965Sjdp bfd *, asection *, bfd_vma)); 12033965Sjdpstatic boolean reloc_dangerous PARAMS ((struct bfd_link_info *, const char *, 12133965Sjdp bfd *, asection *, bfd_vma)); 12233965Sjdpstatic boolean unattached_reloc PARAMS ((struct bfd_link_info *, 12333965Sjdp const char *, bfd *, asection *, 12433965Sjdp bfd_vma)); 12533965Sjdpstatic boolean notice PARAMS ((struct bfd_link_info *, const char *, 12633965Sjdp bfd *, asection *, bfd_vma)); 12733965Sjdp 12833965Sjdpstatic struct bfd_link_callbacks link_callbacks = 12933965Sjdp{ 13033965Sjdp add_archive_element, 13133965Sjdp multiple_definition, 13233965Sjdp multiple_common, 13333965Sjdp add_to_set, 13433965Sjdp constructor_callback, 13533965Sjdp warning_callback, 13633965Sjdp undefined_symbol, 13733965Sjdp reloc_overflow, 13833965Sjdp reloc_dangerous, 13933965Sjdp unattached_reloc, 14033965Sjdp notice 14133965Sjdp}; 14233965Sjdp 14333965Sjdpstruct bfd_link_info link_info; 14433965Sjdp 14533965Sjdpstatic void 14633965Sjdpremove_output () 14733965Sjdp{ 14833965Sjdp if (output_filename) 14933965Sjdp { 15033965Sjdp if (output_bfd && output_bfd->iostream) 15133965Sjdp fclose((FILE *)(output_bfd->iostream)); 15233965Sjdp if (delete_output_file_on_failure) 15333965Sjdp unlink (output_filename); 15433965Sjdp } 15533965Sjdp} 15633965Sjdp 15733965Sjdpint 15833965Sjdpmain (argc, argv) 15933965Sjdp int argc; 16033965Sjdp char **argv; 16133965Sjdp{ 16233965Sjdp char *emulation; 16333965Sjdp long start_time = get_run_time (); 16433965Sjdp 16533965Sjdp program_name = argv[0]; 16633965Sjdp xmalloc_set_program_name (program_name); 16733965Sjdp 16833965Sjdp START_PROGRESS (program_name, 0); 16933965Sjdp 17033965Sjdp bfd_init (); 17133965Sjdp 17233965Sjdp bfd_set_error_program_name (program_name); 17333965Sjdp 17433965Sjdp xatexit (remove_output); 17533965Sjdp 17633965Sjdp /* Set the default BFD target based on the configured target. Doing 17733965Sjdp this permits the linker to be configured for a particular target, 17833965Sjdp and linked against a shared BFD library which was configured for 17933965Sjdp a different target. The macro TARGET is defined by Makefile. */ 18033965Sjdp if (! bfd_set_default_target (TARGET)) 18133965Sjdp { 18233965Sjdp einfo ("%X%P: can't set BFD default target to `%s': %E\n", TARGET); 18333965Sjdp xexit (1); 18433965Sjdp } 18533965Sjdp 18633965Sjdp /* Initialize the data about options. */ 18733965Sjdp trace_files = trace_file_tries = version_printed = false; 18833965Sjdp whole_archive = false; 18933965Sjdp config.build_constructors = true; 19033965Sjdp config.dynamic_link = false; 19133965Sjdp command_line.force_common_definition = false; 19233965Sjdp command_line.interpreter = NULL; 19333965Sjdp command_line.rpath = NULL; 19433965Sjdp 19533965Sjdp link_info.callbacks = &link_callbacks; 19633965Sjdp link_info.relocateable = false; 19733965Sjdp link_info.shared = false; 19833965Sjdp link_info.symbolic = false; 19933965Sjdp link_info.static_link = false; 20033965Sjdp link_info.traditional_format = false; 20133965Sjdp link_info.strip = strip_none; 20233965Sjdp link_info.discard = discard_none; 20333965Sjdp link_info.keep_memory = true; 20433965Sjdp link_info.input_bfds = NULL; 20533965Sjdp link_info.create_object_symbols_section = NULL; 20633965Sjdp link_info.hash = NULL; 20733965Sjdp link_info.keep_hash = NULL; 20833965Sjdp link_info.notice_all = false; 20933965Sjdp link_info.notice_hash = NULL; 21033965Sjdp link_info.wrap_hash = NULL; 21133965Sjdp 21233965Sjdp ldfile_add_arch (""); 21333965Sjdp 21433965Sjdp config.make_executable = true; 21533965Sjdp force_make_executable = false; 21633965Sjdp config.magic_demand_paged = true; 21733965Sjdp config.text_read_only = true; 21833965Sjdp config.make_executable = true; 21933965Sjdp 22033965Sjdp emulation = get_emulation (argc, argv); 22133965Sjdp ldemul_choose_mode (emulation); 22233965Sjdp default_target = ldemul_choose_target (); 22333965Sjdp lang_init (); 22433965Sjdp ldemul_before_parse (); 22533965Sjdp lang_has_input_file = false; 22633965Sjdp parse_args (argc, argv); 22733965Sjdp 22833965Sjdp ldemul_set_symbols (); 22933965Sjdp 23033965Sjdp if (link_info.relocateable) 23133965Sjdp { 23233965Sjdp if (command_line.relax) 23333965Sjdp einfo ("%P%F: -relax and -r may not be used together\n"); 23433965Sjdp if (link_info.shared) 23533965Sjdp einfo ("%P%F: -r and -shared may not be used together\n"); 23633965Sjdp } 23733965Sjdp 23833965Sjdp /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I 23933965Sjdp don't see how else this can be handled, since in this case we 24033965Sjdp must preserve all externally visible symbols. */ 24133965Sjdp if (link_info.relocateable && link_info.strip == strip_all) 24233965Sjdp { 24333965Sjdp link_info.strip = strip_debugger; 24433965Sjdp if (link_info.discard == discard_none) 24533965Sjdp link_info.discard = discard_all; 24633965Sjdp } 24733965Sjdp 24833965Sjdp /* This essentially adds another -L directory so this must be done after 24933965Sjdp the -L's in argv have been processed. */ 25033965Sjdp set_scripts_dir (); 25133965Sjdp 25233965Sjdp if (had_script == false) 25333965Sjdp { 25433965Sjdp /* Read the emulation's appropriate default script. */ 25533965Sjdp int isfile; 25633965Sjdp char *s = ldemul_get_script (&isfile); 25733965Sjdp 25833965Sjdp if (isfile) 25933965Sjdp ldfile_open_command_file (s); 26033965Sjdp else 26133965Sjdp { 26233965Sjdp if (trace_file_tries) 26333965Sjdp { 26433965Sjdp info_msg ("using internal linker script:\n"); 26533965Sjdp info_msg ("==================================================\n"); 26633965Sjdp info_msg (s); 26733965Sjdp info_msg ("\n==================================================\n"); 26833965Sjdp } 26933965Sjdp lex_string = s; 27033965Sjdp lex_redirect (s); 27133965Sjdp } 27233965Sjdp parser_input = input_script; 27333965Sjdp yyparse (); 27433965Sjdp lex_string = NULL; 27533965Sjdp } 27633965Sjdp 27733965Sjdp lang_final (); 27833965Sjdp 27933965Sjdp if (lang_has_input_file == false) 28033965Sjdp { 28133965Sjdp if (version_printed) 28233965Sjdp xexit (0); 28333965Sjdp einfo ("%P%F: no input files\n"); 28433965Sjdp } 28533965Sjdp 28633965Sjdp if (trace_files) 28733965Sjdp { 28833965Sjdp info_msg ("%P: mode %s\n", emulation); 28933965Sjdp } 29033965Sjdp 29133965Sjdp ldemul_after_parse (); 29233965Sjdp 29333965Sjdp 29433965Sjdp if (config.map_filename) 29533965Sjdp { 29633965Sjdp if (strcmp (config.map_filename, "-") == 0) 29733965Sjdp { 29833965Sjdp config.map_file = stdout; 29933965Sjdp } 30033965Sjdp else 30133965Sjdp { 30233965Sjdp config.map_file = fopen (config.map_filename, FOPEN_WT); 30333965Sjdp if (config.map_file == (FILE *) NULL) 30433965Sjdp { 30533965Sjdp bfd_set_error (bfd_error_system_call); 30633965Sjdp einfo ("%P%F: cannot open map file %s: %E\n", 30733965Sjdp config.map_filename); 30833965Sjdp } 30933965Sjdp } 31033965Sjdp } 31133965Sjdp 31233965Sjdp 31333965Sjdp lang_process (); 31433965Sjdp 31533965Sjdp /* Print error messages for any missing symbols, for any warning 31633965Sjdp symbols, and possibly multiple definitions */ 31733965Sjdp 31833965Sjdp 31933965Sjdp if (config.text_read_only) 32033965Sjdp { 32133965Sjdp /* Look for a text section and mark the readonly attribute in it */ 32233965Sjdp asection *found = bfd_get_section_by_name (output_bfd, ".text"); 32333965Sjdp 32433965Sjdp if (found != (asection *) NULL) 32533965Sjdp { 32633965Sjdp found->flags |= SEC_READONLY; 32733965Sjdp } 32833965Sjdp } 32933965Sjdp 33033965Sjdp if (link_info.relocateable) 33133965Sjdp output_bfd->flags &= ~EXEC_P; 33233965Sjdp else 33333965Sjdp output_bfd->flags |= EXEC_P; 33433965Sjdp 33533965Sjdp ldwrite (); 33633965Sjdp 33733965Sjdp if (config.map_file != NULL) 33833965Sjdp lang_map (); 33933965Sjdp if (command_line.cref) 34033965Sjdp output_cref (config.map_file != NULL ? config.map_file : stdout); 34133965Sjdp if (nocrossref_list != NULL) 34233965Sjdp check_nocrossrefs (); 34333965Sjdp 34433965Sjdp /* Even if we're producing relocateable output, some non-fatal errors should 34533965Sjdp be reported in the exit status. (What non-fatal errors, if any, do we 34633965Sjdp want to ignore for relocateable output?) */ 34733965Sjdp 34833965Sjdp if (config.make_executable == false && force_make_executable == false) 34933965Sjdp { 35033965Sjdp if (trace_files == true) 35133965Sjdp { 35233965Sjdp einfo ("%P: link errors found, deleting executable `%s'\n", 35333965Sjdp output_filename); 35433965Sjdp } 35533965Sjdp 35633965Sjdp /* The file will be removed by remove_output. */ 35733965Sjdp 35833965Sjdp xexit (1); 35933965Sjdp } 36033965Sjdp else 36133965Sjdp { 36233965Sjdp if (! bfd_close (output_bfd)) 36333965Sjdp einfo ("%F%B: final close failed: %E\n", output_bfd); 36433965Sjdp 36533965Sjdp /* If the --force-exe-suffix is enabled, and we're making an 36633965Sjdp executable file and it doesn't end in .exe, copy it to one which does. */ 36733965Sjdp 36833965Sjdp if (! link_info.relocateable && command_line.force_exe_suffix) 36933965Sjdp { 37033965Sjdp int len = strlen (output_filename); 37133965Sjdp if (len < 4 37233965Sjdp || (strcasecmp (output_filename + len - 4, ".exe") != 0 37333965Sjdp && strcasecmp (output_filename + len - 4, ".dll") != 0)) 37433965Sjdp { 37533965Sjdp FILE *src; 37633965Sjdp FILE *dst; 37733965Sjdp const int bsize = 4096; 37833965Sjdp char *buf = xmalloc (bsize); 37933965Sjdp int l; 38033965Sjdp char *dst_name = xmalloc (len + 5); 38133965Sjdp strcpy (dst_name, output_filename); 38233965Sjdp strcat (dst_name, ".exe"); 38333965Sjdp src = fopen (output_filename, FOPEN_RB); 38433965Sjdp dst = fopen (dst_name, FOPEN_WB); 38533965Sjdp 38633965Sjdp if (!src) 38733965Sjdp einfo ("%X%P: unable to open for source of copy `%s'\n", output_filename); 38833965Sjdp if (!dst) 38933965Sjdp einfo ("%X%P: unable to open for destination of copy `%s'\n", dst_name); 39033965Sjdp while ((l = fread (buf, 1, bsize, src)) > 0) 39133965Sjdp { 39233965Sjdp int done = fwrite (buf, 1, l, dst); 39333965Sjdp if (done != l) 39433965Sjdp { 39533965Sjdp einfo ("%P: Error writing file `%s'\n", dst_name); 39633965Sjdp } 39733965Sjdp } 39833965Sjdp fclose (src); 39933965Sjdp if (fclose (dst) == EOF) 40033965Sjdp { 40133965Sjdp einfo ("%P: Error closing file `%s'\n", dst_name); 40233965Sjdp } 40333965Sjdp free (dst_name); 40433965Sjdp free (buf); 40533965Sjdp } 40633965Sjdp } 40733965Sjdp } 40833965Sjdp 40933965Sjdp END_PROGRESS (program_name); 41033965Sjdp 41133965Sjdp if (config.stats) 41233965Sjdp { 41333965Sjdp extern char **environ; 41433965Sjdp#ifdef HAVE_SBRK 41533965Sjdp char *lim = (char *) sbrk (0); 41633965Sjdp#endif 41733965Sjdp long run_time = get_run_time () - start_time; 41833965Sjdp 41933965Sjdp fprintf (stderr, "%s: total time in link: %ld.%06ld\n", 42033965Sjdp program_name, run_time / 1000000, run_time % 1000000); 42133965Sjdp#ifdef HAVE_SBRK 42233965Sjdp fprintf (stderr, "%s: data size %ld\n", program_name, 42333965Sjdp (long) (lim - (char *) &environ)); 42433965Sjdp#endif 42533965Sjdp } 42633965Sjdp 42733965Sjdp /* Prevent remove_output from doing anything, after a successful link. */ 42833965Sjdp output_filename = NULL; 42933965Sjdp 43033965Sjdp xexit (0); 43133965Sjdp return 0; 43233965Sjdp} 43333965Sjdp 43433965Sjdp/* We need to find any explicitly given emulation in order to initialize the 43533965Sjdp state that's needed by the lex&yacc argument parser (parse_args). */ 43633965Sjdp 43733965Sjdpstatic char * 43833965Sjdpget_emulation (argc, argv) 43933965Sjdp int argc; 44033965Sjdp char **argv; 44133965Sjdp{ 44233965Sjdp char *emulation; 44333965Sjdp int i; 44433965Sjdp 44533965Sjdp emulation = getenv (EMULATION_ENVIRON); 44633965Sjdp if (emulation == NULL) 44733965Sjdp emulation = DEFAULT_EMULATION; 44833965Sjdp 44933965Sjdp for (i = 1; i < argc; i++) 45033965Sjdp { 45133965Sjdp if (!strncmp (argv[i], "-m", 2)) 45233965Sjdp { 45333965Sjdp if (argv[i][2] == '\0') 45433965Sjdp { 45533965Sjdp /* -m EMUL */ 45633965Sjdp if (i < argc - 1) 45733965Sjdp { 45833965Sjdp emulation = argv[i + 1]; 45933965Sjdp i++; 46033965Sjdp } 46133965Sjdp else 46233965Sjdp { 46333965Sjdp einfo("%P%F: missing argument to -m\n"); 46433965Sjdp } 46533965Sjdp } 46633965Sjdp else if (strcmp (argv[i], "-mips1") == 0 46733965Sjdp || strcmp (argv[i], "-mips2") == 0 46833965Sjdp || strcmp (argv[i], "-mips3") == 0 46933965Sjdp || strcmp (argv[i], "-mips4") == 0) 47033965Sjdp { 47133965Sjdp /* FIXME: The arguments -mips1, -mips2 and -mips3 are 47233965Sjdp passed to the linker by some MIPS compilers. They 47333965Sjdp generally tell the linker to use a slightly different 47433965Sjdp library path. Perhaps someday these should be 47533965Sjdp implemented as emulations; until then, we just ignore 47633965Sjdp the arguments and hope that nobody ever creates 47733965Sjdp emulations named ips1, ips2 or ips3. */ 47833965Sjdp } 47933965Sjdp else if (strcmp (argv[i], "-m486") == 0) 48033965Sjdp { 48133965Sjdp /* FIXME: The argument -m486 is passed to the linker on 48233965Sjdp some Linux systems. Hope that nobody creates an 48333965Sjdp emulation named 486. */ 48433965Sjdp } 48533965Sjdp else 48633965Sjdp { 48733965Sjdp /* -mEMUL */ 48833965Sjdp emulation = &argv[i][2]; 48933965Sjdp } 49033965Sjdp } 49133965Sjdp } 49233965Sjdp 49333965Sjdp return emulation; 49433965Sjdp} 49533965Sjdp 49633965Sjdp/* If directory DIR contains an "ldscripts" subdirectory, 49733965Sjdp add DIR to the library search path and return true, 49833965Sjdp else return false. */ 49933965Sjdp 50033965Sjdpstatic boolean 50133965Sjdpcheck_for_scripts_dir (dir) 50233965Sjdp char *dir; 50333965Sjdp{ 50433965Sjdp size_t dirlen; 50533965Sjdp char *buf; 50633965Sjdp struct stat s; 50733965Sjdp boolean res; 50833965Sjdp 50933965Sjdp dirlen = strlen (dir); 51033965Sjdp /* sizeof counts the terminating NUL. */ 51133965Sjdp buf = (char *) xmalloc (dirlen + sizeof("/ldscripts")); 51233965Sjdp sprintf (buf, "%s/ldscripts", dir); 51333965Sjdp 51433965Sjdp res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode); 51533965Sjdp free (buf); 51633965Sjdp if (res) 51733965Sjdp ldfile_add_library_path (dir, false); 51833965Sjdp return res; 51933965Sjdp} 52033965Sjdp 52133965Sjdp/* Set the default directory for finding script files. 52233965Sjdp Libraries will be searched for here too, but that's ok. 52333965Sjdp We look for the "ldscripts" directory in: 52433965Sjdp 52533965Sjdp SCRIPTDIR (passed from Makefile) 52633965Sjdp the dir where this program is (for using it from the build tree) 52733965Sjdp the dir where this program is/../lib (for installing the tool suite elsewhere) */ 52833965Sjdp 52933965Sjdpstatic void 53033965Sjdpset_scripts_dir () 53133965Sjdp{ 53233965Sjdp char *end, *dir; 53333965Sjdp size_t dirlen; 53433965Sjdp 53533965Sjdp if (check_for_scripts_dir (SCRIPTDIR)) 53633965Sjdp return; /* We've been installed normally. */ 53733965Sjdp 53833965Sjdp /* Look for "ldscripts" in the dir where our binary is. */ 53933965Sjdp end = strrchr (program_name, '/'); 54033965Sjdp 54133965Sjdp if (end == NULL) 54233965Sjdp { 54333965Sjdp /* Don't look for ldscripts in the current directory. There is 54433965Sjdp too much potential for confusion. */ 54533965Sjdp return; 54633965Sjdp } 54733965Sjdp 54833965Sjdp dirlen = end - program_name; 54933965Sjdp /* Make a copy of program_name in dir. 55033965Sjdp Leave room for later "/../lib". */ 55133965Sjdp dir = (char *) xmalloc (dirlen + 8); 55233965Sjdp strncpy (dir, program_name, dirlen); 55333965Sjdp dir[dirlen] = '\0'; 55433965Sjdp 55533965Sjdp if (check_for_scripts_dir (dir)) 55633965Sjdp return; /* Don't free dir. */ 55733965Sjdp 55833965Sjdp /* Look for "ldscripts" in <the dir where our binary is>/../lib. */ 55933965Sjdp strcpy (dir + dirlen, "/../lib"); 56033965Sjdp if (check_for_scripts_dir (dir)) 56133965Sjdp return; 56233965Sjdp 56333965Sjdp free (dir); /* Well, we tried. */ 56433965Sjdp} 56533965Sjdp 56633965Sjdpvoid 56733965Sjdpadd_ysym (name) 56833965Sjdp const char *name; 56933965Sjdp{ 57033965Sjdp if (link_info.notice_hash == (struct bfd_hash_table *) NULL) 57133965Sjdp { 57233965Sjdp link_info.notice_hash = ((struct bfd_hash_table *) 57333965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 57433965Sjdp if (! bfd_hash_table_init_n (link_info.notice_hash, 57533965Sjdp bfd_hash_newfunc, 57633965Sjdp 61)) 57733965Sjdp einfo ("%P%F: bfd_hash_table_init failed: %E\n"); 57833965Sjdp } 57933965Sjdp 58033965Sjdp if (bfd_hash_lookup (link_info.notice_hash, name, true, true) 58133965Sjdp == (struct bfd_hash_entry *) NULL) 58233965Sjdp einfo ("%P%F: bfd_hash_lookup failed: %E\n"); 58333965Sjdp} 58433965Sjdp 58533965Sjdp/* Record a symbol to be wrapped, from the --wrap option. */ 58633965Sjdp 58733965Sjdpvoid 58833965Sjdpadd_wrap (name) 58933965Sjdp const char *name; 59033965Sjdp{ 59133965Sjdp if (link_info.wrap_hash == NULL) 59233965Sjdp { 59333965Sjdp link_info.wrap_hash = ((struct bfd_hash_table *) 59433965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 59533965Sjdp if (! bfd_hash_table_init_n (link_info.wrap_hash, 59633965Sjdp bfd_hash_newfunc, 59733965Sjdp 61)) 59833965Sjdp einfo ("%P%F: bfd_hash_table_init failed: %E\n"); 59933965Sjdp } 60033965Sjdp if (bfd_hash_lookup (link_info.wrap_hash, name, true, true) == NULL) 60133965Sjdp einfo ("%P%F: bfd_hash_lookup failed: %E\n"); 60233965Sjdp} 60333965Sjdp 60433965Sjdp/* Handle the -retain-symbols-file option. */ 60533965Sjdp 60633965Sjdpvoid 60733965Sjdpadd_keepsyms_file (filename) 60833965Sjdp const char *filename; 60933965Sjdp{ 61033965Sjdp FILE *file; 61133965Sjdp char *buf; 61233965Sjdp size_t bufsize; 61333965Sjdp int c; 61433965Sjdp 61533965Sjdp if (link_info.strip == strip_some) 61633965Sjdp einfo ("%X%P: error: duplicate retain-symbols-file\n"); 61733965Sjdp 61833965Sjdp file = fopen (filename, "r"); 61933965Sjdp if (file == (FILE *) NULL) 62033965Sjdp { 62133965Sjdp bfd_set_error (bfd_error_system_call); 62233965Sjdp einfo ("%X%P: %s: %E\n", filename); 62333965Sjdp return; 62433965Sjdp } 62533965Sjdp 62633965Sjdp link_info.keep_hash = ((struct bfd_hash_table *) 62733965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 62833965Sjdp if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc)) 62933965Sjdp einfo ("%P%F: bfd_hash_table_init failed: %E\n"); 63033965Sjdp 63133965Sjdp bufsize = 100; 63233965Sjdp buf = (char *) xmalloc (bufsize); 63333965Sjdp 63433965Sjdp c = getc (file); 63533965Sjdp while (c != EOF) 63633965Sjdp { 63733965Sjdp while (isspace (c)) 63833965Sjdp c = getc (file); 63933965Sjdp 64033965Sjdp if (c != EOF) 64133965Sjdp { 64233965Sjdp size_t len = 0; 64333965Sjdp 64433965Sjdp while (! isspace (c) && c != EOF) 64533965Sjdp { 64633965Sjdp buf[len] = c; 64733965Sjdp ++len; 64833965Sjdp if (len >= bufsize) 64933965Sjdp { 65033965Sjdp bufsize *= 2; 65133965Sjdp buf = xrealloc (buf, bufsize); 65233965Sjdp } 65333965Sjdp c = getc (file); 65433965Sjdp } 65533965Sjdp 65633965Sjdp buf[len] = '\0'; 65733965Sjdp 65833965Sjdp if (bfd_hash_lookup (link_info.keep_hash, buf, true, true) 65933965Sjdp == (struct bfd_hash_entry *) NULL) 66033965Sjdp einfo ("%P%F: bfd_hash_lookup for insertion failed: %E\n"); 66133965Sjdp } 66233965Sjdp } 66333965Sjdp 66433965Sjdp if (link_info.strip != strip_none) 66533965Sjdp einfo ("%P: `-retain-symbols-file' overrides `-s' and `-S'\n"); 66633965Sjdp 66733965Sjdp link_info.strip = strip_some; 66833965Sjdp} 66933965Sjdp 67033965Sjdp/* Callbacks from the BFD linker routines. */ 67133965Sjdp 67233965Sjdp/* This is called when BFD has decided to include an archive member in 67333965Sjdp a link. */ 67433965Sjdp 67533965Sjdp/*ARGSUSED*/ 67633965Sjdpstatic boolean 67733965Sjdpadd_archive_element (info, abfd, name) 67833965Sjdp struct bfd_link_info *info; 67933965Sjdp bfd *abfd; 68033965Sjdp const char *name; 68133965Sjdp{ 68233965Sjdp lang_input_statement_type *input; 68333965Sjdp 68433965Sjdp input = ((lang_input_statement_type *) 68533965Sjdp xmalloc (sizeof (lang_input_statement_type))); 68633965Sjdp input->filename = abfd->filename; 68733965Sjdp input->local_sym_name = abfd->filename; 68833965Sjdp input->the_bfd = abfd; 68933965Sjdp input->asymbols = NULL; 69033965Sjdp input->next = NULL; 69133965Sjdp input->just_syms_flag = false; 69233965Sjdp input->loaded = false; 69333965Sjdp input->search_dirs_flag = false; 69433965Sjdp 69533965Sjdp /* FIXME: The following fields are not set: header.next, 69633965Sjdp header.type, closed, passive_position, symbol_count, 69733965Sjdp next_real_file, is_archive, target, real. This bit of code is 69833965Sjdp from the old decode_library_subfile function. I don't know 69933965Sjdp whether any of those fields matters. */ 70033965Sjdp 70133965Sjdp ldlang_add_file (input); 70233965Sjdp 70333965Sjdp if (config.map_file != (FILE *) NULL) 70433965Sjdp { 70533965Sjdp static boolean header_printed; 70633965Sjdp struct bfd_link_hash_entry *h; 70733965Sjdp bfd *from; 70833965Sjdp int len; 70933965Sjdp 71033965Sjdp h = bfd_link_hash_lookup (link_info.hash, name, false, false, true); 71133965Sjdp 71233965Sjdp if (h == NULL) 71333965Sjdp from = NULL; 71433965Sjdp else 71533965Sjdp { 71633965Sjdp switch (h->type) 71733965Sjdp { 71833965Sjdp default: 71933965Sjdp from = NULL; 72033965Sjdp break; 72133965Sjdp 72233965Sjdp case bfd_link_hash_defined: 72333965Sjdp case bfd_link_hash_defweak: 72433965Sjdp from = h->u.def.section->owner; 72533965Sjdp break; 72633965Sjdp 72733965Sjdp case bfd_link_hash_undefined: 72833965Sjdp case bfd_link_hash_undefweak: 72933965Sjdp from = h->u.undef.abfd; 73033965Sjdp break; 73133965Sjdp 73233965Sjdp case bfd_link_hash_common: 73333965Sjdp from = h->u.c.p->section->owner; 73433965Sjdp break; 73533965Sjdp } 73633965Sjdp } 73733965Sjdp 73833965Sjdp if (! header_printed) 73933965Sjdp { 74033965Sjdp char buf[100]; 74133965Sjdp 74233965Sjdp sprintf (buf, "%-29s %s\n\n", "Archive member included", 74333965Sjdp "because of file (symbol)"); 74433965Sjdp minfo ("%s", buf); 74533965Sjdp header_printed = true; 74633965Sjdp } 74733965Sjdp 74833965Sjdp if (bfd_my_archive (abfd) == NULL) 74933965Sjdp { 75033965Sjdp minfo ("%s", bfd_get_filename (abfd)); 75133965Sjdp len = strlen (bfd_get_filename (abfd)); 75233965Sjdp } 75333965Sjdp else 75433965Sjdp { 75533965Sjdp minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)), 75633965Sjdp bfd_get_filename (abfd)); 75733965Sjdp len = (strlen (bfd_get_filename (bfd_my_archive (abfd))) 75833965Sjdp + strlen (bfd_get_filename (abfd)) 75933965Sjdp + 2); 76033965Sjdp } 76133965Sjdp 76233965Sjdp if (len >= 29) 76333965Sjdp { 76433965Sjdp print_nl (); 76533965Sjdp len = 0; 76633965Sjdp } 76733965Sjdp while (len < 30) 76833965Sjdp { 76933965Sjdp print_space (); 77033965Sjdp ++len; 77133965Sjdp } 77233965Sjdp 77333965Sjdp if (from != NULL) 77433965Sjdp minfo ("%B ", from); 77533965Sjdp if (h != NULL) 77633965Sjdp minfo ("(%T)\n", h->root.string); 77733965Sjdp else 77833965Sjdp minfo ("(%s)\n", name); 77933965Sjdp } 78033965Sjdp 78133965Sjdp if (trace_files || trace_file_tries) 78233965Sjdp info_msg ("%I\n", input); 78333965Sjdp 78433965Sjdp return true; 78533965Sjdp} 78633965Sjdp 78733965Sjdp/* This is called when BFD has discovered a symbol which is defined 78833965Sjdp multiple times. */ 78933965Sjdp 79033965Sjdp/*ARGSUSED*/ 79133965Sjdpstatic boolean 79233965Sjdpmultiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval) 79333965Sjdp struct bfd_link_info *info; 79433965Sjdp const char *name; 79533965Sjdp bfd *obfd; 79633965Sjdp asection *osec; 79733965Sjdp bfd_vma oval; 79833965Sjdp bfd *nbfd; 79933965Sjdp asection *nsec; 80033965Sjdp bfd_vma nval; 80133965Sjdp{ 80233965Sjdp /* If either section has the output_section field set to 80333965Sjdp bfd_abs_section_ptr, it means that the section is being 80433965Sjdp discarded, and this is not really a multiple definition at all. 80533965Sjdp FIXME: It would be cleaner to somehow ignore symbols defined in 80633965Sjdp sections which are being discarded. */ 80733965Sjdp if ((osec->output_section != NULL 80833965Sjdp && ! bfd_is_abs_section (osec) 80933965Sjdp && bfd_is_abs_section (osec->output_section)) 81033965Sjdp || (nsec->output_section != NULL 81133965Sjdp && ! bfd_is_abs_section (nsec) 81233965Sjdp && bfd_is_abs_section (nsec->output_section))) 81333965Sjdp return true; 81433965Sjdp 81533965Sjdp einfo ("%X%C: multiple definition of `%T'\n", 81633965Sjdp nbfd, nsec, nval, name); 81733965Sjdp if (obfd != (bfd *) NULL) 81833965Sjdp einfo ("%D: first defined here\n", obfd, osec, oval); 81933965Sjdp return true; 82033965Sjdp} 82133965Sjdp 82233965Sjdp/* This is called when there is a definition of a common symbol, or 82333965Sjdp when a common symbol is found for a symbol that is already defined, 82433965Sjdp or when two common symbols are found. We only do something if 82533965Sjdp -warn-common was used. */ 82633965Sjdp 82733965Sjdp/*ARGSUSED*/ 82833965Sjdpstatic boolean 82933965Sjdpmultiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize) 83033965Sjdp struct bfd_link_info *info; 83133965Sjdp const char *name; 83233965Sjdp bfd *obfd; 83333965Sjdp enum bfd_link_hash_type otype; 83433965Sjdp bfd_vma osize; 83533965Sjdp bfd *nbfd; 83633965Sjdp enum bfd_link_hash_type ntype; 83733965Sjdp bfd_vma nsize; 83833965Sjdp{ 83933965Sjdp if (! config.warn_common) 84033965Sjdp return true; 84133965Sjdp 84233965Sjdp if (ntype == bfd_link_hash_defined 84333965Sjdp || ntype == bfd_link_hash_defweak 84433965Sjdp || ntype == bfd_link_hash_indirect) 84533965Sjdp { 84633965Sjdp ASSERT (otype == bfd_link_hash_common); 84733965Sjdp einfo ("%B: warning: definition of `%T' overriding common\n", 84833965Sjdp nbfd, name); 84933965Sjdp if (obfd != NULL) 85033965Sjdp einfo ("%B: warning: common is here\n", obfd); 85133965Sjdp } 85233965Sjdp else if (otype == bfd_link_hash_defined 85333965Sjdp || otype == bfd_link_hash_defweak 85433965Sjdp || otype == bfd_link_hash_indirect) 85533965Sjdp { 85633965Sjdp ASSERT (ntype == bfd_link_hash_common); 85733965Sjdp einfo ("%B: warning: common of `%T' overridden by definition\n", 85833965Sjdp nbfd, name); 85933965Sjdp if (obfd != NULL) 86033965Sjdp einfo ("%B: warning: defined here\n", obfd); 86133965Sjdp } 86233965Sjdp else 86333965Sjdp { 86433965Sjdp ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common); 86533965Sjdp if (osize > nsize) 86633965Sjdp { 86733965Sjdp einfo ("%B: warning: common of `%T' overridden by larger common\n", 86833965Sjdp nbfd, name); 86933965Sjdp if (obfd != NULL) 87033965Sjdp einfo ("%B: warning: larger common is here\n", obfd); 87133965Sjdp } 87233965Sjdp else if (nsize > osize) 87333965Sjdp { 87433965Sjdp einfo ("%B: warning: common of `%T' overriding smaller common\n", 87533965Sjdp nbfd, name); 87633965Sjdp if (obfd != NULL) 87733965Sjdp einfo ("%B: warning: smaller common is here\n", obfd); 87833965Sjdp } 87933965Sjdp else 88033965Sjdp { 88133965Sjdp einfo ("%B: warning: multiple common of `%T'\n", nbfd, name); 88233965Sjdp if (obfd != NULL) 88333965Sjdp einfo ("%B: warning: previous common is here\n", obfd); 88433965Sjdp } 88533965Sjdp } 88633965Sjdp 88733965Sjdp return true; 88833965Sjdp} 88933965Sjdp 89033965Sjdp/* This is called when BFD has discovered a set element. H is the 89133965Sjdp entry in the linker hash table for the set. SECTION and VALUE 89233965Sjdp represent a value which should be added to the set. */ 89333965Sjdp 89433965Sjdp/*ARGSUSED*/ 89533965Sjdpstatic boolean 89633965Sjdpadd_to_set (info, h, reloc, abfd, section, value) 89733965Sjdp struct bfd_link_info *info; 89833965Sjdp struct bfd_link_hash_entry *h; 89933965Sjdp bfd_reloc_code_real_type reloc; 90033965Sjdp bfd *abfd; 90133965Sjdp asection *section; 90233965Sjdp bfd_vma value; 90333965Sjdp{ 90433965Sjdp if (config.warn_constructors) 90533965Sjdp einfo ("%P: warning: global constructor %s used\n", 90633965Sjdp h->root.string); 90733965Sjdp 90833965Sjdp if (! config.build_constructors) 90933965Sjdp return true; 91033965Sjdp 91133965Sjdp ldctor_add_set_entry (h, reloc, (const char *) NULL, section, value); 91233965Sjdp 91333965Sjdp if (h->type == bfd_link_hash_new) 91433965Sjdp { 91533965Sjdp h->type = bfd_link_hash_undefined; 91633965Sjdp h->u.undef.abfd = abfd; 91733965Sjdp /* We don't call bfd_link_add_undef to add this to the list of 91833965Sjdp undefined symbols because we are going to define it 91933965Sjdp ourselves. */ 92033965Sjdp } 92133965Sjdp 92233965Sjdp return true; 92333965Sjdp} 92433965Sjdp 92533965Sjdp/* This is called when BFD has discovered a constructor. This is only 92633965Sjdp called for some object file formats--those which do not handle 92733965Sjdp constructors in some more clever fashion. This is similar to 92833965Sjdp adding an element to a set, but less general. */ 92933965Sjdp 93033965Sjdpstatic boolean 93133965Sjdpconstructor_callback (info, constructor, name, abfd, section, value) 93233965Sjdp struct bfd_link_info *info; 93333965Sjdp boolean constructor; 93433965Sjdp const char *name; 93533965Sjdp bfd *abfd; 93633965Sjdp asection *section; 93733965Sjdp bfd_vma value; 93833965Sjdp{ 93933965Sjdp char *s; 94033965Sjdp struct bfd_link_hash_entry *h; 94133965Sjdp char set_name[1 + sizeof "__CTOR_LIST__"]; 94233965Sjdp 94333965Sjdp if (config.warn_constructors) 94433965Sjdp einfo ("%P: warning: global constructor %s used\n", name); 94533965Sjdp 94633965Sjdp if (! config.build_constructors) 94733965Sjdp return true; 94833965Sjdp 94933965Sjdp /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a 95033965Sjdp useful error message. */ 95133965Sjdp if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL 95233965Sjdp && (link_info.relocateable 95333965Sjdp || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL)) 95433965Sjdp einfo ("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n"); 95533965Sjdp 95633965Sjdp s = set_name; 95733965Sjdp if (bfd_get_symbol_leading_char (abfd) != '\0') 95833965Sjdp *s++ = bfd_get_symbol_leading_char (abfd); 95933965Sjdp if (constructor) 96033965Sjdp strcpy (s, "__CTOR_LIST__"); 96133965Sjdp else 96233965Sjdp strcpy (s, "__DTOR_LIST__"); 96333965Sjdp 96433965Sjdp h = bfd_link_hash_lookup (info->hash, set_name, true, true, true); 96533965Sjdp if (h == (struct bfd_link_hash_entry *) NULL) 96633965Sjdp einfo ("%P%F: bfd_link_hash_lookup failed: %E\n"); 96733965Sjdp if (h->type == bfd_link_hash_new) 96833965Sjdp { 96933965Sjdp h->type = bfd_link_hash_undefined; 97033965Sjdp h->u.undef.abfd = abfd; 97133965Sjdp /* We don't call bfd_link_add_undef to add this to the list of 97233965Sjdp undefined symbols because we are going to define it 97333965Sjdp ourselves. */ 97433965Sjdp } 97533965Sjdp 97633965Sjdp ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value); 97733965Sjdp return true; 97833965Sjdp} 97933965Sjdp 98033965Sjdp/* A structure used by warning_callback to pass information through 98133965Sjdp bfd_map_over_sections. */ 98233965Sjdp 98333965Sjdpstruct warning_callback_info 98433965Sjdp{ 98533965Sjdp boolean found; 98633965Sjdp const char *warning; 98733965Sjdp const char *symbol; 98833965Sjdp asymbol **asymbols; 98933965Sjdp}; 99033965Sjdp 99133965Sjdp/* This is called when there is a reference to a warning symbol. */ 99233965Sjdp 99333965Sjdp/*ARGSUSED*/ 99433965Sjdpstatic boolean 99533965Sjdpwarning_callback (info, warning, symbol, abfd, section, address) 99633965Sjdp struct bfd_link_info *info; 99733965Sjdp const char *warning; 99833965Sjdp const char *symbol; 99933965Sjdp bfd *abfd; 100033965Sjdp asection *section; 100133965Sjdp bfd_vma address; 100233965Sjdp{ 100333965Sjdp /* This is a hack to support warn_multiple_gp. FIXME: This should 100433965Sjdp have a cleaner interface, but what? */ 100533965Sjdp if (! config.warn_multiple_gp 100633965Sjdp && strcmp (warning, "using multiple gp values") == 0) 100733965Sjdp return true; 100833965Sjdp 100933965Sjdp if (section != NULL) 101033965Sjdp einfo ("%C: %s\n", abfd, section, address, warning); 101133965Sjdp else if (abfd == NULL) 101233965Sjdp einfo ("%P: %s\n", warning); 101333965Sjdp else if (symbol == NULL) 101433965Sjdp einfo ("%B: %s\n", abfd, warning); 101533965Sjdp else 101633965Sjdp { 101733965Sjdp lang_input_statement_type *entry; 101833965Sjdp asymbol **asymbols; 101933965Sjdp struct warning_callback_info info; 102033965Sjdp 102133965Sjdp /* Look through the relocs to see if we can find a plausible 102233965Sjdp address. */ 102333965Sjdp 102433965Sjdp entry = (lang_input_statement_type *) abfd->usrdata; 102533965Sjdp if (entry != NULL && entry->asymbols != NULL) 102633965Sjdp asymbols = entry->asymbols; 102733965Sjdp else 102833965Sjdp { 102933965Sjdp long symsize; 103033965Sjdp long symbol_count; 103133965Sjdp 103233965Sjdp symsize = bfd_get_symtab_upper_bound (abfd); 103333965Sjdp if (symsize < 0) 103433965Sjdp einfo ("%B%F: could not read symbols: %E\n", abfd); 103533965Sjdp asymbols = (asymbol **) xmalloc (symsize); 103633965Sjdp symbol_count = bfd_canonicalize_symtab (abfd, asymbols); 103733965Sjdp if (symbol_count < 0) 103833965Sjdp einfo ("%B%F: could not read symbols: %E\n", abfd); 103933965Sjdp if (entry != NULL) 104033965Sjdp { 104133965Sjdp entry->asymbols = asymbols; 104233965Sjdp entry->symbol_count = symbol_count; 104333965Sjdp } 104433965Sjdp } 104533965Sjdp 104633965Sjdp info.found = false; 104733965Sjdp info.warning = warning; 104833965Sjdp info.symbol = symbol; 104933965Sjdp info.asymbols = asymbols; 105033965Sjdp bfd_map_over_sections (abfd, warning_find_reloc, (PTR) &info); 105133965Sjdp 105233965Sjdp if (! info.found) 105333965Sjdp einfo ("%B: %s\n", abfd, warning); 105433965Sjdp 105533965Sjdp if (entry == NULL) 105633965Sjdp free (asymbols); 105733965Sjdp } 105833965Sjdp 105933965Sjdp return true; 106033965Sjdp} 106133965Sjdp 106233965Sjdp/* This is called by warning_callback for each section. It checks the 106333965Sjdp relocs of the section to see if it can find a reference to the 106433965Sjdp symbol which triggered the warning. If it can, it uses the reloc 106533965Sjdp to give an error message with a file and line number. */ 106633965Sjdp 106733965Sjdpstatic void 106833965Sjdpwarning_find_reloc (abfd, sec, iarg) 106933965Sjdp bfd *abfd; 107033965Sjdp asection *sec; 107133965Sjdp PTR iarg; 107233965Sjdp{ 107333965Sjdp struct warning_callback_info *info = (struct warning_callback_info *) iarg; 107433965Sjdp long relsize; 107533965Sjdp arelent **relpp; 107633965Sjdp long relcount; 107733965Sjdp arelent **p, **pend; 107833965Sjdp 107933965Sjdp if (info->found) 108033965Sjdp return; 108133965Sjdp 108233965Sjdp relsize = bfd_get_reloc_upper_bound (abfd, sec); 108333965Sjdp if (relsize < 0) 108433965Sjdp einfo ("%B%F: could not read relocs: %E\n", abfd); 108533965Sjdp if (relsize == 0) 108633965Sjdp return; 108733965Sjdp 108833965Sjdp relpp = (arelent **) xmalloc (relsize); 108933965Sjdp relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols); 109033965Sjdp if (relcount < 0) 109133965Sjdp einfo ("%B%F: could not read relocs: %E\n", abfd); 109233965Sjdp 109333965Sjdp p = relpp; 109433965Sjdp pend = p + relcount; 109533965Sjdp for (; p < pend && *p != NULL; p++) 109633965Sjdp { 109733965Sjdp arelent *q = *p; 109833965Sjdp 109933965Sjdp if (q->sym_ptr_ptr != NULL 110033965Sjdp && *q->sym_ptr_ptr != NULL 110133965Sjdp && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0) 110233965Sjdp { 110333965Sjdp /* We found a reloc for the symbol we are looking for. */ 110433965Sjdp einfo ("%C: %s\n", abfd, sec, q->address, info->warning); 110533965Sjdp info->found = true; 110633965Sjdp break; 110733965Sjdp } 110833965Sjdp } 110933965Sjdp 111033965Sjdp free (relpp); 111133965Sjdp} 111233965Sjdp 111333965Sjdp/* This is called when an undefined symbol is found. */ 111433965Sjdp 111533965Sjdp/*ARGSUSED*/ 111633965Sjdpstatic boolean 111733965Sjdpundefined_symbol (info, name, abfd, section, address) 111833965Sjdp struct bfd_link_info *info; 111933965Sjdp const char *name; 112033965Sjdp bfd *abfd; 112133965Sjdp asection *section; 112233965Sjdp bfd_vma address; 112333965Sjdp{ 112433965Sjdp static char *error_name; 112533965Sjdp static unsigned int error_count; 112633965Sjdp 112733965Sjdp#define MAX_ERRORS_IN_A_ROW 5 112833965Sjdp 112933965Sjdp if (config.warn_once) 113033965Sjdp { 113133965Sjdp static struct bfd_hash_table *hash; 113233965Sjdp 113333965Sjdp /* Only warn once about a particular undefined symbol. */ 113433965Sjdp 113533965Sjdp if (hash == NULL) 113633965Sjdp { 113733965Sjdp hash = ((struct bfd_hash_table *) 113833965Sjdp xmalloc (sizeof (struct bfd_hash_table))); 113933965Sjdp if (! bfd_hash_table_init (hash, bfd_hash_newfunc)) 114033965Sjdp einfo ("%F%P: bfd_hash_table_init failed: %E\n"); 114133965Sjdp } 114233965Sjdp 114333965Sjdp if (bfd_hash_lookup (hash, name, false, false) != NULL) 114433965Sjdp return true; 114533965Sjdp 114633965Sjdp if (bfd_hash_lookup (hash, name, true, true) == NULL) 114733965Sjdp einfo ("%F%P: bfd_hash_lookup failed: %E\n"); 114833965Sjdp } 114933965Sjdp 115033965Sjdp /* We never print more than a reasonable number of errors in a row 115133965Sjdp for a single symbol. */ 115233965Sjdp if (error_name != (char *) NULL 115333965Sjdp && strcmp (name, error_name) == 0) 115433965Sjdp ++error_count; 115533965Sjdp else 115633965Sjdp { 115733965Sjdp error_count = 0; 115833965Sjdp if (error_name != (char *) NULL) 115933965Sjdp free (error_name); 116033965Sjdp error_name = buystring (name); 116133965Sjdp } 116233965Sjdp 116333965Sjdp if (section != NULL) 116433965Sjdp { 116533965Sjdp if (error_count < MAX_ERRORS_IN_A_ROW) 116633965Sjdp einfo ("%X%C: undefined reference to `%T'\n", 116733965Sjdp abfd, section, address, name); 116833965Sjdp else if (error_count == MAX_ERRORS_IN_A_ROW) 116933965Sjdp einfo ("%D: more undefined references to `%T' follow\n", 117033965Sjdp abfd, section, address, name); 117133965Sjdp } 117233965Sjdp else 117333965Sjdp { 117433965Sjdp if (error_count < MAX_ERRORS_IN_A_ROW) 117533965Sjdp einfo ("%X%B: undefined reference to `%T'\n", 117633965Sjdp abfd, name); 117733965Sjdp else if (error_count == MAX_ERRORS_IN_A_ROW) 117833965Sjdp einfo ("%B: more undefined references to `%T' follow\n", 117933965Sjdp abfd, name); 118033965Sjdp } 118133965Sjdp 118233965Sjdp return true; 118333965Sjdp} 118433965Sjdp 118533965Sjdp/* This is called when a reloc overflows. */ 118633965Sjdp 118733965Sjdp/*ARGSUSED*/ 118833965Sjdpstatic boolean 118933965Sjdpreloc_overflow (info, name, reloc_name, addend, abfd, section, address) 119033965Sjdp struct bfd_link_info *info; 119133965Sjdp const char *name; 119233965Sjdp const char *reloc_name; 119333965Sjdp bfd_vma addend; 119433965Sjdp bfd *abfd; 119533965Sjdp asection *section; 119633965Sjdp bfd_vma address; 119733965Sjdp{ 119833965Sjdp if (abfd == (bfd *) NULL) 119933965Sjdp einfo ("%P%X: generated"); 120033965Sjdp else 120133965Sjdp einfo ("%X%C:", abfd, section, address); 120233965Sjdp einfo (" relocation truncated to fit: %s %T", reloc_name, name); 120333965Sjdp if (addend != 0) 120433965Sjdp einfo ("+%v", addend); 120533965Sjdp einfo ("\n"); 120633965Sjdp return true; 120733965Sjdp} 120833965Sjdp 120933965Sjdp/* This is called when a dangerous relocation is made. */ 121033965Sjdp 121133965Sjdp/*ARGSUSED*/ 121233965Sjdpstatic boolean 121333965Sjdpreloc_dangerous (info, message, abfd, section, address) 121433965Sjdp struct bfd_link_info *info; 121533965Sjdp const char *message; 121633965Sjdp bfd *abfd; 121733965Sjdp asection *section; 121833965Sjdp bfd_vma address; 121933965Sjdp{ 122033965Sjdp if (abfd == (bfd *) NULL) 122133965Sjdp einfo ("%P%X: generated"); 122233965Sjdp else 122333965Sjdp einfo ("%X%C:", abfd, section, address); 122433965Sjdp einfo ("dangerous relocation: %s\n", message); 122533965Sjdp return true; 122633965Sjdp} 122733965Sjdp 122833965Sjdp/* This is called when a reloc is being generated attached to a symbol 122933965Sjdp that is not being output. */ 123033965Sjdp 123133965Sjdp/*ARGSUSED*/ 123233965Sjdpstatic boolean 123333965Sjdpunattached_reloc (info, name, abfd, section, address) 123433965Sjdp struct bfd_link_info *info; 123533965Sjdp const char *name; 123633965Sjdp bfd *abfd; 123733965Sjdp asection *section; 123833965Sjdp bfd_vma address; 123933965Sjdp{ 124033965Sjdp if (abfd == (bfd *) NULL) 124133965Sjdp einfo ("%P%X: generated"); 124233965Sjdp else 124333965Sjdp einfo ("%X%C:", abfd, section, address); 124433965Sjdp einfo (" reloc refers to symbol `%T' which is not being output\n", name); 124533965Sjdp return true; 124633965Sjdp} 124733965Sjdp 124833965Sjdp/* This is called if link_info.notice_all is set, or when a symbol in 124933965Sjdp link_info.notice_hash is found. Symbols are put in notice_hash 125033965Sjdp using the -y option. */ 125133965Sjdp 125233965Sjdpstatic boolean 125333965Sjdpnotice (info, name, abfd, section, value) 125433965Sjdp struct bfd_link_info *info; 125533965Sjdp const char *name; 125633965Sjdp bfd *abfd; 125733965Sjdp asection *section; 125833965Sjdp bfd_vma value; 125933965Sjdp{ 126033965Sjdp if (! info->notice_all 126133965Sjdp || (info->notice_hash != NULL 126233965Sjdp && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL)) 126333965Sjdp einfo ("%B: %s %s\n", abfd, 126433965Sjdp bfd_is_und_section (section) ? "reference to" : "definition of", 126533965Sjdp name); 126633965Sjdp 126733965Sjdp if (command_line.cref || nocrossref_list != NULL) 126833965Sjdp add_cref (name, abfd, section, value); 126933965Sjdp 127033965Sjdp return true; 127133965Sjdp} 1272