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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [binutils/] [bucomm.c] - Blame information for rev 859

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

Line No. Rev Author Line
1 205 julius
/* bucomm.c -- Bin Utils COMmon code.
2
   Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
3
   2003, 2005, 2006, 2007, 2008, 2009
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GNU Binutils.
7
 
8
   This program 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 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program 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 this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
22
 
23
/* We might put this in a library someday so it could be dynamically
24
   loaded, but for now it's not necessary.  */
25
 
26
#include "sysdep.h"
27
#include "bfd.h"
28
#include "libiberty.h"
29
#include "filenames.h"
30
#include "libbfd.h"
31
 
32
#include <sys/stat.h>
33
#include <time.h>               /* ctime, maybe time_t */
34
#include <assert.h>
35
#include "bucomm.h"
36
 
37
#ifndef HAVE_TIME_T_IN_TIME_H
38
#ifndef HAVE_TIME_T_IN_TYPES_H
39
typedef long time_t;
40
#endif
41
#endif
42
 
43
static const char * endian_string (enum bfd_endian);
44
static int display_target_list (void);
45
static int display_info_table (int, int);
46
static int display_target_tables (void);
47
 
48
/* Error reporting.  */
49
 
50
char *program_name;
51
 
52
void
53
bfd_nonfatal (const char *string)
54
{
55
  const char *errmsg = bfd_errmsg (bfd_get_error ());
56
 
57
  if (string)
58
    fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
59
  else
60
    fprintf (stderr, "%s: %s\n", program_name, errmsg);
61
}
62
 
63
/* Issue a non fatal error message.  FILENAME, or if NULL then BFD,
64
   are used to indicate the problematic file.  SECTION, if non NULL,
65
   is used to provide a section name.  If FORMAT is non-null, then it
66
   is used to print additional information via vfprintf.  Finally the
67
   bfd error message is printed.  In summary, error messages are of
68
   one of the following forms:
69
 
70
   PROGRAM:file: bfd-error-message
71
   PROGRAM:file[section]: bfd-error-message
72
   PROGRAM:file: printf-message: bfd-error-message
73
   PROGRAM:file[section]: printf-message: bfd-error-message
74
*/
75
 
76
void
77
bfd_nonfatal_message (const char *filename,
78
                      const bfd *bfd, const asection *section,
79
                      const char *format, ...)
80
{
81
  const char *errmsg = bfd_errmsg (bfd_get_error ());
82
  const char *section_name = NULL;
83
  va_list args;
84
 
85
  va_start (args, format);
86
  fprintf (stderr, "%s", program_name);
87
 
88
  if (bfd)
89
    {
90
      if (!filename)
91
        filename = bfd_get_archive_filename (bfd);
92
      if (section)
93
        section_name = bfd_get_section_name (bfd, section);
94
    }
95
  if (section_name)
96
    fprintf (stderr, ":%s[%s]", filename, section_name);
97
  else
98
    fprintf (stderr, ":%s", filename);
99
 
100
  if (format)
101
    {
102
      fprintf (stderr, ": ");
103
      vfprintf (stderr, format, args);
104
    }
105
  fprintf (stderr, ": %s\n", errmsg);
106
  va_end (args);
107
}
108
 
109
void
110
bfd_fatal (const char *string)
111
{
112
  bfd_nonfatal (string);
113
  xexit (1);
114
}
115
 
116
void
117
report (const char * format, va_list args)
118
{
119
  fprintf (stderr, "%s: ", program_name);
120
  vfprintf (stderr, format, args);
121
  putc ('\n', stderr);
122
}
123
 
124
void
125
fatal VPARAMS ((const char *format, ...))
126
{
127
  VA_OPEN (args, format);
128
  VA_FIXEDARG (args, const char *, format);
129
 
130
  report (format, args);
131
  VA_CLOSE (args);
132
  xexit (1);
133
}
134
 
135
void
136
non_fatal VPARAMS ((const char *format, ...))
137
{
138
  VA_OPEN (args, format);
139
  VA_FIXEDARG (args, const char *, format);
140
 
141
  report (format, args);
142
  VA_CLOSE (args);
143
}
144
 
145
/* Set the default BFD target based on the configured target.  Doing
146
   this permits the binutils to be configured for a particular target,
147
   and linked against a shared BFD library which was configured for a
148
   different target.  */
149
 
