ldmisc.c revision 60484
1/* ldmisc.c
2   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
3   Free Software Foundation, Inc.
4   Written by Steve Chamberlain of Cygnus Support.
5
6This file is part of GLD, the Gnu Linker.
7
8GLD is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GLD is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GLD; see the file COPYING.  If not, write to the Free
20Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2102111-1307, USA.  */
22
23#include "bfd.h"
24#include "sysdep.h"
25#include "libiberty.h"
26#include "demangle.h"
27
28#ifdef ANSI_PROTOTYPES
29#include <stdarg.h>
30#define USE_STDARG 1
31#else
32#include <varargs.h>
33#define USE_STDARG 0
34#endif
35
36#include "ld.h"
37#include "ldmisc.h"
38#include "ldexp.h"
39#include "ldlang.h"
40#include "ldgram.h"
41#include "ldlex.h"
42#include "ldmain.h"
43#include "ldfile.h"
44
45static void vfinfo PARAMS ((FILE *, const char *, va_list));
46
47/*
48 %% literal %
49 %F error is fatal
50 %P print program name
51 %S print script file and linenumber
52 %E current bfd error or errno
53 %I filename from a lang_input_statement_type
54 %B filename from a bfd
55 %T symbol name
56 %X no object output, fail return
57 %V hex bfd_vma
58 %v hex bfd_vma, no leading zeros
59 %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces
60 %C clever filename:linenumber with function
61 %D like %C, but no function name
62 %G like %D, but only function name
63 %R info about a relent
64 %s arbitrary string, like printf
65 %d integer, like printf
66 %u integer, like printf
67*/
68
69char *
70demangle (string)
71     const char *string;
72{
73  char *res;
74
75  if (output_bfd != NULL
76      && bfd_get_symbol_leading_char (output_bfd) == string[0])
77    ++string;
78
79  /* This is a hack for better error reporting on XCOFF, or the MS PE   */
80  /* format.  Xcoff has a single '.', while the NT PE for PPC has '..'. */
81  /* So we remove all of them.                                          */
82  while(string[0] == '.')
83    ++string;
84
85  res = cplus_demangle (string, DMGL_ANSI | DMGL_PARAMS);
86  return res ? res : xstrdup (string);
87}
88
89static void
90vfinfo (fp, fmt, arg)
91     FILE *fp;
92     const char *fmt;
93     va_list arg;
94{
95  boolean fatal = false;
96
97  while (*fmt != '\0')
98    {
99      while (*fmt != '%' && *fmt != '\0')
100	{
101	  putc (*fmt, fp);
102	  fmt++;
103	}
104
105      if (*fmt == '%')
106	{
107	  fmt ++;
108	  switch (*fmt++)
109	    {
110	    default:
111	      fprintf (fp,"%%%c", fmt[-1]);
112	      break;
113
114	    case '%':
115	      /* literal % */
116	      putc ('%', fp);
117	      break;
118
119	    case 'X':
120	      /* no object output, fail return */
121	      config.make_executable = false;
122	      break;
123
124	    case 'V':
125	      /* hex bfd_vma */
126	      {
127		bfd_vma value = va_arg (arg, bfd_vma);
128		fprintf_vma (fp, value);
129	      }
130	      break;
131
132	    case 'v':
133	      /* hex bfd_vma, no leading zeros */
134	      {
135		char buf[100];
136		char *p = buf;
137		bfd_vma value = va_arg (arg, bfd_vma);
138		sprintf_vma (p, value);
139		while (*p == '0')
140		  p++;
141		if (!*p)
142		  p--;
143		fputs (p, fp);
144	      }
145	      break;
146
147	    case 'W':
148	      /* hex bfd_vma with 0x with no leading zeroes taking up
149                 8 spaces.  */
150	      {
151		char buf[100];
152		bfd_vma value;
153		char *p;
154		int len;
155
156		value = va_arg (arg, bfd_vma);
157		sprintf_vma (buf, value);
158		for (p = buf; *p == '0'; ++p)
159		  ;
160		if (*p == '\0')
161		  --p;
162		len = strlen (p);
163		while (len < 8)
164		  {
165		    putc (' ', fp);
166		    ++len;
167		  }
168		fprintf (fp, "0x%s", p);
169	      }
170	      break;
171
172	    case 'T':
173	      /* Symbol name.  */
174	      {
175		const char *name = va_arg (arg, const char *);
176
177		if (name == (const char *) NULL || *name == 0)
178		  fprintf (fp, _("no symbol"));
179		else if (! demangling)
180		  fprintf (fp, "%s", name);
181		else
182		  {
183		    char *demangled;
184
185		    demangled = demangle (name);
186		    fprintf (fp, "%s", demangled);
187		    free (demangled);
188		  }
189	      }
190	      break;
191
192	    case 'B':
193	      /* filename from a bfd */
194	      {
195		bfd *abfd = va_arg (arg, bfd *);
196		if (abfd->my_archive)
197		  fprintf (fp, "%s(%s)", abfd->my_archive->filename,
198			   abfd->filename);
199		else
200		  fprintf (fp, "%s", abfd->filename);
201	      }
202	      break;
203
204	    case 'F':
205	      /* error is fatal */
206	      fatal = true;
207	      break;
208
209	    case 'P':
210	      /* print program name */
211	      fprintf (fp, "%s", program_name);
212	      break;
213
214	    case 'E':
215	      /* current bfd error or errno */
216	      fprintf (fp, "%s", bfd_errmsg (bfd_get_error ()));
217	      break;
218
219	    case 'I':
220	      /* filename from a lang_input_statement_type */
221	      {
222		lang_input_statement_type *i;
223
224		i = va_arg (arg, lang_input_statement_type *);
225		if (bfd_my_archive (i->the_bfd) != NULL)
226		  fprintf (fp, "(%s)",
227			   bfd_get_filename (bfd_my_archive (i->the_bfd)));
228		fprintf (fp, "%s", i->local_sym_name);
229		if (bfd_my_archive (i->the_bfd) == NULL
230		    && strcmp (i->local_sym_name, i->filename) != 0)
231		  fprintf (fp, " (%s)", i->filename);
232	      }
233	      break;
234
235	    case 'S':
236	      /* print script file and linenumber */
237	      if (parsing_defsym)
238		fprintf (fp, "--defsym %s", lex_string);
239	      else if (ldfile_input_filename != NULL)
240		fprintf (fp, "%s:%u", ldfile_input_filename, lineno);
241	      else
242		fprintf (fp, _("built in linker script:%u"), lineno);
243	      break;
244
245	    case 'R':
246	      /* Print all that's interesting about a relent */
247	      {
248		arelent *relent = va_arg (arg, arelent *);
249
250		lfinfo (fp, "%s+0x%v (type %s)",
251			(*(relent->sym_ptr_ptr))->name,
252			relent->addend,
253			relent->howto->name);
254	      }
255	      break;
256
257	    case 'C':
258	    case 'D':
259	    case 'G':
260	      /* Clever filename:linenumber with function name if possible,
261		 or section name as a last resort.  The arguments are a BFD,
262		 a section, and an offset.  */
263	      {
264		static bfd *last_bfd;
265		static char *last_file = NULL;
266		static char *last_function = NULL;
267		bfd *abfd;
268		asection *section;
269		bfd_vma offset;
270		lang_input_statement_type *entry;
271		asymbol **asymbols;
272		const char *filename;
273		const char *functionname;
274		unsigned int linenumber;
275		boolean discard_last;
276
277		abfd = va_arg (arg, bfd *);
278		section = va_arg (arg, asection *);
279		offset = va_arg (arg, bfd_vma);
280
281		entry = (lang_input_statement_type *) abfd->usrdata;
282		if (entry != (lang_input_statement_type *) NULL
283		    && entry->asymbols != (asymbol **) NULL)
284		  asymbols = entry->asymbols;
285		else
286		  {
287		    long symsize;
288		    long symbol_count;
289
290		    symsize = bfd_get_symtab_upper_bound (abfd);
291		    if (symsize < 0)
292		      einfo (_("%B%F: could not read symbols\n"), abfd);
293		    asymbols = (asymbol **) xmalloc (symsize);
294		    symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
295		    if (symbol_count < 0)
296		      einfo (_("%B%F: could not read symbols\n"), abfd);
297		    if (entry != (lang_input_statement_type *) NULL)
298		      {
299			entry->asymbols = asymbols;
300			entry->symbol_count = symbol_count;
301		      }
302		  }
303
304		discard_last = true;
305		if (bfd_find_nearest_line (abfd, section, asymbols, offset,
306					   &filename, &functionname,
307					   &linenumber))
308		  {
309		    if (functionname != NULL && fmt[-1] == 'G')
310		      {
311			lfinfo (fp, "%B:", abfd);
312			if (filename != NULL
313			    && strcmp (filename, bfd_get_filename (abfd)) != 0)
314			  fprintf (fp, "%s:", filename);
315			lfinfo (fp, "%T", functionname);
316		      }
317		    else if (functionname != NULL && fmt[-1] == 'C')
318		      {
319			if (filename == (char *) NULL)
320			  filename = abfd->filename;
321
322			if (last_bfd == NULL
323			    || last_file == NULL
324			    || last_function == NULL
325			    || last_bfd != abfd
326			    || strcmp (last_file, filename) != 0
327			    || strcmp (last_function, functionname) != 0)
328			  {
329			    /* We use abfd->filename in this initial line,
330			       in case filename is a .h file or something
331			       similarly unhelpful.  */
332			    lfinfo (fp, _("%B: In function `%T':\n"),
333				    abfd, functionname);
334
335			    last_bfd = abfd;
336			    if (last_file != NULL)
337			      free (last_file);
338			    last_file = buystring (filename);
339			    if (last_function != NULL)
340			      free (last_function);
341			    last_function = buystring (functionname);
342			  }
343			discard_last = false;
344			if (linenumber != 0)
345			  fprintf (fp, "%s:%u", filename, linenumber);
346			else
347			  lfinfo (fp, "%s(%s+0x%v)", filename, section->name,
348				  offset);
349		      }
350		    else if (filename == NULL
351			     || strcmp (filename, abfd->filename) == 0)
352		      {
353			lfinfo (fp, "%B(%s+0x%v)", abfd, section->name,
354				offset);
355			if (linenumber != 0)
356			  lfinfo (fp, ":%u", linenumber);
357		      }
358		    else if (linenumber != 0)
359		      lfinfo (fp, "%B:%s:%u", abfd, filename, linenumber);
360		    else
361		      lfinfo (fp, "%B(%s+0x%v):%s", abfd, section->name,
362			      offset, filename);
363		  }
364		else
365		  lfinfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
366
367		if (discard_last)
368		  {
369		    last_bfd = NULL;
370		    if (last_file != NULL)
371		      {
372			free (last_file);
373			last_file = NULL;
374		      }
375		    if (last_function != NULL)
376		      {
377			free (last_function);
378			last_function = NULL;
379		      }
380		  }
381	      }
382	      break;
383
384	    case 's':
385	      /* arbitrary string, like printf */
386	      fprintf (fp, "%s", va_arg (arg, char *));
387	      break;
388
389	    case 'd':
390	      /* integer, like printf */
391	      fprintf (fp, "%d", va_arg (arg, int));
392	      break;
393
394	    case 'u':
395	      /* unsigned integer, like printf */
396	      fprintf (fp, "%u", va_arg (arg, unsigned int));
397	      break;
398	    }
399	}
400    }
401
402  if (fatal == true)
403    xexit(1);
404}
405
406/* Format info message and print on stdout. */
407
408/* (You would think this should be called just "info", but then you
409   would hosed by LynxOS, which defines that name in its libc.)  */
410
411void
412#if USE_STDARG
413info_msg (const char *fmt, ...)
414#else
415info_msg (va_alist)
416     va_dcl
417#endif
418{
419  va_list arg;
420
421#if ! USE_STDARG
422  const char *fmt;
423
424  va_start (arg);
425  fmt = va_arg (arg, const char *);
426#else
427  va_start (arg, fmt);
428#endif
429
430  vfinfo (stdout, fmt, arg);
431  va_end (arg);
432}
433
434/* ('e' for error.) Format info message and print on stderr. */
435
436void
437#if USE_STDARG
438einfo (const char *fmt, ...)
439#else
440einfo (va_alist)
441     va_dcl
442#endif
443{
444  va_list arg;
445
446#if ! USE_STDARG
447  const char *fmt;
448
449  va_start (arg);
450  fmt = va_arg (arg, const char *);
451#else
452  va_start (arg, fmt);
453#endif
454
455  vfinfo (stderr, fmt, arg);
456  va_end (arg);
457}
458
459void
460info_assert (file, line)
461     const char *file;
462     unsigned int line;
463{
464  einfo (_("%F%P: internal error %s %d\n"), file, line);
465}
466
467char *
468buystring (x)
469     CONST char *CONST x;
470{
471  size_t l = strlen(x)+1;
472  char *r = xmalloc(l);
473  memcpy(r, x,l);
474  return r;
475}
476
477/* ('m' for map) Format info message and print on map. */
478
479void
480#if USE_STDARG
481minfo (const char *fmt, ...)
482#else
483minfo (va_alist)
484     va_dcl
485#endif
486{
487  va_list arg;
488
489#if ! USE_STDARG
490  const char *fmt;
491  va_start (arg);
492  fmt = va_arg (arg, const char *);
493#else
494  va_start (arg, fmt);
495#endif
496
497  vfinfo (config.map_file, fmt, arg);
498  va_end (arg);
499}
500
501void
502#if USE_STDARG
503lfinfo (FILE *file, const char *fmt, ...)
504#else
505lfinfo (va_alist)
506     va_dcl
507#endif
508{
509  va_list arg;
510
511#if ! USE_STDARG
512  FILE *file;
513  const char *fmt;
514
515  va_start (arg);
516  file = va_arg (arg, FILE *);
517  fmt = va_arg (arg, const char *);
518#else
519  va_start (arg, fmt);
520#endif
521
522  vfinfo (file, fmt, arg);
523  va_end (arg);
524}
525
526/* Functions to print the link map.  */
527
528void
529print_space ()
530{
531  fprintf (config.map_file, " ");
532}
533
534void
535print_nl ()
536{
537  fprintf (config.map_file, "\n");
538}
539
540/* A more or less friendly abort message.  In ld.h abort is defined to
541   call this function.  */
542
543void
544ld_abort (file, line, fn)
545     const char *file;
546     int line;
547     const char *fn;
548{
549  if (fn != NULL)
550    einfo (_("%P: internal error: aborting at %s line %d in %s\n"),
551	   file, line, fn);
552  else
553    einfo (_("%P: internal error: aborting at %s line %d\n"),
554	   file, line);
555  einfo (_("%P%F: please report this bug\n"));
556  xexit (1);
557}
558