xref: /openbsd-src/gnu/usr.bin/binutils/ld/ldmisc.c (revision 49975d4860c10c33c98009c5f02254dbca6129fd)
12159047fSniklas /* ldmisc.c
2c074d1c9Sdrahn    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3c074d1c9Sdrahn    2000, 2002, 2003
4b305b0f1Sespie    Free Software Foundation, Inc.
52159047fSniklas    Written by Steve Chamberlain of Cygnus Support.
62159047fSniklas 
72159047fSniklas    This file is part of GLD, the Gnu Linker.
82159047fSniklas 
92159047fSniklas    GLD is free software; you can redistribute it and/or modify
102159047fSniklas    it under the terms of the GNU General Public License as published by
112159047fSniklas    the Free Software Foundation; either version 2, or (at your option)
122159047fSniklas    any later version.
132159047fSniklas 
142159047fSniklas    GLD is distributed in the hope that it will be useful,
152159047fSniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
162159047fSniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
172159047fSniklas    GNU General Public License for more details.
182159047fSniklas 
192159047fSniklas    You should have received a copy of the GNU General Public License
20b305b0f1Sespie    along with GLD; see the file COPYING.  If not, write to the Free
21b305b0f1Sespie    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22b305b0f1Sespie    02111-1307, USA.  */
232159047fSniklas 
242159047fSniklas #include "bfd.h"
25007c2a45Smiod #include "bfdlink.h"
262159047fSniklas #include "sysdep.h"
27191aa565Sniklas #include "libiberty.h"
28191aa565Sniklas #include "demangle.h"
29191aa565Sniklas #include <stdarg.h>
302159047fSniklas #include "ld.h"
312159047fSniklas #include "ldmisc.h"
322159047fSniklas #include "ldexp.h"
332159047fSniklas #include "ldlang.h"
34c074d1c9Sdrahn #include <ldgram.h>
352159047fSniklas #include "ldlex.h"
362159047fSniklas #include "ldmain.h"
372159047fSniklas #include "ldfile.h"
382159047fSniklas 
392159047fSniklas /*
402159047fSniklas  %% literal %
412159047fSniklas  %F error is fatal
422159047fSniklas  %P print program name
432159047fSniklas  %S print script file and linenumber
442159047fSniklas  %E current bfd error or errno
452159047fSniklas  %I filename from a lang_input_statement_type
462159047fSniklas  %B filename from a bfd
472159047fSniklas  %T symbol name
482159047fSniklas  %X no object output, fail return
492159047fSniklas  %V hex bfd_vma
502159047fSniklas  %v hex bfd_vma, no leading zeros
51191aa565Sniklas  %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces
522159047fSniklas  %C clever filename:linenumber with function
532159047fSniklas  %D like %C, but no function name
54191aa565Sniklas  %G like %D, but only function name
552159047fSniklas  %R info about a relent
562159047fSniklas  %s arbitrary string, like printf
572159047fSniklas  %d integer, like printf
582159047fSniklas  %u integer, like printf
592159047fSniklas */
602159047fSniklas 
612159047fSniklas static void
vfinfo(FILE * fp,const char * fmt,va_list arg)62007c2a45Smiod vfinfo (FILE *fp, const char *fmt, va_list arg)
632159047fSniklas {
64c074d1c9Sdrahn   bfd_boolean fatal = FALSE;
652159047fSniklas 
66191aa565Sniklas   while (*fmt != '\0')
672159047fSniklas     {
682159047fSniklas       while (*fmt != '%' && *fmt != '\0')
692159047fSniklas 	{
702159047fSniklas 	  putc (*fmt, fp);
712159047fSniklas 	  fmt++;
722159047fSniklas 	}
732159047fSniklas 
742159047fSniklas       if (*fmt == '%')
752159047fSniklas 	{
762159047fSniklas 	  fmt++;
772159047fSniklas 	  switch (*fmt++)
782159047fSniklas 	    {
792159047fSniklas 	    default:
802159047fSniklas 	      fprintf (fp, "%%%c", fmt[-1]);
812159047fSniklas 	      break;
822159047fSniklas 
832159047fSniklas 	    case '%':
842159047fSniklas 	      /* literal % */
852159047fSniklas 	      putc ('%', fp);
862159047fSniklas 	      break;
872159047fSniklas 
882159047fSniklas 	    case 'X':
892159047fSniklas 	      /* no object output, fail return */
90c074d1c9Sdrahn 	      config.make_executable = FALSE;
912159047fSniklas 	      break;
922159047fSniklas 
932159047fSniklas 	    case 'V':
942159047fSniklas 	      /* hex bfd_vma */
952159047fSniklas 	      {
962159047fSniklas 		bfd_vma value = va_arg (arg, bfd_vma);
972159047fSniklas 		fprintf_vma (fp, value);
982159047fSniklas 	      }
992159047fSniklas 	      break;
1002159047fSniklas 
1012159047fSniklas 	    case 'v':
1022159047fSniklas 	      /* hex bfd_vma, no leading zeros */
1032159047fSniklas 	      {
1042159047fSniklas 		char buf[100];
1052159047fSniklas 		char *p = buf;
1062159047fSniklas 		bfd_vma value = va_arg (arg, bfd_vma);
1072159047fSniklas 		sprintf_vma (p, value);
1082159047fSniklas 		while (*p == '0')
1092159047fSniklas 		  p++;
1102159047fSniklas 		if (!*p)
1112159047fSniklas 		  p--;
1122159047fSniklas 		fputs (p, fp);
1132159047fSniklas 	      }
1142159047fSniklas 	      break;
1152159047fSniklas 
116191aa565Sniklas 	    case 'W':
117191aa565Sniklas 	      /* hex bfd_vma with 0x with no leading zeroes taking up
118191aa565Sniklas 		 8 spaces.  */
119191aa565Sniklas 	      {
120191aa565Sniklas 		char buf[100];
121191aa565Sniklas 		bfd_vma value;
122191aa565Sniklas 		char *p;
123191aa565Sniklas 		int len;
124191aa565Sniklas 
125191aa565Sniklas 		value = va_arg (arg, bfd_vma);
126191aa565Sniklas 		sprintf_vma (buf, value);
127191aa565Sniklas 		for (p = buf; *p == '0'; ++p)
128191aa565Sniklas 		  ;
1290c6d0228Sniklas 		if (*p == '\0')
1300c6d0228Sniklas 		  --p;
131191aa565Sniklas 		len = strlen (p);
132191aa565Sniklas 		while (len < 8)
133191aa565Sniklas 		  {
134191aa565Sniklas 		    putc (' ', fp);
135191aa565Sniklas 		    ++len;
136191aa565Sniklas 		  }
137191aa565Sniklas 		fprintf (fp, "0x%s", p);
138191aa565Sniklas 	      }
139191aa565Sniklas 	      break;
140191aa565Sniklas 
1412159047fSniklas 	    case 'T':
1422159047fSniklas 	      /* Symbol name.  */
1432159047fSniklas 	      {
1442159047fSniklas 		const char *name = va_arg (arg, const char *);
1452159047fSniklas 
146007c2a45Smiod 		if (name == NULL || *name == 0)
147b305b0f1Sespie 		  fprintf (fp, _("no symbol"));
148b305b0f1Sespie 		else if (! demangling)
149b305b0f1Sespie 		  fprintf (fp, "%s", name);
150191aa565Sniklas 		else
151191aa565Sniklas 		  {
152191aa565Sniklas 		    char *demangled;
153191aa565Sniklas 
154191aa565Sniklas 		    demangled = demangle (name);
155191aa565Sniklas 		    fprintf (fp, "%s", demangled);
156191aa565Sniklas 		    free (demangled);
157191aa565Sniklas 		  }
1582159047fSniklas 	      }
1592159047fSniklas 	      break;
1602159047fSniklas 
1612159047fSniklas 	    case 'B':
1622159047fSniklas 	      /* filename from a bfd */
1632159047fSniklas 	      {
1642159047fSniklas 		bfd *abfd = va_arg (arg, bfd *);
165191aa565Sniklas 		if (abfd->my_archive)
1662159047fSniklas 		  fprintf (fp, "%s(%s)", abfd->my_archive->filename,
1672159047fSniklas 			   abfd->filename);
168191aa565Sniklas 		else
1692159047fSniklas 		  fprintf (fp, "%s", abfd->filename);
1702159047fSniklas 	      }
1712159047fSniklas 	      break;
1722159047fSniklas 
1732159047fSniklas 	    case 'F':
174b55d4692Sfgsch 	      /* Error is fatal.  */
175c074d1c9Sdrahn 	      fatal = TRUE;
1762159047fSniklas 	      break;
1772159047fSniklas 
1782159047fSniklas 	    case 'P':
179b55d4692Sfgsch 	      /* Print program name.  */
1802159047fSniklas 	      fprintf (fp, "%s", program_name);
1812159047fSniklas 	      break;
1822159047fSniklas 
1832159047fSniklas 	    case 'E':
1842159047fSniklas 	      /* current bfd error or errno */
185b305b0f1Sespie 	      fprintf (fp, "%s", bfd_errmsg (bfd_get_error ()));
1862159047fSniklas 	      break;
1872159047fSniklas 
1882159047fSniklas 	    case 'I':
1892159047fSniklas 	      /* filename from a lang_input_statement_type */
1902159047fSniklas 	      {
191191aa565Sniklas 		lang_input_statement_type *i;
1922159047fSniklas 
193191aa565Sniklas 		i = va_arg (arg, lang_input_statement_type *);
194191aa565Sniklas 		if (bfd_my_archive (i->the_bfd) != NULL)
195191aa565Sniklas 		  fprintf (fp, "(%s)",
196191aa565Sniklas 			   bfd_get_filename (bfd_my_archive (i->the_bfd)));
1972159047fSniklas 		fprintf (fp, "%s", i->local_sym_name);
198191aa565Sniklas 		if (bfd_my_archive (i->the_bfd) == NULL
199191aa565Sniklas 		    && strcmp (i->local_sym_name, i->filename) != 0)
200191aa565Sniklas 		  fprintf (fp, " (%s)", i->filename);
2012159047fSniklas 	      }
2022159047fSniklas 	      break;
2032159047fSniklas 
2042159047fSniklas 	    case 'S':
205b55d4692Sfgsch 	      /* Print script file and linenumber.  */
2062159047fSniklas 	      if (parsing_defsym)
2072159047fSniklas 		fprintf (fp, "--defsym %s", lex_string);
2082159047fSniklas 	      else if (ldfile_input_filename != NULL)
2092159047fSniklas 		fprintf (fp, "%s:%u", ldfile_input_filename, lineno);
2102159047fSniklas 	      else
211b305b0f1Sespie 		fprintf (fp, _("built in linker script:%u"), lineno);
2122159047fSniklas 	      break;
2132159047fSniklas 
2142159047fSniklas 	    case 'R':
215b55d4692Sfgsch 	      /* Print all that's interesting about a relent.  */
2162159047fSniklas 	      {
2172159047fSniklas 		arelent *relent = va_arg (arg, arelent *);
2182159047fSniklas 
219b305b0f1Sespie 		lfinfo (fp, "%s+0x%v (type %s)",
2202159047fSniklas 			(*(relent->sym_ptr_ptr))->name,
2212159047fSniklas 			relent->addend,
2222159047fSniklas 			relent->howto->name);
2232159047fSniklas 	      }
2242159047fSniklas 	      break;
2252159047fSniklas 
2262159047fSniklas 	    case 'C':
2272159047fSniklas 	    case 'D':
228191aa565Sniklas 	    case 'G':
229c074d1c9Sdrahn 	      /* Clever filename:linenumber with function name if possible.
230c074d1c9Sdrahn 		 The arguments are a BFD, a section, and an offset.  */
2312159047fSniklas 	      {
2322159047fSniklas 		static bfd *last_bfd;
2332159047fSniklas 		static char *last_file = NULL;
2342159047fSniklas 		static char *last_function = NULL;
2352159047fSniklas 		bfd *abfd;
2362159047fSniklas 		asection *section;
2372159047fSniklas 		bfd_vma offset;
2382159047fSniklas 		lang_input_statement_type *entry;
2392159047fSniklas 		asymbol **asymbols;
2402159047fSniklas 		const char *filename;
2412159047fSniklas 		const char *functionname;
2422159047fSniklas 		unsigned int linenumber;
243c074d1c9Sdrahn 		bfd_boolean discard_last;
2442159047fSniklas 
2452159047fSniklas 		abfd = va_arg (arg, bfd *);
2462159047fSniklas 		section = va_arg (arg, asection *);
2472159047fSniklas 		offset = va_arg (arg, bfd_vma);
2482159047fSniklas 
2492159047fSniklas 		entry = (lang_input_statement_type *) abfd->usrdata;
2502159047fSniklas 		if (entry != (lang_input_statement_type *) NULL
2512159047fSniklas 		    && entry->asymbols != (asymbol **) NULL)
2522159047fSniklas 		  asymbols = entry->asymbols;
2532159047fSniklas 		else
2542159047fSniklas 		  {
2552159047fSniklas 		    long symsize;
2562159047fSniklas 		    long symbol_count;
2572159047fSniklas 
2582159047fSniklas 		    symsize = bfd_get_symtab_upper_bound (abfd);
2592159047fSniklas 		    if (symsize < 0)
260b305b0f1Sespie 		      einfo (_("%B%F: could not read symbols\n"), abfd);
261007c2a45Smiod 		    asymbols = xmalloc (symsize);
2622159047fSniklas 		    symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
2632159047fSniklas 		    if (symbol_count < 0)
264b305b0f1Sespie 		      einfo (_("%B%F: could not read symbols\n"), abfd);
2652159047fSniklas 		    if (entry != (lang_input_statement_type *) NULL)
2662159047fSniklas 		      {
2672159047fSniklas 			entry->asymbols = asymbols;
2682159047fSniklas 			entry->symbol_count = symbol_count;
2692159047fSniklas 		      }
2702159047fSniklas 		  }
2712159047fSniklas 
272c074d1c9Sdrahn 		lfinfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
273c074d1c9Sdrahn 
274c074d1c9Sdrahn 		discard_last = TRUE;
2752159047fSniklas 		if (bfd_find_nearest_line (abfd, section, asymbols, offset,
276191aa565Sniklas 					   &filename, &functionname,
277191aa565Sniklas 					   &linenumber))
2782159047fSniklas 		  {
279c074d1c9Sdrahn 		    bfd_boolean need_colon = TRUE;
2802159047fSniklas 
281c074d1c9Sdrahn 		    if (functionname != NULL && fmt[-1] == 'C')
282c074d1c9Sdrahn 		      {
2832159047fSniklas 			if (last_bfd == NULL
2842159047fSniklas 			    || last_file == NULL
2852159047fSniklas 			    || last_function == NULL
2862159047fSniklas 			    || last_bfd != abfd
287c074d1c9Sdrahn 			    || (filename != NULL
288c074d1c9Sdrahn 				&& strcmp (last_file, filename) != 0)
2892159047fSniklas 			    || strcmp (last_function, functionname) != 0)
2902159047fSniklas 			  {
291c074d1c9Sdrahn 			    lfinfo (fp, _(": In function `%T':\n"),
292c074d1c9Sdrahn 				    functionname);
293c074d1c9Sdrahn 			    need_colon = FALSE;
2942159047fSniklas 
2952159047fSniklas 			    last_bfd = abfd;
2962159047fSniklas 			    if (last_file != NULL)
2972159047fSniklas 			      free (last_file);
298c074d1c9Sdrahn 			    last_file = NULL;
299c074d1c9Sdrahn 			    if (filename)
300b55d4692Sfgsch 			      last_file = xstrdup (filename);
3012159047fSniklas 			    if (last_function != NULL)
3022159047fSniklas 			      free (last_function);
303b55d4692Sfgsch 			    last_function = xstrdup (functionname);
3042159047fSniklas 			  }
305c074d1c9Sdrahn 			discard_last = FALSE;
3062159047fSniklas 		      }
307c074d1c9Sdrahn 
308c074d1c9Sdrahn 		    if (filename != NULL)
3092159047fSniklas 		      {
310c074d1c9Sdrahn 			if (need_colon)
311c074d1c9Sdrahn 			  putc (':', fp);
312c074d1c9Sdrahn 			fputs (filename, fp);
3132159047fSniklas 		      }
314c074d1c9Sdrahn 
315c074d1c9Sdrahn 		    if (functionname != NULL && fmt[-1] == 'G')
316c074d1c9Sdrahn 		      lfinfo (fp, ":%T", functionname);
317c074d1c9Sdrahn 		    else if (filename != NULL && linenumber != 0)
318c074d1c9Sdrahn 		      fprintf (fp, ":%u", linenumber);
3192159047fSniklas 		  }
320c074d1c9Sdrahn 
321c074d1c9Sdrahn 		if (asymbols != NULL && entry == NULL)
322c074d1c9Sdrahn 		  free (asymbols);
3232159047fSniklas 
3242159047fSniklas 		if (discard_last)
3252159047fSniklas 		  {
3262159047fSniklas 		    last_bfd = NULL;
3272159047fSniklas 		    if (last_file != NULL)
3282159047fSniklas 		      {
3292159047fSniklas 			free (last_file);
3302159047fSniklas 			last_file = NULL;
3312159047fSniklas 		      }
3322159047fSniklas 		    if (last_function != NULL)
3332159047fSniklas 		      {
3342159047fSniklas 			free (last_function);
3352159047fSniklas 			last_function = NULL;
3362159047fSniklas 		      }
3372159047fSniklas 		  }
3382159047fSniklas 	      }
3392159047fSniklas 	      break;
3402159047fSniklas 
3412159047fSniklas 	    case 's':
3422159047fSniklas 	      /* arbitrary string, like printf */
3432159047fSniklas 	      fprintf (fp, "%s", va_arg (arg, char *));
3442159047fSniklas 	      break;
3452159047fSniklas 
3462159047fSniklas 	    case 'd':
3472159047fSniklas 	      /* integer, like printf */
3482159047fSniklas 	      fprintf (fp, "%d", va_arg (arg, int));
3492159047fSniklas 	      break;
3502159047fSniklas 
3512159047fSniklas 	    case 'u':
3522159047fSniklas 	      /* unsigned integer, like printf */
3532159047fSniklas 	      fprintf (fp, "%u", va_arg (arg, unsigned int));
3542159047fSniklas 	      break;
3552159047fSniklas 	    }
3562159047fSniklas 	}
3572159047fSniklas     }
3582159047fSniklas 
359c074d1c9Sdrahn   if (config.fatal_warnings)
360c074d1c9Sdrahn     config.make_executable = FALSE;
361c074d1c9Sdrahn 
362c074d1c9Sdrahn   if (fatal)
3632159047fSniklas     xexit (1);
3642159047fSniklas }
3652159047fSniklas 
366c074d1c9Sdrahn /* Wrapper around cplus_demangle.  Strips leading underscores and
367c074d1c9Sdrahn    other such chars that would otherwise confuse the demangler.  */
368c074d1c9Sdrahn 
369c074d1c9Sdrahn char *
demangle(const char * name)370007c2a45Smiod demangle (const char *name)
371c074d1c9Sdrahn {
372c074d1c9Sdrahn   char *res;
373c074d1c9Sdrahn   const char *p;
374c074d1c9Sdrahn 
375c074d1c9Sdrahn   if (output_bfd != NULL
376c074d1c9Sdrahn       && bfd_get_symbol_leading_char (output_bfd) == name[0])
377c074d1c9Sdrahn     ++name;
378c074d1c9Sdrahn 
379c074d1c9Sdrahn   /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
380c074d1c9Sdrahn      or the MS PE format.  These formats have a number of leading '.'s
381c074d1c9Sdrahn      on at least some symbols, so we remove all dots to avoid
382c074d1c9Sdrahn      confusing the demangler.  */
383c074d1c9Sdrahn   p = name;
384c074d1c9Sdrahn   while (*p == '.')
385c074d1c9Sdrahn     ++p;
386c074d1c9Sdrahn 
387c074d1c9Sdrahn   res = cplus_demangle (p, DMGL_ANSI | DMGL_PARAMS);
388c074d1c9Sdrahn   if (res)
389c074d1c9Sdrahn     {
390c074d1c9Sdrahn       size_t dots = p - name;
391c074d1c9Sdrahn 
392c074d1c9Sdrahn       /* Now put back any stripped dots.  */
393c074d1c9Sdrahn       if (dots != 0)
394c074d1c9Sdrahn 	{
395c074d1c9Sdrahn 	  size_t len = strlen (res) + 1;
396c074d1c9Sdrahn 	  char *add_dots = xmalloc (len + dots);
397c074d1c9Sdrahn 
398c074d1c9Sdrahn 	  memcpy (add_dots, name, dots);
399c074d1c9Sdrahn 	  memcpy (add_dots + dots, res, len);
400c074d1c9Sdrahn 	  free (res);
401c074d1c9Sdrahn 	  res = add_dots;
402c074d1c9Sdrahn 	}
403c074d1c9Sdrahn       return res;
404c074d1c9Sdrahn     }
405c074d1c9Sdrahn   return xstrdup (name);
406c074d1c9Sdrahn }
407c074d1c9Sdrahn 
4082159047fSniklas /* Format info message and print on stdout.  */
4092159047fSniklas 
410191aa565Sniklas /* (You would think this should be called just "info", but then you
411007c2a45Smiod    would be hosed by LynxOS, which defines that name in its libc.)  */
4122159047fSniklas 
413191aa565Sniklas void
info_msg(const char * fmt,...)414007c2a45Smiod info_msg (const char *fmt, ...)
4152159047fSniklas {
416007c2a45Smiod   va_list arg;
417191aa565Sniklas 
418007c2a45Smiod   va_start (arg, fmt);
4192159047fSniklas   vfinfo (stdout, fmt, arg);
420007c2a45Smiod   va_end (arg);
4212159047fSniklas }
4222159047fSniklas 
4232159047fSniklas /* ('e' for error.) Format info message and print on stderr.  */
4242159047fSniklas 
425191aa565Sniklas void
einfo(const char * fmt,...)426007c2a45Smiod einfo (const char *fmt, ...)
4272159047fSniklas {
428007c2a45Smiod   va_list arg;
429*49975d48Smillert   char buf[BUFSIZ];
430191aa565Sniklas 
431*49975d48Smillert   setvbuf(stderr, buf, _IOFBF, sizeof(buf));
432007c2a45Smiod   va_start (arg, fmt);
4332159047fSniklas   vfinfo (stderr, fmt, arg);
434007c2a45Smiod   va_end (arg);
435*49975d48Smillert   fflush(stderr);
436*49975d48Smillert   setvbuf(stderr, NULL, _IONBF, 0);
4372159047fSniklas }
4382159047fSniklas 
4392159047fSniklas void
info_assert(const char * file,unsigned int line)440007c2a45Smiod info_assert (const char *file, unsigned int line)
4412159047fSniklas {
442b305b0f1Sespie   einfo (_("%F%P: internal error %s %d\n"), file, line);
4432159047fSniklas }
4442159047fSniklas 
4452159047fSniklas /* ('m' for map) Format info message and print on map.  */
4462159047fSniklas 
447191aa565Sniklas void
minfo(const char * fmt,...)448007c2a45Smiod minfo (const char *fmt, ...)
4492159047fSniklas {
450007c2a45Smiod   va_list arg;
451191aa565Sniklas 
452007c2a45Smiod   va_start (arg, fmt);
4532159047fSniklas   vfinfo (config.map_file, fmt, arg);
454007c2a45Smiod   va_end (arg);
4552159047fSniklas }
4562159047fSniklas 
457191aa565Sniklas void
lfinfo(FILE * file,const char * fmt,...)458007c2a45Smiod lfinfo (FILE *file, const char *fmt, ...)
4592159047fSniklas {
460007c2a45Smiod   va_list arg;
461191aa565Sniklas 
462007c2a45Smiod   va_start (arg, fmt);
4632159047fSniklas   vfinfo (file, fmt, arg);
464007c2a45Smiod   va_end (arg);
4652159047fSniklas }
466191aa565Sniklas 
467191aa565Sniklas /* Functions to print the link map.  */
4682159047fSniklas 
4692159047fSniklas void
print_space(void)470007c2a45Smiod print_space (void)
4712159047fSniklas {
4722159047fSniklas   fprintf (config.map_file, " ");
4732159047fSniklas }
474191aa565Sniklas 
4752159047fSniklas void
print_nl(void)476007c2a45Smiod print_nl (void)
4772159047fSniklas {
4782159047fSniklas   fprintf (config.map_file, "\n");
4792159047fSniklas }
480b305b0f1Sespie 
481b305b0f1Sespie /* A more or less friendly abort message.  In ld.h abort is defined to
482b305b0f1Sespie    call this function.  */
483b305b0f1Sespie 
484b305b0f1Sespie void
ld_abort(const char * file,int line,const char * fn)485007c2a45Smiod ld_abort (const char *file, int line, const char *fn)
486b305b0f1Sespie {
487b305b0f1Sespie   if (fn != NULL)
488b305b0f1Sespie     einfo (_("%P: internal error: aborting at %s line %d in %s\n"),
489b305b0f1Sespie 	   file, line, fn);
490b305b0f1Sespie   else
491b305b0f1Sespie     einfo (_("%P: internal error: aborting at %s line %d\n"),
492b305b0f1Sespie 	   file, line);
493b305b0f1Sespie   einfo (_("%P%F: please report this bug\n"));
494b305b0f1Sespie   xexit (1);
495b305b0f1Sespie }
496c074d1c9Sdrahn 
497c074d1c9Sdrahn bfd_boolean
error_handler(int id,const char * fmt,...)498007c2a45Smiod error_handler (int id, const char *fmt, ...)
499c074d1c9Sdrahn {
500007c2a45Smiod   va_list arg;
501c074d1c9Sdrahn 
502007c2a45Smiod   va_start (arg, fmt);
503007c2a45Smiod 
504007c2a45Smiod   switch (id)
505007c2a45Smiod     {
506007c2a45Smiod     default:
507007c2a45Smiod       break;
508007c2a45Smiod 
509007c2a45Smiod     /* We can be called with
510007c2a45Smiod 
511007c2a45Smiod 	error_handler (-LD_DEFINITION_IN_DISCARDED_SECTION, "", 0);
512007c2a45Smiod 
513007c2a45Smiod 	to make this error non-fatal and
514007c2a45Smiod 
515007c2a45Smiod 	error_handler (-LD_DEFINITION_IN_DISCARDED_SECTION, "", 1);
516007c2a45Smiod 
517007c2a45Smiod 	to make this error fatal.  */
518007c2a45Smiod     case -LD_DEFINITION_IN_DISCARDED_SECTION:
519007c2a45Smiod     case LD_DEFINITION_IN_DISCARDED_SECTION:
520007c2a45Smiod       {
521007c2a45Smiod 	static struct bfd_hash_table *hash;
522007c2a45Smiod 	static int fatal = 1;
523007c2a45Smiod 	const char *name;
524007c2a45Smiod 
525007c2a45Smiod 	if (id == -LD_DEFINITION_IN_DISCARDED_SECTION)
526007c2a45Smiod 	  {
527007c2a45Smiod 	    fatal = va_arg (arg, int);
528007c2a45Smiod 	    goto out;
529007c2a45Smiod 	  }
530007c2a45Smiod 
531007c2a45Smiod 	name = va_arg (arg, const char *);
532007c2a45Smiod 	/* Only warn once about a particular undefined symbol.  */
533007c2a45Smiod 	if (hash == NULL)
534007c2a45Smiod 	  {
535007c2a45Smiod 	    hash = xmalloc (sizeof (struct bfd_hash_table));
536007c2a45Smiod 	    if (! bfd_hash_table_init (hash, bfd_hash_newfunc))
537007c2a45Smiod 	      einfo (_("%F%P: bfd_hash_table_init failed: %E\n"));
538007c2a45Smiod 	  }
539007c2a45Smiod 
540007c2a45Smiod 	if (bfd_hash_lookup (hash, name, FALSE, FALSE) != NULL)
541007c2a45Smiod 	  goto out;
542007c2a45Smiod 
543007c2a45Smiod 	if (bfd_hash_lookup (hash, name, TRUE, TRUE) == NULL)
544007c2a45Smiod 	  einfo (_("%F%P: bfd_hash_lookup failed: %E\n"));
545007c2a45Smiod 
546007c2a45Smiod 	if (fatal)
547007c2a45Smiod 	  config.make_executable = FALSE;
548007c2a45Smiod       }
549007c2a45Smiod       break;
550007c2a45Smiod     }
551c074d1c9Sdrahn   vfinfo (stderr, fmt, arg);
552007c2a45Smiod 
553007c2a45Smiod out:
554007c2a45Smiod   va_end (arg);
555c074d1c9Sdrahn   return TRUE;
556c074d1c9Sdrahn }
557