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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [binutils/] [bucomm.c] - Blame information for rev 816

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* bucomm.c -- Bin Utils COMmon code.
2
   Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
3
   2003, 2006, 2007
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_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
      enum bfd_architecture 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
  enum bfd_architecture 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 (a, 0), "UNKNOWN!") != 0)
298
      {
299
        printf ("%*s ", (int) LONGEST_ARCH - 1,
300
                bfd_printable_arch_mach (a, 0));
301
        for (t = first; t < last && bfd_target_vector[t]; t++)
302
          {
303
            const bfd_target *p = bfd_target_vector[t];
304
            bfd_boolean ok = TRUE;
305
            bfd *abfd = bfd_openw (dummy_name, p->name);
306
 
307
            if (abfd == NULL)
308
              {
309
                bfd_nonfatal (p->name);
310
                ret = 0;
311
                ok = FALSE;
312
              }
313
 
314
            if (ok)
315
              {
316
                if (! bfd_set_format (abfd, bfd_object))
317
                  {
318
                    if (bfd_get_error () != bfd_error_invalid_operation)
319
                      {
320
                        bfd_nonfatal (p->name);
321
                        ret = 0;
322
                      }
323
                    ok = FALSE;
324
                  }
325
              }
326
 
327
            if (ok)
328
              {
329
                if (! bfd_set_arch_mach (abfd, a, 0))
330
                  ok = FALSE;
331
              }
332
 
333
            if (ok)
334
              printf ("%s ", p->name);
335
            else
336
              {
337
                int l = strlen (p->name);
338
                while (l--)
339
                  putchar ('-');
340
                putchar (' ');
341
              }
342
            if (abfd != NULL)
343
              bfd_close_all_done (abfd);
344
          }
345
        putchar ('\n');
346
      }
347
  unlink (dummy_name);
348
  free (dummy_name);
349
 
350
  return ret;
351
}
352
 
353
/* Print tables of all the target-architecture combinations that
354
   BFD has been configured to support.  */
355
 
356
static int
357
display_target_tables (void)
358
{
359
  int t;
360
  int columns;
361
  int ret = 1;
362
  char *colum;
363
 
364
  columns = 0;
365
  colum = getenv ("COLUMNS");
366
  if (colum != NULL)
367
    columns = atoi (colum);
368
  if (columns == 0)
369
    columns = 80;
370
 
371
  t = 0;
372
  while (bfd_target_vector[t] != NULL)
373
    {
374
      int oldt = t, wid;
375
 
376
      wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
377
      ++t;
378
      while (wid < columns && bfd_target_vector[t] != NULL)
379
        {
380
          int newwid;
381
 
382
          newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
383
          if (newwid >= columns)
384
            break;
385
          wid = newwid;
386
          ++t;
387
        }
388
      if (! display_info_table (oldt, t))
389
        ret = 0;
390
    }
391
 
392
  return ret;
393
}
394
 
395
int
396
display_info (void)
397
{
398
  printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
399
  if (! display_target_list () || ! display_target_tables ())
400
    return 1;
401
  else
402
    return 0;
403
}
404
 
405
/* Display the archive header for an element as if it were an ls -l listing:
406
 
407
   Mode       User\tGroup\tSize\tDate               Name */
408
 
409
void
410
print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
411
{
412
  struct stat buf;
413
 
414
  if (verbose)
415
    {
416
      if (bfd_stat_arch_elt (abfd, &buf) == 0)
417
        {
418
          char modebuf[11];
419
          char timebuf[40];
420
          time_t when = buf.st_mtime;
421
          const char *ctime_result = (const char *) ctime (&when);
422
 
423
          /* POSIX format:  skip weekday and seconds from ctime output.  */
424
          sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
425
 
426
          mode_string (buf.st_mode, modebuf);
427
          modebuf[10] = '\0';
428
          /* POSIX 1003.2/D11 says to skip first character (entry type).  */
429
          fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
430
                   (long) buf.st_uid, (long) buf.st_gid,
431
                   (long) buf.st_size, timebuf);
432
        }
433
    }
434
 
435
  fprintf (file, "%s\n", bfd_get_filename (abfd));
436
}
437
 
438
/* Return a path for a new temporary file in the same directory
439
   as file PATH.  */
440
 
