xref: /openbsd-src/gnu/usr.bin/binutils-2.17/ld/ldmisc.c (revision 87aacc86920b67c5ad49e042451c504133d24db1)
13d8817e4Smiod /* ldmisc.c
23d8817e4Smiod    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
33d8817e4Smiod    2001, 2002, 2003, 2004, 2005, 2006
43d8817e4Smiod    Free Software Foundation, Inc.
53d8817e4Smiod    Written by Steve Chamberlain of Cygnus Support.
63d8817e4Smiod 
73d8817e4Smiod    This file is part of GLD, the Gnu Linker.
83d8817e4Smiod 
93d8817e4Smiod    GLD is free software; you can redistribute it and/or modify
103d8817e4Smiod    it under the terms of the GNU General Public License as published by
113d8817e4Smiod    the Free Software Foundation; either version 2, or (at your option)
123d8817e4Smiod    any later version.
133d8817e4Smiod 
143d8817e4Smiod    GLD is distributed in the hope that it will be useful,
153d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
163d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
173d8817e4Smiod    GNU General Public License for more details.
183d8817e4Smiod 
193d8817e4Smiod    You should have received a copy of the GNU General Public License
203d8817e4Smiod    along with GLD; see the file COPYING.  If not, write to the Free
213d8817e4Smiod    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
223d8817e4Smiod    02110-1301, USA.  */
233d8817e4Smiod 
243d8817e4Smiod #include "bfd.h"
253d8817e4Smiod #include "bfdlink.h"
263d8817e4Smiod #include "sysdep.h"
273d8817e4Smiod #include "libiberty.h"
283d8817e4Smiod #include "demangle.h"
293d8817e4Smiod #include <stdarg.h>
303d8817e4Smiod #include "ld.h"
313d8817e4Smiod #include "ldmisc.h"
323d8817e4Smiod #include "ldexp.h"
333d8817e4Smiod #include "ldlang.h"
343d8817e4Smiod #include <ldgram.h>
353d8817e4Smiod #include "ldlex.h"
363d8817e4Smiod #include "ldmain.h"
373d8817e4Smiod #include "ldfile.h"
383d8817e4Smiod #include "elf-bfd.h"
393d8817e4Smiod 
403d8817e4Smiod /*
413d8817e4Smiod  %% literal %
423d8817e4Smiod  %A section name from a section
433d8817e4Smiod  %B filename from a bfd
443d8817e4Smiod  %C clever filename:linenumber with function
453d8817e4Smiod  %D like %C, but no function name
463d8817e4Smiod  %E current bfd error or errno
473d8817e4Smiod  %F error is fatal
483d8817e4Smiod  %G like %D, but only function name
493d8817e4Smiod  %I filename from a lang_input_statement_type
503d8817e4Smiod  %P print program name
513d8817e4Smiod  %R info about a relent
523d8817e4Smiod  %S print script file and linenumber
533d8817e4Smiod  %T symbol name
543d8817e4Smiod  %V hex bfd_vma
553d8817e4Smiod  %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces
563d8817e4Smiod  %X no object output, fail return
573d8817e4Smiod  %d integer, like printf
583d8817e4Smiod  %ld long, like printf
593d8817e4Smiod  %lu unsigned long, like printf
603d8817e4Smiod  %s arbitrary string, like printf
613d8817e4Smiod  %u integer, like printf
623d8817e4Smiod  %v hex bfd_vma, no leading zeros
633d8817e4Smiod */
643d8817e4Smiod 
653d8817e4Smiod static void
vfinfo(FILE * fp,const char * fmt,va_list arg,bfd_boolean is_warning)663d8817e4Smiod vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
673d8817e4Smiod {
683d8817e4Smiod   bfd_boolean fatal = FALSE;
693d8817e4Smiod 
703d8817e4Smiod   while (*fmt != '\0')
713d8817e4Smiod     {
723d8817e4Smiod       while (*fmt != '%' && *fmt != '\0')
733d8817e4Smiod 	{
743d8817e4Smiod 	  putc (*fmt, fp);
753d8817e4Smiod 	  fmt++;
763d8817e4Smiod 	}
773d8817e4Smiod 
783d8817e4Smiod       if (*fmt == '%')
793d8817e4Smiod 	{
803d8817e4Smiod 	  fmt++;
813d8817e4Smiod 	  switch (*fmt++)
823d8817e4Smiod 	    {
833d8817e4Smiod 	    case '%':
843d8817e4Smiod 	      /* literal % */
853d8817e4Smiod 	      putc ('%', fp);
863d8817e4Smiod 	      break;
873d8817e4Smiod 
883d8817e4Smiod 	    case 'X':
893d8817e4Smiod 	      /* no object output, fail return */
903d8817e4Smiod 	      config.make_executable = FALSE;
913d8817e4Smiod 	      break;
923d8817e4Smiod 
933d8817e4Smiod 	    case 'V':
943d8817e4Smiod 	      /* hex bfd_vma */
953d8817e4Smiod 	      {
963d8817e4Smiod 		bfd_vma value = va_arg (arg, bfd_vma);
973d8817e4Smiod 		fprintf_vma (fp, value);
983d8817e4Smiod 	      }
993d8817e4Smiod 	      break;
1003d8817e4Smiod 
1013d8817e4Smiod 	    case 'v':
1023d8817e4Smiod 	      /* hex bfd_vma, no leading zeros */
1033d8817e4Smiod 	      {
1043d8817e4Smiod 		char buf[100];
1053d8817e4Smiod 		char *p = buf;
1063d8817e4Smiod 		bfd_vma value = va_arg (arg, bfd_vma);
1073d8817e4Smiod 		sprintf_vma (p, value);
1083d8817e4Smiod 		while (*p == '0')
1093d8817e4Smiod 		  p++;
1103d8817e4Smiod 		if (!*p)
1113d8817e4Smiod 		  p--;
1123d8817e4Smiod 		fputs (p, fp);
1133d8817e4Smiod 	      }
1143d8817e4Smiod 	      break;
1153d8817e4Smiod 
1163d8817e4Smiod 	    case 'W':
1173d8817e4Smiod 	      /* hex bfd_vma with 0x with no leading zeroes taking up
1183d8817e4Smiod 		 8 spaces.  */
1193d8817e4Smiod 	      {
1203d8817e4Smiod 		char buf[100];
1213d8817e4Smiod 		bfd_vma value;
1223d8817e4Smiod 		char *p;
1233d8817e4Smiod 		int len;
1243d8817e4Smiod 
1253d8817e4Smiod 		value = va_arg (arg, bfd_vma);
1263d8817e4Smiod 		sprintf_vma (buf, value);
1273d8817e4Smiod 		for (p = buf; *p == '0'; ++p)
1283d8817e4Smiod 		  ;
1293d8817e4Smiod 		if (*p == '\0')
1303d8817e4Smiod 		  --p;
1313d8817e4Smiod 		len = strlen (p);
1323d8817e4Smiod 		while (len < 8)
1333d8817e4Smiod 		  {
1343d8817e4Smiod 		    putc (' ', fp);
1353d8817e4Smiod 		    ++len;
1363d8817e4Smiod 		  }
1373d8817e4Smiod 		fprintf (fp, "0x%s", p);
1383d8817e4Smiod 	      }
1393d8817e4Smiod 	      break;
1403d8817e4Smiod 
1413d8817e4Smiod 	    case 'T':
1423d8817e4Smiod 	      /* Symbol name.  */
1433d8817e4Smiod 	      {
1443d8817e4Smiod 		const char *name = va_arg (arg, const char *);
1453d8817e4Smiod 
1463d8817e4Smiod 		if (name == NULL || *name == 0)
1473d8817e4Smiod 		  fprintf (fp, _("no symbol"));
1483d8817e4Smiod 		else if (! demangling)
1493d8817e4Smiod 		  fprintf (fp, "%s", name);
1503d8817e4Smiod 		else
1513d8817e4Smiod 		  {
1523d8817e4Smiod 		    char *demangled;
1533d8817e4Smiod 
1543d8817e4Smiod 		    demangled = demangle (name);
1553d8817e4Smiod 		    fprintf (fp, "%s", demangled);
1563d8817e4Smiod 		    free (demangled);
1573d8817e4Smiod 		  }
1583d8817e4Smiod 	      }
1593d8817e4Smiod 	      break;
1603d8817e4Smiod 
1613d8817e4Smiod 	    case 'A':
1623d8817e4Smiod 	      /* section name from a section */
1633d8817e4Smiod 	      {
1643d8817e4Smiod 		asection *sec = va_arg (arg, asection *);
1653d8817e4Smiod 		bfd *abfd = sec->owner;
1663d8817e4Smiod 		const char *group = NULL;
1673d8817e4Smiod 		struct coff_comdat_info *ci;
1683d8817e4Smiod 
1693d8817e4Smiod 		fprintf (fp, "%s", sec->name);
1703d8817e4Smiod 		if (abfd != NULL
1713d8817e4Smiod 		    && bfd_get_flavour (abfd) == bfd_target_elf_flavour
1723d8817e4Smiod 		    && elf_next_in_group (sec) != NULL
1733d8817e4Smiod 		    && (sec->flags & SEC_GROUP) == 0)
1743d8817e4Smiod 		  group = elf_group_name (sec);
1753d8817e4Smiod 		else if (abfd != NULL
1763d8817e4Smiod 			 && bfd_get_flavour (abfd) == bfd_target_coff_flavour
1773d8817e4Smiod 			 && (ci = bfd_coff_get_comdat_section (sec->owner,
1783d8817e4Smiod 							       sec)) != NULL)
1793d8817e4Smiod 		  group = ci->name;
1803d8817e4Smiod 		if (group != NULL)
1813d8817e4Smiod 		  fprintf (fp, "[%s]", group);
1823d8817e4Smiod 	      }
1833d8817e4Smiod 	      break;
1843d8817e4Smiod 
1853d8817e4Smiod 	    case 'B':
1863d8817e4Smiod 	      /* filename from a bfd */
1873d8817e4Smiod 	      {
1883d8817e4Smiod 		bfd *abfd = va_arg (arg, bfd *);
1893d8817e4Smiod 
1903d8817e4Smiod 		if (abfd == NULL)
1913d8817e4Smiod 		  fprintf (fp, "%s generated", program_name);
1923d8817e4Smiod 		else if (abfd->my_archive)
1933d8817e4Smiod 		  fprintf (fp, "%s(%s)", abfd->my_archive->filename,
1943d8817e4Smiod 			   abfd->filename);
1953d8817e4Smiod 		else
1963d8817e4Smiod 		  fprintf (fp, "%s", abfd->filename);
1973d8817e4Smiod 	      }
1983d8817e4Smiod 	      break;
1993d8817e4Smiod 
2003d8817e4Smiod 	    case 'F':
2013d8817e4Smiod 	      /* Error is fatal.  */
2023d8817e4Smiod 	      fatal = TRUE;
2033d8817e4Smiod 	      break;
2043d8817e4Smiod 
2053d8817e4Smiod 	    case 'P':
2063d8817e4Smiod 	      /* Print program name.  */
2073d8817e4Smiod 	      fprintf (fp, "%s", program_name);
2083d8817e4Smiod 	      break;
2093d8817e4Smiod 
2103d8817e4Smiod 	    case 'E':
2113d8817e4Smiod 	      /* current bfd error or errno */
2123d8817e4Smiod 	      fprintf (fp, "%s", bfd_errmsg (bfd_get_error ()));
2133d8817e4Smiod 	      break;
2143d8817e4Smiod 
2153d8817e4Smiod 	    case 'I':
2163d8817e4Smiod 	      /* filename from a lang_input_statement_type */
2173d8817e4Smiod 	      {
2183d8817e4Smiod 		lang_input_statement_type *i;
2193d8817e4Smiod 
2203d8817e4Smiod 		i = va_arg (arg, lang_input_statement_type *);
2213d8817e4Smiod 		if (bfd_my_archive (i->the_bfd) != NULL)
2223d8817e4Smiod 		  fprintf (fp, "(%s)",
2233d8817e4Smiod 			   bfd_get_filename (bfd_my_archive (i->the_bfd)));
2243d8817e4Smiod 		fprintf (fp, "%s", i->local_sym_name);
2253d8817e4Smiod 		if (bfd_my_archive (i->the_bfd) == NULL
2263d8817e4Smiod 		    && strcmp (i->local_sym_name, i->filename) != 0)
2273d8817e4Smiod 		  fprintf (fp, " (%s)", i->filename);
2283d8817e4Smiod 	      }
2293d8817e4Smiod 	      break;
2303d8817e4Smiod 
2313d8817e4Smiod 	    case 'S':
2323d8817e4Smiod 	      /* Print script file and linenumber.  */
2333d8817e4Smiod 	      if (parsing_defsym)
2343d8817e4Smiod 		fprintf (fp, "--defsym %s", lex_string);
2353d8817e4Smiod 	      else if (ldfile_input_filename != NULL)
2363d8817e4Smiod 		fprintf (fp, "%s:%u", ldfile_input_filename, lineno);
2373d8817e4Smiod 	      else
2383d8817e4Smiod 		fprintf (fp, _("built in linker script:%u"), lineno);
2393d8817e4Smiod 	      break;
2403d8817e4Smiod 
2413d8817e4Smiod 	    case 'R':
2423d8817e4Smiod 	      /* Print all that's interesting about a relent.  */
2433d8817e4Smiod 	      {
2443d8817e4Smiod 		arelent *relent = va_arg (arg, arelent *);
2453d8817e4Smiod 
2463d8817e4Smiod 		lfinfo (fp, "%s+0x%v (type %s)",
2473d8817e4Smiod 			(*(relent->sym_ptr_ptr))->name,
2483d8817e4Smiod 			relent->addend,
2493d8817e4Smiod 			relent->howto->name);
2503d8817e4Smiod 	      }
2513d8817e4Smiod 	      break;
2523d8817e4Smiod 
2533d8817e4Smiod 	    case 'C':
2543d8817e4Smiod 	    case 'D':
2553d8817e4Smiod 	    case 'G':
2563d8817e4Smiod 	      /* Clever filename:linenumber with function name if possible.
2573d8817e4Smiod 		 The arguments are a BFD, a section, and an offset.  */
2583d8817e4Smiod 	      {
2593d8817e4Smiod 		static bfd *last_bfd;
2603d8817e4Smiod 		static char *last_file = NULL;
2613d8817e4Smiod 		static char *last_function = NULL;
2623d8817e4Smiod 		bfd *abfd;
2633d8817e4Smiod 		asection *section;
2643d8817e4Smiod 		bfd_vma offset;
2653d8817e4Smiod 		lang_input_statement_type *entry;
2663d8817e4Smiod 		asymbol **asymbols;
2673d8817e4Smiod 		const char *filename;
2683d8817e4Smiod 		const char *functionname;
2693d8817e4Smiod 		unsigned int linenumber;
2703d8817e4Smiod 		bfd_boolean discard_last;
2713d8817e4Smiod 
2723d8817e4Smiod 		abfd = va_arg (arg, bfd *);
2733d8817e4Smiod 		section = va_arg (arg, asection *);
2743d8817e4Smiod 		offset = va_arg (arg, bfd_vma);
2753d8817e4Smiod 
2763d8817e4Smiod 		if (abfd == NULL)
2773d8817e4Smiod 		  {
2783d8817e4Smiod 		    entry = NULL;
2793d8817e4Smiod 		    asymbols = NULL;
2803d8817e4Smiod 		  }
2813d8817e4Smiod 		else
2823d8817e4Smiod 		  {
2833d8817e4Smiod 		    entry = (lang_input_statement_type *) abfd->usrdata;
2843d8817e4Smiod 		    if (entry != (lang_input_statement_type *) NULL
2853d8817e4Smiod 			&& entry->asymbols != (asymbol **) NULL)
2863d8817e4Smiod 		      asymbols = entry->asymbols;
2873d8817e4Smiod 		    else
2883d8817e4Smiod 		      {
2893d8817e4Smiod 			long symsize;
2903d8817e4Smiod 			long sym_count;
2913d8817e4Smiod 
2923d8817e4Smiod 			symsize = bfd_get_symtab_upper_bound (abfd);
2933d8817e4Smiod 			if (symsize < 0)
2943d8817e4Smiod 			  einfo (_("%B%F: could not read symbols\n"), abfd);
2953d8817e4Smiod 			asymbols = xmalloc (symsize);
2963d8817e4Smiod 			sym_count = bfd_canonicalize_symtab (abfd, asymbols);
2973d8817e4Smiod 			if (sym_count < 0)
2983d8817e4Smiod 			  einfo (_("%B%F: could not read symbols\n"), abfd);
2993d8817e4Smiod 			if (entry != (lang_input_statement_type *) NULL)
3003d8817e4Smiod 			  {
3013d8817e4Smiod 			    entry->asymbols = asymbols;
3023d8817e4Smiod 			    entry->symbol_count = sym_count;
3033d8817e4Smiod 			  }
3043d8817e4Smiod 		      }
3053d8817e4Smiod 		  }
3063d8817e4Smiod 
3073d8817e4Smiod 		/* The GNU Coding Standard requires that error messages
3083d8817e4Smiod 		   be of the form:
3093d8817e4Smiod 
3103d8817e4Smiod 		     source-file-name:lineno: message
3113d8817e4Smiod 
3123d8817e4Smiod 		   We do not always have a line number available so if
3133d8817e4Smiod 		   we cannot find them we print out the section name and
3143d8817e4Smiod 		   offset instread.  */
3153d8817e4Smiod 		discard_last = TRUE;
3163d8817e4Smiod 		if (abfd != NULL
3173d8817e4Smiod 		    && bfd_find_nearest_line (abfd, section, asymbols, offset,
3183d8817e4Smiod 					      &filename, &functionname,
3193d8817e4Smiod 					      &linenumber))
3203d8817e4Smiod 		  {
3213d8817e4Smiod 		    if (functionname != NULL && fmt[-1] == 'C')
3223d8817e4Smiod 		      {
3233d8817e4Smiod 			/* Detect the case where we are printing out a
3243d8817e4Smiod 			   message for the same function as the last
3253d8817e4Smiod 			   call to vinfo ("%C").  In this situation do
3263d8817e4Smiod 			   not print out the ABFD filename or the
3273d8817e4Smiod 			   function name again.  Note - we do still
3283d8817e4Smiod 			   print out the source filename, as this will
3293d8817e4Smiod 			   allow programs that parse the linker's output
3303d8817e4Smiod 			   (eg emacs) to correctly locate multiple
3313d8817e4Smiod 			   errors in the same source file.  */
3323d8817e4Smiod 			if (last_bfd == NULL
3333d8817e4Smiod 			    || last_file == NULL
3343d8817e4Smiod 			    || last_function == NULL
3353d8817e4Smiod 			    || last_bfd != abfd
3363d8817e4Smiod 			    || (filename != NULL
3373d8817e4Smiod 				&& strcmp (last_file, filename) != 0)
3383d8817e4Smiod 			    || strcmp (last_function, functionname) != 0)
3393d8817e4Smiod 			  {
3403d8817e4Smiod 			    lfinfo (fp, _("%B: In function `%T':\n"),
3413d8817e4Smiod 				    abfd, functionname);
3423d8817e4Smiod 
3433d8817e4Smiod 			    last_bfd = abfd;
3443d8817e4Smiod 			    if (last_file != NULL)
3453d8817e4Smiod 			      free (last_file);
3463d8817e4Smiod 			    last_file = NULL;
3473d8817e4Smiod 			    if (filename)
3483d8817e4Smiod 			      last_file = xstrdup (filename);
3493d8817e4Smiod 			    if (last_function != NULL)
3503d8817e4Smiod 			      free (last_function);
3513d8817e4Smiod 			    last_function = xstrdup (functionname);
3523d8817e4Smiod 			  }
3533d8817e4Smiod 			discard_last = FALSE;
3543d8817e4Smiod 		      }
3553d8817e4Smiod 		    else
3563d8817e4Smiod 		      lfinfo (fp, "%B:", abfd);
3573d8817e4Smiod 
3583d8817e4Smiod 		    if (filename != NULL)
3593d8817e4Smiod 		      fprintf (fp, "%s:", filename);
3603d8817e4Smiod 
3613d8817e4Smiod 		    if (functionname != NULL && fmt[-1] == 'G')
3623d8817e4Smiod 		      lfinfo (fp, "%T", functionname);
3633d8817e4Smiod 		    else if (filename != NULL && linenumber != 0)
3643d8817e4Smiod 		      fprintf (fp, "%u", linenumber);
3653d8817e4Smiod 		    else
3663d8817e4Smiod 		      lfinfo (fp, "(%A+0x%v)", section, offset);
3673d8817e4Smiod 		  }
3683d8817e4Smiod 		else
3693d8817e4Smiod 		  lfinfo (fp, "%B:(%A+0x%v)", abfd, section, offset);
3703d8817e4Smiod 
3713d8817e4Smiod 		if (asymbols != NULL && entry == NULL)
3723d8817e4Smiod 		  free (asymbols);
3733d8817e4Smiod 
3743d8817e4Smiod 		if (discard_last)
3753d8817e4Smiod 		  {
3763d8817e4Smiod 		    last_bfd = NULL;
3773d8817e4Smiod 		    if (last_file != NULL)
3783d8817e4Smiod 		      {
3793d8817e4Smiod 			free (last_file);
3803d8817e4Smiod 			last_file = NULL;
3813d8817e4Smiod 		      }
3823d8817e4Smiod 		    if (last_function != NULL)
3833d8817e4Smiod 		      {
3843d8817e4Smiod 			free (last_function);
3853d8817e4Smiod 			last_function = NULL;
3863d8817e4Smiod 		      }
3873d8817e4Smiod 		  }
3883d8817e4Smiod 	      }
3893d8817e4Smiod 	      break;
3903d8817e4Smiod 
3913d8817e4Smiod 	    case 's':
3923d8817e4Smiod 	      /* arbitrary string, like printf */
3933d8817e4Smiod 	      fprintf (fp, "%s", va_arg (arg, char *));
3943d8817e4Smiod 	      break;
3953d8817e4Smiod 
3963d8817e4Smiod 	    case 'd':
3973d8817e4Smiod 	      /* integer, like printf */
3983d8817e4Smiod 	      fprintf (fp, "%d", va_arg (arg, int));
3993d8817e4Smiod 	      break;
4003d8817e4Smiod 
4013d8817e4Smiod 	    case 'u':
4023d8817e4Smiod 	      /* unsigned integer, like printf */
4033d8817e4Smiod 	      fprintf (fp, "%u", va_arg (arg, unsigned int));
4043d8817e4Smiod 	      break;
4053d8817e4Smiod 
4063d8817e4Smiod 	    case 'l':
4073d8817e4Smiod 	      if (*fmt == 'd')
4083d8817e4Smiod 		{
4093d8817e4Smiod 		  fprintf (fp, "%ld", va_arg (arg, long));
4103d8817e4Smiod 		  ++fmt;
4113d8817e4Smiod 		  break;
4123d8817e4Smiod 		}
4133d8817e4Smiod 	      else if (*fmt == 'u')
4143d8817e4Smiod 		{
4153d8817e4Smiod 		  fprintf (fp, "%lu", va_arg (arg, unsigned long));
4163d8817e4Smiod 		  ++fmt;
4173d8817e4Smiod 		  break;
4183d8817e4Smiod 		}
4193d8817e4Smiod 	      /* Fall thru */
4203d8817e4Smiod 
4213d8817e4Smiod 	    default:
4223d8817e4Smiod 	      fprintf (fp, "%%%c", fmt[-1]);
4233d8817e4Smiod 	      break;
4243d8817e4Smiod 	    }
4253d8817e4Smiod 	}
4263d8817e4Smiod     }
4273d8817e4Smiod 
4283d8817e4Smiod   if (is_warning && config.fatal_warnings)
4293d8817e4Smiod     config.make_executable = FALSE;
4303d8817e4Smiod 
4313d8817e4Smiod   if (fatal)
4323d8817e4Smiod     xexit (1);
4333d8817e4Smiod }
4343d8817e4Smiod 
4353d8817e4Smiod /* Wrapper around cplus_demangle.  Strips leading underscores and
4363d8817e4Smiod    other such chars that would otherwise confuse the demangler.  */
4373d8817e4Smiod 
4383d8817e4Smiod char *
demangle(const char * name)4393d8817e4Smiod demangle (const char *name)
4403d8817e4Smiod {
4413d8817e4Smiod   char *res;
4423d8817e4Smiod   const char *p;
4433d8817e4Smiod 
4443d8817e4Smiod   if (output_bfd != NULL
4453d8817e4Smiod       && bfd_get_symbol_leading_char (output_bfd) == name[0])
4463d8817e4Smiod     ++name;
4473d8817e4Smiod 
4483d8817e4Smiod   /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
4493d8817e4Smiod      or the MS PE format.  These formats have a number of leading '.'s
4503d8817e4Smiod      on at least some symbols, so we remove all dots to avoid
4513d8817e4Smiod      confusing the demangler.  */
4523d8817e4Smiod   p = name;
4533d8817e4Smiod   while (*p == '.')
4543d8817e4Smiod     ++p;
4553d8817e4Smiod 
4563d8817e4Smiod   res = cplus_demangle (p, DMGL_ANSI | DMGL_PARAMS);
4573d8817e4Smiod   if (res)
4583d8817e4Smiod     {
4593d8817e4Smiod       size_t dots = p - name;
4603d8817e4Smiod 
4613d8817e4Smiod       /* Now put back any stripped dots.  */
4623d8817e4Smiod       if (dots != 0)
4633d8817e4Smiod 	{
4643d8817e4Smiod 	  size_t len = strlen (res) + 1;
4653d8817e4Smiod 	  char *add_dots = xmalloc (len + dots);
4663d8817e4Smiod 
4673d8817e4Smiod 	  memcpy (add_dots, name, dots);
4683d8817e4Smiod 	  memcpy (add_dots + dots, res, len);
4693d8817e4Smiod 	  free (res);
4703d8817e4Smiod 	  res = add_dots;
4713d8817e4Smiod 	}
4723d8817e4Smiod       return res;
4733d8817e4Smiod     }
4743d8817e4Smiod   return xstrdup (name);
4753d8817e4Smiod }
4763d8817e4Smiod 
4773d8817e4Smiod /* Format info message and print on stdout.  */
4783d8817e4Smiod 
4793d8817e4Smiod /* (You would think this should be called just "info", but then you
4803d8817e4Smiod    would be hosed by LynxOS, which defines that name in its libc.)  */
4813d8817e4Smiod 
4823d8817e4Smiod void
info_msg(const char * fmt,...)4833d8817e4Smiod info_msg (const char *fmt, ...)
4843d8817e4Smiod {
4853d8817e4Smiod   va_list arg;
4863d8817e4Smiod 
4873d8817e4Smiod   va_start (arg, fmt);
4883d8817e4Smiod   vfinfo (stdout, fmt, arg, FALSE);
4893d8817e4Smiod   va_end (arg);
4903d8817e4Smiod }
4913d8817e4Smiod 
4923d8817e4Smiod /* ('e' for error.) Format info message and print on stderr.  */
4933d8817e4Smiod 
4943d8817e4Smiod void
einfo(const char * fmt,...)4953d8817e4Smiod einfo (const char *fmt, ...)
4963d8817e4Smiod {
4973d8817e4Smiod   va_list arg;
498*87aacc86Smillert   char buf[BUFSIZ];
4993d8817e4Smiod 
500*87aacc86Smillert   setvbuf(stderr, buf, _IOFBF, sizeof(buf));
5013d8817e4Smiod   va_start (arg, fmt);
5023d8817e4Smiod   vfinfo (stderr, fmt, arg, TRUE);
5033d8817e4Smiod   va_end (arg);
504*87aacc86Smillert   fflush(stderr);
505*87aacc86Smillert   setvbuf(stderr, NULL, _IONBF, 0);
5063d8817e4Smiod }
5073d8817e4Smiod 
5083d8817e4Smiod void
info_assert(const char * file,unsigned int line)5093d8817e4Smiod info_assert (const char *file, unsigned int line)
5103d8817e4Smiod {
5113d8817e4Smiod   einfo (_("%F%P: internal error %s %d\n"), file, line);
5123d8817e4Smiod }
5133d8817e4Smiod 
5143d8817e4Smiod /* ('m' for map) Format info message and print on map.  */
5153d8817e4Smiod 
5163d8817e4Smiod void
minfo(const char * fmt,...)5173d8817e4Smiod minfo (const char *fmt, ...)
5183d8817e4Smiod {
5193d8817e4Smiod   va_list arg;
5203d8817e4Smiod 
5213d8817e4Smiod   va_start (arg, fmt);
5223d8817e4Smiod   vfinfo (config.map_file, fmt, arg, FALSE);
5233d8817e4Smiod   va_end (arg);
5243d8817e4Smiod }
5253d8817e4Smiod 
5263d8817e4Smiod void
lfinfo(FILE * file,const char * fmt,...)5273d8817e4Smiod lfinfo (FILE *file, const char *fmt, ...)
5283d8817e4Smiod {
5293d8817e4Smiod   va_list arg;
5303d8817e4Smiod 
5313d8817e4Smiod   va_start (arg, fmt);
5323d8817e4Smiod   vfinfo (file, fmt, arg, FALSE);
5333d8817e4Smiod   va_end (arg);
5343d8817e4Smiod }
5353d8817e4Smiod 
5363d8817e4Smiod /* Functions to print the link map.  */
5373d8817e4Smiod 
5383d8817e4Smiod void
print_space(void)5393d8817e4Smiod print_space (void)
5403d8817e4Smiod {
5413d8817e4Smiod   fprintf (config.map_file, " ");
5423d8817e4Smiod }
5433d8817e4Smiod 
5443d8817e4Smiod void
print_nl(void)5453d8817e4Smiod print_nl (void)
5463d8817e4Smiod {
5473d8817e4Smiod   fprintf (config.map_file, "\n");
5483d8817e4Smiod }
5493d8817e4Smiod 
5503d8817e4Smiod /* A more or less friendly abort message.  In ld.h abort is defined to
5513d8817e4Smiod    call this function.  */
5523d8817e4Smiod 
5533d8817e4Smiod void
ld_abort(const char * file,int line,const char * fn)5543d8817e4Smiod ld_abort (const char *file, int line, const char *fn)
5553d8817e4Smiod {
5563d8817e4Smiod   if (fn != NULL)
5573d8817e4Smiod     einfo (_("%P: internal error: aborting at %s line %d in %s\n"),
5583d8817e4Smiod 	   file, line, fn);
5593d8817e4Smiod   else
5603d8817e4Smiod     einfo (_("%P: internal error: aborting at %s line %d\n"),
5613d8817e4Smiod 	   file, line);
5623d8817e4Smiod   einfo (_("%P%F: please report this bug\n"));
5633d8817e4Smiod   xexit (1);
5643d8817e4Smiod }
565