OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [ld/] [ldmisc.c] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 jlechner
/* ldmisc.c
2
   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4
   Free Software Foundation, Inc.
5
   Written by Steve Chamberlain of Cygnus Support.
6
 
7
   This file is part of the GNU Binutils.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22
   MA 02110-1301, USA.  */
23
 
24
#include "sysdep.h"
25
#include "bfd.h"
26
#include "bfdlink.h"
27
#include "libiberty.h"
28
#include "demangle.h"
29
#include <stdarg.h>
30
#include "ld.h"
31
#include "ldmisc.h"
32
#include "ldexp.h"
33
#include "ldlang.h"
34
#include <ldgram.h>
35
#include "ldlex.h"
36
#include "ldmain.h"
37
#include "ldfile.h"
38
#include "elf-bfd.h"
39
 
40
/*
41
 %% literal %
42
 %A section name from a section
43
 %B filename from a bfd
44
 %C clever filename:linenumber with function
45
 %D like %C, but no function name
46
 %E current bfd error or errno
47
 %F error is fatal
48
 %G like %D, but only function name
49
 %I filename from a lang_input_statement_type
50
 %P print program name
51
 %R info about a relent
52
 %S print script file and linenumber
53
 %T symbol name
54
 %V hex bfd_vma
55
 %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces
56
 %X no object output, fail return
57
 %d integer, like printf
58
 %ld long, like printf
59
 %lu unsigned long, like printf
60
 %s arbitrary string, like printf
61
 %u integer, like printf
62
 %v hex bfd_vma, no leading zeros
63
*/
64
 
