xref: /openbsd-src/gnu/usr.bin/binutils/ld/ldmisc.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
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 
6 This file is part of GLD, the Gnu Linker.
7 
8 GLD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12 
13 GLD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GLD; see the file COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-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 
45 static 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 
69 char *
70 demangle (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 
89 static void
90 vfinfo (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 
411 void
412 #if USE_STDARG
413 info_msg (const char *fmt, ...)
414 #else
415 info_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 
436 void
437 #if USE_STDARG
438 einfo (const char *fmt, ...)
439 #else
440 einfo (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 
459 void
460 info_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 
467 char *
468 buystring (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 
479 void
480 #if USE_STDARG
481 minfo (const char *fmt, ...)
482 #else
483 minfo (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 
501 void
502 #if USE_STDARG
503 lfinfo (FILE *file, const char *fmt, ...)
504 #else
505 lfinfo (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 
528 void
529 print_space ()
530 {
531   fprintf (config.map_file, " ");
532 }
533 
534 void
535 print_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 
543 void
544 ld_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