* ldlang.c, ldmain.c, ldmisc.c: Use bfd_get_error and
[external/binutils.git] / ld / ldmisc.c
1 /* ldmisc.c
2    Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
3
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
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include <varargs.h>
25 #include <demangle.h>
26
27 #include "ld.h"
28 #include "ldmisc.h"
29 #include "ldexp.h"
30 #include "ldlang.h"
31 #include "ldlex.h"
32 #include "ldmain.h"
33 #include "ldfile.h"
34
35 /* VARARGS*/
36 static void finfo ();
37 static const char *demangle PARAMS ((const char *string,
38                                      int remove_underscore));
39
40 /*
41  %% literal %
42  %F error is fatal
43  %P print program name
44  %S print script file and linenumber
45  %E current bfd error or errno
46  %I filename from a lang_input_statement_type
47  %B filename from a bfd
48  %T symbol name
49  %X no object output, fail return
50  %V hex bfd_vma
51  %v hex bfd_vma, no leading zeros
52  %C Clever filename:linenumber 
53  %R info about a relent
54  %s arbitrary string, like printf
55  %d integer, like printf
56 */
57
58 static const char *
59 demangle (string, remove_underscore)
60      const char *string;
61      int remove_underscore;
62 {
63   const char *res;
64   if (remove_underscore && output_bfd) 
65   {
66     if (bfd_get_symbol_leading_char (output_bfd) == string[0])
67      string++;
68   }
69   /* Note that there's a memory leak here, we keep buying memory
70      for demangled names, and never free.  But if you have so many
71      errors that you run out of VM with the error messages, then
72      there's something up */
73   res = cplus_demangle (string, DMGL_ANSI|DMGL_PARAMS);
74   return res ? res : string;
75 }
76
77 static void
78 vfinfo(fp, fmt, arg)
79      FILE *fp;
80      char *fmt;
81      va_list arg;
82 {
83   boolean fatal = false;
84
85   while (*fmt) 
86   {
87     while (*fmt != '%' && *fmt != '\0') 
88     {
89       putc(*fmt, fp);
90       fmt++;
91     }
92
93     if (*fmt == '%') 
94     {
95       fmt ++;
96       switch (*fmt++) 
97       {
98       default:
99         fprintf(fp,"%%%c", fmt[-1]);
100         break;
101
102       case '%':
103         /* literal % */
104         putc('%', fp);
105         break;
106
107        case 'X':
108         /* no object output, fail return */
109         config.make_executable = false;
110         break;
111
112        case 'V':
113         /* hex bfd_vma */
114         {
115           bfd_vma value = va_arg(arg, bfd_vma);
116           fprintf_vma(fp, value);
117         }
118         break;
119
120       case 'v':
121         /* hex bfd_vma, no leading zeros */
122         {
123           char buf[100];
124           char *p = buf;
125           bfd_vma value = va_arg (arg, bfd_vma);
126           sprintf_vma (p, value);
127           while (*p == '0')
128             p++;
129           if (!*p)
130             p--;
131           fputs (p, fp);
132         }
133         break;
134
135        case 'T':
136         /* Symbol name.  */
137         {
138           const char *name = va_arg (arg, const char *);
139
140           if (name != (const char *) NULL)
141             fprintf (fp, "%s", demangle (name, 1));
142           else
143             fprintf (fp, "no symbol");
144         }
145         break;
146
147        case 'B':
148         /* filename from a bfd */
149        { 
150          bfd *abfd = va_arg(arg, bfd *);
151          if (abfd->my_archive) {
152            fprintf(fp,"%s(%s)", abfd->my_archive->filename,
153                    abfd->filename);
154          }
155          else {
156            fprintf(fp,"%s", abfd->filename);
157          }
158        }
159         break;
160
161        case 'F':
162         /* error is fatal */
163         fatal = true;
164         break;
165
166        case 'P':
167         /* print program name */
168         fprintf(fp,"%s", program_name);
169         break;
170
171        case 'E':
172         /* current bfd error or errno */
173         fprintf(fp, bfd_errmsg(bfd_get_error ()));
174         break;
175
176        case 'I':
177         /* filename from a lang_input_statement_type */
178        {
179          lang_input_statement_type *i =
180           va_arg(arg,lang_input_statement_type *);
181
182          if (i->the_bfd->my_archive)
183            fprintf(fp, "(%s)", i->the_bfd->my_archive->filename);
184          fprintf(fp,"%s", i->local_sym_name);
185        }
186         break;
187
188        case 'S':
189         /* print script file and linenumber */
190        {
191          if (ldfile_input_filename == (char *)NULL) {
192            fprintf(fp,"command line");
193          }
194          else {
195            fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
196          }
197        }
198         break;
199
200        case 'R':
201         /* Print all that's interesting about a relent */
202        {
203          arelent *relent = va_arg(arg, arelent *);
204         
205          finfo (fp, "%s+0x%v (type %s)",
206                 (*(relent->sym_ptr_ptr))->name,
207                 relent->addend,
208                 relent->howto->name);
209        }
210         break;
211         
212        case 'C':
213         /* Clever filename:linenumber with function name if possible,
214            or section name as a last resort.  The arguments are a BFD,
215            a section, and an offset.  */
216         {
217           bfd *abfd;
218           asection *section;
219           bfd_vma offset;
220           lang_input_statement_type *entry;
221           asymbol **asymbols;
222           const char *filename;
223           const char *functionname;
224           unsigned int linenumber;
225
226           abfd = va_arg (arg, bfd *);
227           section = va_arg (arg, asection *);
228           offset = va_arg (arg, bfd_vma);
229
230           entry = (lang_input_statement_type *) abfd->usrdata;
231           if (entry != (lang_input_statement_type *) NULL
232               && entry->asymbols != (asymbol **) NULL)
233             asymbols = entry->asymbols;
234           else
235             {
236               unsigned int symsize;
237               unsigned int symbol_count;
238
239               symsize = get_symtab_upper_bound (abfd);
240               asymbols = (asymbol **) xmalloc (symsize);
241               symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
242               if (entry != (lang_input_statement_type *) NULL)
243                 {
244                   entry->asymbols = asymbols;
245                   entry->symbol_count = symbol_count;
246                 }
247             }
248
249           if (bfd_find_nearest_line (abfd, section, asymbols, offset,
250                                      &filename, &functionname, &linenumber))
251             {
252               if (filename == (char *) NULL)
253                 filename = abfd->filename;
254
255               if (functionname != (char *)NULL) 
256                 fprintf (fp, "%s:%u: %s", filename, linenumber,
257                          demangle (functionname, 1));
258               else if (linenumber != 0) 
259                 fprintf (fp, "%s:%u", filename, linenumber);
260               else
261                 finfo (fp, "%s(%s+0x%v)", filename, section->name, offset);
262
263             }
264           else
265             finfo (fp, "%s(%s+0x%v)", abfd->filename, section->name, offset);
266         }
267         break;
268                 
269        case 's':
270         /* arbitrary string, like printf */
271         fprintf(fp,"%s", va_arg(arg, char *));
272         break;
273
274        case 'd':
275         /* integer, like printf */
276         fprintf(fp,"%d", va_arg(arg, int));
277         break;
278       }
279     }
280   }
281
282   if (fatal == true) 
283     xexit(1);
284 }
285
286 /* Format info message and print on stdout. */
287
288 /* (You would think this should be called just "info", but then you would
289    hosed by LynxOS, which defines that name in its libc.) */
290
291 void info_msg(va_alist)
292      va_dcl
293 {
294   char *fmt;
295   va_list arg;
296   va_start(arg);
297   fmt = va_arg(arg, char *);
298   vfinfo(stdout, fmt, arg);
299   va_end(arg);
300 }
301
302 /* ('e' for error.) Format info message and print on stderr. */
303
304 void einfo(va_alist)
305      va_dcl
306 {
307   char *fmt;
308   va_list arg;
309   va_start(arg);
310   fmt = va_arg(arg, char *);
311   vfinfo(stderr, fmt, arg);
312   va_end(arg);
313 }
314
315 /* Warn about a symbol NEWSYM being multiply defined with another symbol OLDSYM.
316    MESSAGE1 and MESSAGE2 should look something like:
317    "%C: warning: multiple commons of `%s'\n"
318    "%C: warning: previous common here\n"  */
319
320 void
321 multiple_warn (message1, newsym, message2, oldsym)
322      char *message1;
323      asymbol *newsym;
324      char *message2;
325      asymbol *oldsym;
326 {
327   lang_input_statement_type *inp_stat;
328   asymbol **stat_symbols;
329
330   inp_stat = (lang_input_statement_type *) bfd_asymbol_bfd (newsym)->usrdata;
331   stat_symbols = inp_stat ? inp_stat->asymbols : 0;
332
333   einfo (message1,
334          bfd_asymbol_bfd (newsym), newsym->section, stat_symbols, newsym->value,
335          demangle (newsym->name, 1));
336
337   inp_stat = (lang_input_statement_type *) bfd_asymbol_bfd (oldsym)->usrdata;
338   stat_symbols = inp_stat ? inp_stat->asymbols : 0;
339
340   einfo (message2,
341          bfd_asymbol_bfd (oldsym), oldsym->section, stat_symbols, oldsym->value);
342 }
343
344 void 
345 info_assert(file, line)
346      char *file;
347      unsigned int line;
348 {
349   einfo("%F%P: internal error %s %d\n", file,line);
350 }
351
352 /* Return a newly-allocated string
353    whose contents concatenate those of S1, S2, S3.  */
354
355 char *
356 concat (s1, s2, s3)
357      CONST char *s1;
358      CONST char *s2;
359      CONST char *s3;
360 {
361   size_t len1 = strlen (s1);
362   size_t len2 = strlen (s2);
363   size_t len3 = strlen (s3);
364   char *result = xmalloc (len1 + len2 + len3 + 1);
365
366   if (len1 != 0)
367     memcpy(result, s1, len1);
368   if (len2 != 0)
369     memcpy(result+len1, s2, len2);
370   if (len3 != 0)
371     memcpy(result+len1+len2, s2, len3);
372   *(result + len1 + len2 + len3) = 0;
373
374   return result;
375 }
376
377 char *
378 buystring (x)
379      CONST char *CONST x;
380 {
381   size_t l = strlen(x)+1;
382   char *r = xmalloc(l);
383   memcpy(r, x,l);
384   return r;
385 }
386
387
388 /* ('m' for map) Format info message and print on map. */
389
390 void minfo(va_alist)
391      va_dcl
392 {
393   char *fmt;
394   va_list arg;
395   va_start(arg);
396   fmt = va_arg(arg, char *);
397   vfinfo(config.map_file, fmt, arg);
398   va_end(arg);
399 }
400
401
402 static void
403 finfo (va_alist)
404      va_dcl
405 {
406   char *fmt;
407   FILE *file;
408   va_list arg;
409   va_start (arg);
410   file = va_arg (arg, FILE *);
411   fmt = va_arg (arg, char *);
412   vfinfo (file, fmt, arg);
413   va_end (arg);
414 }
415
416
417
418 /*----------------------------------------------------------------------
419   Functions to print the link map 
420  */
421
422 void 
423 print_space ()
424 {
425   fprintf(config.map_file, " ");
426 }
427 void 
428 print_nl ()
429 {
430   fprintf(config.map_file, "\n");
431 }
432 void 
433 print_address (value)
434      bfd_vma value;
435 {
436   fprintf_vma(config.map_file, value);
437 }