150
void
151
set_default_bfd_target (void)
152
{
153
  /* The macro TARGET is defined by Makefile.  */
154
  const char *target = TARGET;
155
 
156
  if (! bfd_set_default_target (target))
157
    fatal (_("can't set BFD default target to `%s': %s"),
158
           target, bfd_errmsg (bfd_get_error ()));
159
}
160
 
161
/* After a FALSE return from bfd_check_format_matches with
162
   bfd_get_error () == bfd_error_file_ambiguously_recognized, print
163
   the possible matching targets.  */
164
 
165
void
166
list_matching_formats (char **p)
167
{
168
  fprintf (stderr, _("%s: Matching formats:"), program_name);
169
  while (*p)
170
    fprintf (stderr, " %s", *p++);
171
  fputc ('\n', stderr);
172
}
173
 
174
/* List the supported targets.  */
175
 
176
void
177
list_supported_targets (const char *name, FILE *f)
178
{
179
  int t;
180
  const char **targ_names = bfd_target_list ();
181
 
182
  if (name == NULL)
183
    fprintf (f, _("Supported targets:"));
184
  else
185
    fprintf (f, _("%s: supported targets:"), name);
186
 
187
  for (t = 0; targ_names[t] != NULL; t++)
188
    fprintf (f, " %s", targ_names[t]);
189
  fprintf (f, "\n");
190
  free (targ_names);
191
}
192
 
193
/* List the supported architectures.  */
194
 
195
void
196
list_supported_architectures (const char *name, FILE *f)
197
{
198
  const char ** arch;
199
  const char ** arches;
200
 
201
  if (name == NULL)
202
    fprintf (f, _("Supported architectures:"));
203
  else
204
    fprintf (f, _("%s: supported architectures:"), name);
205
 
206
  for (arch = arches = bfd_arch_list (); *arch; arch++)
207
    fprintf (f, " %s", *arch);
208
  fprintf (f, "\n");
209
  free (arches);
210
}
211
 
212
/* The length of the longest architecture name + 1.  */
213
#define LONGEST_ARCH sizeof ("powerpc:common")
214
 
215
static const char *
216
endian_string (enum bfd_endian endian)
217
{
218
  switch (endian)
219
    {
220
    case BFD_ENDIAN_BIG: return "big endian";
221
    case BFD_ENDIAN_LITTLE: return "little endian";
222
    default: return "endianness unknown";
223
    }
224
}
225
 
226
/* List the targets that BFD is configured to support, each followed
227
   by its endianness and the architectures it supports.  */
228
 