65
static void
66
vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
67
{
68
  bfd_boolean fatal = FALSE;
69
 
70
  while (*fmt != '\0')
71
    {
72
      while (*fmt != '%' && *fmt != '\0')
73
        {
74
          putc (*fmt, fp);
75
          fmt++;
76
        }
77
 
78
      if (*fmt == '%')
79
        {
80
          fmt++;
81
          switch (*fmt++)
82
            {
83
            case '%':
84
              /* literal % */
85
              putc ('%', fp);
86
              break;
87
 
88
            case 'X':
89
              /* no object output, fail return */
90
              config.make_executable = FALSE;
91
              break;
92
 
93
            case 'V':
94
              /* hex bfd_vma */
95
              {
96
                bfd_vma value = va_arg (arg, bfd_vma);
97
                fprintf_vma (fp, value);
98
              }
99
              break;
100
 
101
            case 'v':
102
              /* hex bfd_vma, no leading zeros */
103
              {
104
                char buf[100];
105
                char *p = buf;
106
                bfd_vma value = va_arg (arg, bfd_vma);
107
                sprintf_vma (p, value);
108
                while (*p == '0')
109
                  p++;
110
                if (!*p)
111
                  p--;
112
                fputs (p, fp);
113
              }
114
              break;
115
 
116
            case 'W':
117
              /* hex bfd_vma with 0x with no leading zeroes taking up
118
                 8 spaces.  */
119
              {
120
                char buf[100];
121
                bfd_vma value;
122
                char *p;
123
                int len;
124
 
125
                value = va_arg (arg, bfd_vma);
126
                sprintf_vma (buf, value);
127
                for (p = buf; *p == '0'; ++p)
128
                  ;
129
                if (*p == '\0')
130
                  --p;
131
                len = strlen (p);
132
                while (len < 8)
133
                  {
134
                    putc (' ', fp);
135
                    ++len;
136
                  }
137
                fprintf (fp, "0x%s", p);
138
              }
139
              break;
140
 
141
            case 'T':
142
              /* Symbol name.  */
143
              {
144
                const char *name = va_arg (arg, const char *);
145
 
146
                if (name == NULL || *name == 0)
147
                  {
148
                    fprintf (fp, _("no symbol"));
149
                    break;
150
                  }
151
                else if (demangling)
152
                  {
153
                    char *demangled;
154
 
155
                    demangled = bfd_demangle (link_info.output_bfd, name,
156
                                              DMGL_ANSI | DMGL_PARAMS);
157
                    if (demangled != NULL)
158
                      {
159
                        fprintf (fp, "%s", demangled);
160
                        free (demangled);
161
                        break;
162
                      }
163
                  }
164
                fprintf (fp, "%s", name);
165
              }
166
              break;
167
 
168
            case 'A':
169
              /* section name from a section */
170
              {
171
                asection *sec = va_arg (arg, asection *);
172
                bfd *abfd = sec->owner;
173
                const char *group = NULL;
174
                struct coff_comdat_info *ci;
175
 
176
                fprintf (fp, "%s", sec->name);
177
                if (abfd != NULL
178
                    && bfd_get_flavour (abfd) == bfd_target_elf_flavour
179
                    && elf_next_in_group (sec) != NULL
180
                    && (sec->flags & SEC_GROUP) == 0)
181
                  group = elf_group_name (sec);
182
                else if (abfd != NULL
183
                         && bfd_get_flavour (abfd) == bfd_target_coff_flavour
184
                         && (ci = bfd_coff_get_comdat_section (sec->owner,
185
                                                               sec)) != NULL)
186
                  group = ci->name;
187
                if (group != NULL)
188
                  fprintf (fp, "[%s]", group);
189
              }
190
              break;
191
 
192
            case 'B':
193
              /* filename from a bfd */
194
              {
195
                bfd *abfd = va_arg (arg, bfd *);
196
 
197
                if (abfd == NULL)
198
                  fprintf (fp, "%s generated", program_name);
199
                else if (abfd->my_archive)
200
                  fprintf (fp, "%s(%s)", abfd->my_archive->filename,
201
                           abfd->filename);
202
                else
203
                  fprintf (fp, "%s", abfd->filename);
204
              }
205
              break;
206
 
207
            case 'F':
208
              /* Error is fatal.  */
209
              fatal = TRUE;
210
              break;
211
 
212
            case 'P':
213
              /* Print program name.  */
214
              fprintf (fp, "%s", program_name);
215
              break;
216
 
217
            case 'E':
218
              /* current bfd error or errno */
219
              fprintf (fp, "%s", bfd_errmsg (bfd_get_error ()));
220
              break;
221
 
222
            case 'I':
223
              /* filename from a lang_input_statement_type */
224
              {
225
                lang_input_statement_type *i;
226
 
227
                i = va_arg (arg, lang_input_statement_type *);
228
                if (bfd_my_archive (i->the_bfd) != NULL)
229
                  fprintf (fp, "(%s)",
230
                           bfd_get_filename (bfd_my_archive (i->the_bfd)));
231
                fprintf (fp, "%s", i->local_sym_name);
232
                if (bfd_my_archive (i->the_bfd) == NULL
233
                    && strcmp (i->local_sym_name, i->filename) != 0)
234
                  fprintf (fp, " (%s)", i->filename);
235
              }
236
              break;
237
 
238
            case 'S':
239
              /* Print script file and linenumber.  */
240
              if (parsing_defsym)
241
                fprintf (fp, "--defsym %s", lex_string);
242
              else if (ldfile_input_filename != NULL)
243
                fprintf (fp, "%s:%u", ldfile_input_filename, lineno);
244
              else
245
                fprintf (fp, _("built in linker script:%u"), lineno);
246
              break;
247
 
248
            case 'R':
249
              /* Print all that's interesting about a relent.  */
250
              {
251
                arelent *relent = va_arg (arg, arelent *);
252
 
253
                lfinfo (fp, "%s+0x%v (type %s)",
254
                        (*(relent->sym_ptr_ptr))->name,
255
                        relent->addend,
256
                        relent->howto->name);
257
              }
258
              break;
259
 
260
            case 'C':
261
            case 'D':
262
            case 'G':
263
              /* Clever filename:linenumber with function name if possible.
264
                 The arguments are a BFD, a section, and an offset.  */
265
              {
266
                static bfd *last_bfd;
267
                static char *last_file = NULL;
268
                static char *last_function = NULL;
269
                bfd *abfd;
270
                asection *section;
271
                bfd_vma offset;
272
                asymbol **asymbols = NULL;
273
                const char *filename;
274
                const char *functionname;
275
                unsigned int linenumber;
276
                bfd_boolean discard_last;
277
 
278
                abfd = va_arg (arg, bfd *);
279
                section = va_arg (arg, asection *);
280
                offset = va_arg (arg, bfd_vma);
281
 
282
                if (abfd != NULL)
283
                  {
284
                    if (!bfd_generic_link_read_symbols (abfd))
285
                      einfo (_("%B%F: could not read symbols: %E\n"), abfd);
286
 
287
                    asymbols = bfd_get_outsymbols (abfd);
288
                  }
289
 
290
                /* The GNU Coding Standard requires that error messages
291
                   be of the form:
292
 
293
                     source-file-name:lineno: message
294
 
295
                   We do not always have a line number available so if
296
                   we cannot find them we print out the section name and
297
                   offset instread.  */
298
                discard_last = TRUE;
299
                if (abfd != NULL
300
                    && bfd_find_nearest_line (abfd, section, asymbols, offset,
301
                                              &filename, &functionname,
302
                                              &linenumber))
303
                  {
304
                    if (functionname != NULL && fmt[-1] == 'C')
305
                      {
306
                        /* Detect the case where we are printing out a
307
                           message for the same function as the last
308
                           call to vinfo ("%C").  In this situation do
309
                           not print out the ABFD filename or the
310
                           function name again.  Note - we do still
311
                           print out the source filename, as this will
312
                           allow programs that parse the linker's output
313
                           (eg emacs) to correctly locate multiple
314
                           errors in the same source file.  */
315
                        if (last_bfd == NULL
316
                            || last_file == NULL
317
                            || last_function == NULL
318
                            || last_bfd != abfd
319
                            || (filename != NULL
320
                                && strcmp (last_file, filename) != 0)
321
                            || strcmp (last_function, functionname) != 0)
322
                          {
323
                            lfinfo (fp, _("%B: In function `%T':\n"),
324
                                    abfd, functionname);
325
 
326
                            last_bfd = abfd;
327
                            if (last_file != NULL)
328
                              free (last_file);
329
                            last_file = NULL;
330
                            if (filename)
331
                              last_file = xstrdup (filename);
332
                            if (last_function != NULL)
333
                              free (last_function);
334
                            last_function = xstrdup (functionname);
335
                          }
336
                        discard_last = FALSE;
337
                      }
338
                    else
339
                      lfinfo (fp, "%B:", abfd);
340
 
341
                    if (filename != NULL)
342
                      fprintf (fp, "%s:", filename);
343
 
344
                    if (functionname != NULL && fmt[-1] == 'G')
345
                      lfinfo (fp, "%T", functionname);
346
                    else if (filename != NULL && linenumber != 0)
347
                      fprintf (fp, "%u", linenumber);
348
                    else
349
                      lfinfo (fp, "(%A+0x%v)", section, offset);
350
                  }
351
                else
352
                  lfinfo (fp, "%B:(%A+0x%v)", abfd, section, offset);
353
 
354
                if (discard_last)
355
                  {
356
                    last_bfd = NULL;
357
                    if (last_file != NULL)
358
                      {
359
                        free (last_file);
360
                        last_file = NULL;
361
                      }
362
                    if (last_function != NULL)
363
                      {
364
                        free (last_function);
365
                        last_function = NULL;
366
                      }
367
                  }
368
              }
369
              break;
370
 
371
            case 's':
372
              /* arbitrary string, like printf */
373
              fprintf (fp, "%s", va_arg (arg, char *));
374
              break;
375
 
376
            case 'd':
377
              /* integer, like printf */
378
              fprintf (fp, "%d", va_arg (arg, int));
379
              break;
380
 
381
            case 'u':
382
              /* unsigned integer, like printf */
383
              fprintf (fp, "%u", va_arg (arg, unsigned int));
384
              break;
385
 
386
            case 'l':
387
              if (*fmt == 'd')
388
                {
389
                  fprintf (fp, "%ld", va_arg (arg, long));
390
                  ++fmt;
391
                  break;
392
                }
393
              else if (*fmt == 'u')
394
                {
395
                  fprintf (fp, "%lu", va_arg (arg, unsigned long));
396
                  ++fmt;
397
                  break;
398
                }
399
              /* Fall thru */
400
 
401
            default:
402
              fprintf (fp, "%%%c", fmt[-1]);
403
              break;
404
            }
405
        }
406
    }
407
 
408
  if (is_warning && config.fatal_warnings)
409
    config.make_executable = FALSE;
410
 
411
  if (fatal)
412
    xexit (1);
413
}
414
 
