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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [bucomm.c] - Blame information for rev 36

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

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

powered by: WebSVN 2.1.0

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