229
static int
230
display_target_list (void)
231
{
232
  char *dummy_name;
233
  int t;
234
  int ret = 1;
235
 
236
  dummy_name = make_temp_file (NULL);
237
  for (t = 0; bfd_target_vector[t]; t++)
238
    {
239
      const bfd_target *p = bfd_target_vector[t];
240
      bfd *abfd = bfd_openw (dummy_name, p->name);
241
      int a;
242
 
243
      printf ("%s\n (header %s, data %s)\n", p->name,
244
              endian_string (p->header_byteorder),
245
              endian_string (p->byteorder));
246
 
247
      if (abfd == NULL)
248
        {
249
          bfd_nonfatal (dummy_name);
250
          ret = 0;
251
          continue;
252
        }
253
 
254
      if (! bfd_set_format (abfd, bfd_object))
255
        {
256
          if (bfd_get_error () != bfd_error_invalid_operation)
257
            {
258
              bfd_nonfatal (p->name);
259
              ret = 0;
260
            }
261
          bfd_close_all_done (abfd);
262
          continue;
263
        }
264
 
265
      for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
266
        if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
267
          printf ("  %s\n",
268
                  bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
269
      bfd_close_all_done (abfd);
270
    }
271
  unlink (dummy_name);
272
  free (dummy_name);
273
 
274
  return ret;
275
}
276
 
277
/* Print a table showing which architectures are supported for entries
278
   FIRST through LAST-1 of bfd_target_vector (targets across,
279
   architectures down).  */
280
 
281
static int
282
display_info_table (int first, int last)
283
{
284
  int t;
285
  int ret = 1;
286
  char *dummy_name;
287
  int a;
288
 
289
  /* Print heading of target names.  */
290
  printf ("\n%*s", (int) LONGEST_ARCH, " ");
291
  for (t = first; t < last && bfd_target_vector[t]; t++)
292
    printf ("%s ", bfd_target_vector[t]->name);
293
  putchar ('\n');
294
 
295
  dummy_name = make_temp_file (NULL);
296
  for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
297
    if (strcmp (bfd_printable_arch_mach ((enum bfd_architecture) a, 0),
298
                "UNKNOWN!") != 0)
299
      {
300
        printf ("%*s ", (int) LONGEST_ARCH - 1,
301
                bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
302
        for (t = first; t < last && bfd_target_vector[t]; t++)
303
          {
304
            const bfd_target *p = bfd_target_vector[t];
305
            bfd_boolean ok = TRUE;
306
            bfd *abfd = bfd_openw (dummy_name, p->name);
307
 
308
            if (abfd == NULL)
309
              {
310
                bfd_nonfatal (p->name);
311
                ret = 0;
312
                ok = FALSE;
313
              }
314
 
315
            if (ok)
316
              {
317
                if (! bfd_set_format (abfd, bfd_object))
318
                  {
319
                    if (bfd_get_error () != bfd_error_invalid_operation)
320
                      {
321
                        bfd_nonfatal (p->name);
322
                        ret = 0;
323
                      }
324
                    ok = FALSE;
325
                  }
326
              }
327
 
328
            if (ok)
329
              {
330
                if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
331
                  ok = FALSE;
332
              }
333
 
334
            if (ok)
335
              printf ("%s ", p->name);
336
            else
337
              {
338
                int l = strlen (p->name);
339
                while (l--)
340
                  putchar ('-');
341
                putchar (' ');
342
              }
343
            if (abfd != NULL)
344
              bfd_close_all_done (abfd);
345
          }
346
        putchar ('\n');
347
      }
348
  unlink (dummy_name);
349
  free (dummy_name);
350
 
351
  return ret;
352
}
353
 
354
/* Print tables of all the target-architecture combinations that
355
   BFD has been configured to support.  */
356
 
357
static int
358
display_target_tables (void)
359
{
360
  int t;
361
  int columns;
362
  int ret = 1;
363
  char *colum;
364
 
365
  columns = 0;
366
  colum = getenv ("COLUMNS");
367
  if (colum != NULL)
368
    columns = atoi (colum);
369
  if (columns == 0)
370
    columns = 80;
371
 
372
  t = 0;
373
  while (bfd_target_vector[t] != NULL)
374
    {
375
      int oldt = t, wid;
376
 
377
      wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
378
      ++t;
379
      while (wid < columns && bfd_target_vector[t] != NULL)
380
        {
381
          int newwid;
382
 
383
          newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
384
          if (newwid >= columns)
385
            break;
386
          wid = newwid;
387
          ++t;
388
        }
389
      if (! display_info_table (oldt, t))
390
        ret = 0;
391
    }
392
 
393
  return ret;
394
}
395
 
396
int
397
display_info (void)
398
{
399
  printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
400
  if (! display_target_list () || ! display_target_tables ())
401
    return 1;
402
  else
403
    return 0;
404
}
405
 
406
/* Display the archive header for an element as if it were an ls -l listing:
407
 
408
   Mode       User\tGroup\tSize\tDate               Name */
409
 
410
void
411
print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
412
{
413
  struct stat buf;
414
 
415
  if (verbose)
416
    {
417
      if (bfd_stat_arch_elt (abfd, &buf) == 0)
418
        {
419
          char modebuf[11];
420
          char timebuf[40];
421
          time_t when = buf.st_mtime;
422
          const char *ctime_result = (const char *) ctime (&when);
423
 
424
          /* POSIX format:  skip weekday and seconds from ctime output.  */
425
          sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
426
 
427
          mode_string (buf.st_mode, modebuf);
428
          modebuf[10] = '\0';
429
          /* POSIX 1003.2/D11 says to skip first character (entry type).  */
430
          fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
431
                   (long) buf.st_uid, (long) buf.st_gid,
432
                   (long) buf.st_size, timebuf);
433
        }
434
    }
435
 
436
  fprintf (file, "%s\n", bfd_get_filename (abfd));
437
}
438
 
439
/* Return a path for a new temporary file in the same directory
440
   as file PATH.  */
441
 
442
static char *
443
template_in_dir (const char *path)
444
{
445
#define template "stXXXXXX"
446
  const char *slash = strrchr (path, '/');
447
  char *tmpname;
448
  size_t len;
449
 
450
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
451
  {
452
    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
453
    char *bslash = strrchr (path, '\\');
454
 
455
    if (slash == NULL || (bslash != NULL && bslash > slash))
456
      slash = bslash;
457
    if (slash == NULL && path[0] != '\0' && path[1] == ':')
458
      slash = path + 1;
459
  }
460
#endif
461
 
462
  if (slash != (char *) NULL)
463
    {
464
      len = slash - path;
465
      tmpname = (char *) xmalloc (len + sizeof (template) + 2);
466
      memcpy (tmpname, path, len);
467
 
468
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
469
      /* If tmpname is "X:", appending a slash will make it a root
470
         directory on drive X, which is NOT the same as the current
471
         directory on drive X.  */
472
      if (len == 2 && tmpname[1] == ':')
473
        tmpname[len++] = '.';
474
#endif
475
      tmpname[len++] = '/';
476
    }
477
  else
478
    {
479
      tmpname = (char *) xmalloc (sizeof (template));
480
      len = 0;
481
    }
482
 
483
  memcpy (tmpname + len, template, sizeof (template));
484
  return tmpname;
485
#undef template
486
}
487
 
488
/* Return the name of a created temporary file in the same directory
489
   as FILENAME.  */
490
 
491
char *
492
make_tempname (char *filename)
493
{
494
  char *tmpname = template_in_dir (filename);
495
  int fd;
496
 
497
#ifdef HAVE_MKSTEMP
498
  fd = mkstemp (tmpname);
499
#else
500
  tmpname = mktemp (tmpname);
501
  if (tmpname == NULL)
502
    return NULL;
503
  fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
504
#endif
505
  if (fd == -1)
506
    return NULL;
507
  close (fd);
508
  return tmpname;
509
}
510
 
511
/* Return the name of a created temporary directory inside the
512
   directory containing FILENAME.  */
513
 
514
char *
515
make_tempdir (char *filename)
516
{
517
  char *tmpname = template_in_dir (filename);
518
 
519
#ifdef HAVE_MKDTEMP
520
  return mkdtemp (tmpname);
521
#else
522
  tmpname = mktemp (tmpname);
523
  if (tmpname == NULL)
524
    return NULL;
525
#if defined (_WIN32) && !defined (__CYGWIN32__)
526
  if (mkdir (tmpname) != 0)
527
    return NULL;
528
#else
529
  if (mkdir (tmpname, 0700) != 0)
530
    return NULL;
531
#endif
532
  return tmpname;
533
#endif
534
}
535
 
536
/* Parse a string into a VMA, with a fatal error if it can't be
537
   parsed.  */
538
 
539
bfd_vma
540
parse_vma (const char *s, const char *arg)
541
{
542
  bfd_vma ret;
543
  const char *end;
544
 
545
  ret = bfd_scan_vma (s, &end, 0);
546
 
547
  if (*end != '\0')
548
    fatal (_("%s: bad number: %s"), arg, s);
549
 
550
  return ret;
551
}
552
 
553
/* Returns the size of the named file.  If the file does not
554
   exist, or if it is not a real file, then a suitable non-fatal
555
   error message is printed and zero is returned.  */
556
 
557
off_t
558
get_file_size (const char * file_name)
559
{
560
  struct stat statbuf;
561
 
562
  if (stat (file_name, &statbuf) < 0)
563
    {
564
      if (errno == ENOENT)
565
        non_fatal (_("'%s': No such file"), file_name);
566
      else
567
        non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
568
                   file_name, strerror (errno));
569
    }
570
  else if (! S_ISREG (statbuf.st_mode))
571
    non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
572
  else
573
    return statbuf.st_size;
574
 
575
  return (off_t) -1;
576
}
577
 
578
/* Return the filename in a static buffer.  */
579
 
580
const char *
581
bfd_get_archive_filename (const bfd *abfd)
582
{
583
  static size_t curr = 0;
584
  static char *buf;
585
  size_t needed;
586
 
587
  assert (abfd != NULL);
588
 
589
  if (!abfd->my_archive)
590
    return bfd_get_filename (abfd);
591
 
592
  needed = (strlen (bfd_get_filename (abfd->my_archive))
593
            + strlen (bfd_get_filename (abfd)) + 3);
594
  if (needed > curr)
595
    {
596
      if (curr)
597
        free (buf);
598
      curr = needed + (needed >> 1);
599
      buf = (char *) bfd_malloc (curr);
600
      /* If we can't malloc, fail safe by returning just the file name.
601
         This function is only used when building error messages.  */
602
      if (!buf)
603
        {
604
          curr = 0;
605
          return bfd_get_filename (abfd);
606
        }
607
    }
608
  sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
609
           bfd_get_filename (abfd));
610
  return buf;
611
}

powered by: WebSVN 2.1.0

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