441
static char *
442
template_in_dir (const char *path)
443
{
444
#define template "stXXXXXX"
445
  const char *slash = strrchr (path, '/');
446
  char *tmpname;
447
  size_t len;
448
 
449
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
450
  {
451
    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
452
    char *bslash = strrchr (path, '\\');
453
 
454
    if (slash == NULL || (bslash != NULL && bslash > slash))
455
      slash = bslash;
456
    if (slash == NULL && path[0] != '\0' && path[1] == ':')
457
      slash = path + 1;
458
  }
459
#endif
460
 
461
  if (slash != (char *) NULL)
462
    {
463
      len = slash - path;
464
      tmpname = xmalloc (len + sizeof (template) + 2);
465
      memcpy (tmpname, path, len);
466
 
467
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
468
      /* If tmpname is "X:", appending a slash will make it a root
469
         directory on drive X, which is NOT the same as the current
470
         directory on drive X.  */
471
      if (len == 2 && tmpname[1] == ':')
472
        tmpname[len++] = '.';
473
#endif
474
      tmpname[len++] = '/';
475
    }
476
  else
477
    {
478
      tmpname = xmalloc (sizeof (template));
479
      len = 0;
480
    }
481
 
482
  memcpy (tmpname + len, template, sizeof (template));
483
  return tmpname;
484
#undef template
485
}
486
 
487
/* Return the name of a created temporary file in the same directory
488
   as FILENAME.  */
489
 
490
char *
491
make_tempname (char *filename)
492
{
493
  char *tmpname = template_in_dir (filename);
494
  int fd;
495
 
496
#ifdef HAVE_MKSTEMP
497
  fd = mkstemp (tmpname);
498
#else
499
  tmpname = mktemp (tmpname);
500
  if (tmpname == NULL)
501
    return NULL;
502
  fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
503
#endif
504
  if (fd == -1)
505
    return NULL;
506
  close (fd);
507
  return tmpname;
508
}
509
 
510
/* Return the name of a created temporary directory inside the
511
   directory containing FILENAME.  */
512
 
513
char *
514
make_tempdir (char *filename)
515
{
516
  char *tmpname = template_in_dir (filename);
517
 
518
#ifdef HAVE_MKDTEMP
519
  return mkdtemp (tmpname);
520
#else
521
  tmpname = mktemp (tmpname);
522
  if (tmpname == NULL)
523
    return NULL;
524
#if defined (_WIN32) && !defined (__CYGWIN32__)
525
  if (mkdir (tmpname) != 0)
526
    return NULL;
527
#else
528
  if (mkdir (tmpname, 0700) != 0)
529
    return NULL;
530
#endif
531
  return tmpname;
532
#endif
533
}
534
 
535
/* Parse a string into a VMA, with a fatal error if it can't be
536
   parsed.  */
537
 
538
bfd_vma
539
parse_vma (const char *s, const char *arg)
540
{
541
  bfd_vma ret;
542
  const char *end;
543
 
544
  ret = bfd_scan_vma (s, &end, 0);
545
 
546
  if (*end != '\0')
547
    fatal (_("%s: bad number: %s"), arg, s);
548
 
549
  return ret;
550
}
551
 
552
/* Returns the size of the named file.  If the file does not
553
   exist, or if it is not a real file, then a suitable non-fatal
554
   error message is printed and zero is returned.  */
555
 
556
off_t
557
get_file_size (const char * file_name)
558
{
559
  struct stat statbuf;
560
 
561
  if (stat (file_name, &statbuf) < 0)
562
    {
563
      if (errno == ENOENT)
564
        non_fatal (_("'%s': No such file"), file_name);
565
      else
566
        non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
567
                   file_name, strerror (errno));
568
    }
569
  else if (! S_ISREG (statbuf.st_mode))
570
    non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
571
  else
572
    return statbuf.st_size;
573
 
574
  return 0;
575
}
576
 
577
/* Return the filename in a static buffer.  */
578
 
579
const char *
580
bfd_get_archive_filename (bfd *abfd)
581
{
582
  static size_t curr = 0;
583
  static char *buf;
584
  size_t needed;
585
 
586
  assert (abfd != NULL);
587
 
588
  if (!abfd->my_archive)
589
    return bfd_get_filename (abfd);
590
 
591
  needed = (strlen (bfd_get_filename (abfd->my_archive))
592
            + strlen (bfd_get_filename (abfd)) + 3);
593
  if (needed > curr)
594
    {
595
      if (curr)
596
        free (buf);
597
      curr = needed + (needed >> 1);
598
      buf = bfd_malloc (curr);
599
      /* If we can't malloc, fail safe by returning just the file name.
600
         This function is only used when building error messages.  */
601
      if (!buf)
602
        {
603
          curr = 0;
604
          return bfd_get_filename (abfd);
605
        }
606
    }
607
  sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
608
           bfd_get_filename (abfd));
609
  return buf;
610
}

powered by: WebSVN 2.1.0

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