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 231

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

powered by: WebSVN 2.1.0

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