415
/* Format info message and print on stdout.  */
416
 
417
/* (You would think this should be called just "info", but then you
418
   would be hosed by LynxOS, which defines that name in its libc.)  */
419
 
420
void
421
info_msg (const char *fmt, ...)
422
{
423
  va_list arg;
424
 
425
  va_start (arg, fmt);
426
  vfinfo (stdout, fmt, arg, FALSE);
427
  va_end (arg);
428
}
429
 
430
/* ('e' for error.) Format info message and print on stderr.  */
431
 
432
void
433
einfo (const char *fmt, ...)
434
{
435
  va_list arg;
436
 
437
  va_start (arg, fmt);
438
  vfinfo (stderr, fmt, arg, TRUE);
439
  va_end (arg);
440
}
441
 
442
void
443
info_assert (const char *file, unsigned int line)
444
{
445
  einfo (_("%F%P: internal error %s %d\n"), file, line);
446
}
447
 
448
/* ('m' for map) Format info message and print on map.  */
449
 
450
void
451
minfo (const char *fmt, ...)
452
{
453
  if (config.map_file != NULL)
454
    {
455
      va_list arg;
456
 
457
      va_start (arg, fmt);
458
      vfinfo (config.map_file, fmt, arg, FALSE);
459
      va_end (arg);
460
    }
461
}
462
 
463
void
464
lfinfo (FILE *file, const char *fmt, ...)
465
{
466
  va_list arg;
467
 
468
  va_start (arg, fmt);
469
  vfinfo (file, fmt, arg, FALSE);
470
  va_end (arg);
471
}
472
 
473
/* Functions to print the link map.  */
474
 
475
void
476
print_space (void)
477
{
478
  fprintf (config.map_file, " ");
479
}
480
 
481
void
482
print_nl (void)
483
{
484
  fprintf (config.map_file, "\n");
485
}
486
 
487
/* A more or less friendly abort message.  In ld.h abort is defined to
488
   call this function.  */
489
 
490
void
491
ld_abort (const char *file, int line, const char *fn)
492
{
493
  if (fn != NULL)
494
    einfo (_("%P: internal error: aborting at %s line %d in %s\n"),
495
           file, line, fn);
496
  else
497
    einfo (_("%P: internal error: aborting at %s line %d\n"),
498
           file, line);
499
  einfo (_("%P%F: please report this bug\n"));
500
  xexit (1);
501
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.