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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [ld/] [ldmisc.c] - Blame information for rev 146

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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