1 /* 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.
6 This file is part of GNU Binutils.
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.
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.
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
23 /* We might put this in a library someday so it could be dynamically
24 loaded, but for now it's not necessary. */
28 #include "libiberty.h"
29 #include "filenames.h"
33 #include <time.h> /* ctime, maybe time_t */
37 #ifndef HAVE_TIME_T_IN_TIME_H
38 #ifndef HAVE_TIME_T_IN_TYPES_H
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);
48 /* Error reporting. */
53 bfd_nonfatal (const char *string
)
55 const char *errmsg
= bfd_errmsg (bfd_get_error ());
58 fprintf (stderr
, "%s: %s: %s\n", program_name
, string
, errmsg
);
60 fprintf (stderr
, "%s: %s\n", program_name
, errmsg
);
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:
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
77 bfd_nonfatal_message (const char *filename
,
78 const bfd
*bfd
, const asection
*section
,
79 const char *format
, ...)
81 const char *errmsg
= bfd_errmsg (bfd_get_error ());
82 const char *section_name
= NULL
;
85 va_start (args
, format
);
86 fprintf (stderr
, "%s", program_name
);
91 filename
= bfd_get_archive_filename (bfd
);
93 section_name
= bfd_get_section_name (bfd
, section
);
96 fprintf (stderr
, ":%s[%s]", filename
, section_name
);
98 fprintf (stderr
, ":%s", filename
);
102 fprintf (stderr
, ": ");
103 vfprintf (stderr
, format
, args
);
105 fprintf (stderr
, ": %s\n", errmsg
);
110 bfd_fatal (const char *string
)
112 bfd_nonfatal (string
);
117 report (const char * format
, va_list args
)
119 fprintf (stderr
, "%s: ", program_name
);
120 vfprintf (stderr
, format
, args
);
125 fatal
VPARAMS ((const char *format
, ...))
127 VA_OPEN (args
, format
);
128 VA_FIXEDARG (args
, const char *, format
);
130 report (format
, args
);
136 non_fatal
VPARAMS ((const char *format
, ...))
138 VA_OPEN (args
, format
);
139 VA_FIXEDARG (args
, const char *, format
);
141 report (format
, args
);
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
151 set_default_bfd_target (void)
153 /* The macro TARGET is defined by Makefile. */
154 const char *target
= TARGET
;
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 ()));
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. */
166 list_matching_formats (char **p
)
168 fprintf (stderr
, _("%s: Matching formats:"), program_name
);
170 fprintf (stderr
, " %s", *p
++);
171 fputc ('\n', stderr
);
174 /* List the supported targets. */
177 list_supported_targets (const char *name
, FILE *f
)
180 const char **targ_names
= bfd_target_list ();
183 fprintf (f
, _("Supported targets:"));
185 fprintf (f
, _("%s: supported targets:"), name
);
187 for (t
= 0; targ_names
[t
] != NULL
; t
++)
188 fprintf (f
, " %s", targ_names
[t
]);
193 /* List the supported architectures. */
196 list_supported_architectures (const char *name
, FILE *f
)
199 const char ** arches
;
202 fprintf (f
, _("Supported architectures:"));
204 fprintf (f
, _("%s: supported architectures:"), name
);
206 for (arch
= arches
= bfd_arch_list (); *arch
; arch
++)
207 fprintf (f
, " %s", *arch
);
212 /* The length of the longest architecture name + 1. */
213 #define LONGEST_ARCH sizeof ("powerpc:common")
216 endian_string (enum bfd_endian endian
)
220 case BFD_ENDIAN_BIG
: return "big endian";
221 case BFD_ENDIAN_LITTLE
: return "little endian";
222 default: return "endianness unknown";
226 /* List the targets that BFD is configured to support, each followed
227 by its endianness and the architectures it supports. */
230 display_target_list (void)
236 dummy_name
= make_temp_file (NULL
);
237 for (t
= 0; bfd_target_vector
[t
]; t
++)
239 const bfd_target
*p
= bfd_target_vector
[t
];
240 bfd
*abfd
= bfd_openw (dummy_name
, p
->name
);
241 enum bfd_architecture a
;
243 printf ("%s\n (header %s, data %s)\n", p
->name
,
244 endian_string (p
->header_byteorder
),
245 endian_string (p
->byteorder
));
249 bfd_nonfatal (dummy_name
);
254 if (! bfd_set_format (abfd
, bfd_object
))
256 if (bfd_get_error () != bfd_error_invalid_operation
)
258 bfd_nonfatal (p
->name
);
261 bfd_close_all_done (abfd
);
265 for (a
= bfd_arch_obscure
+ 1; a
< bfd_arch_last
; a
++)
266 if (bfd_set_arch_mach (abfd
, (enum bfd_architecture
) a
, 0))
268 bfd_printable_arch_mach ((enum bfd_architecture
) a
, 0));
269 bfd_close_all_done (abfd
);
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). */
282 display_info_table (int first
, int last
)
287 enum bfd_architecture a
;
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
);
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)
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
++)
303 const bfd_target
*p
= bfd_target_vector
[t
];
304 bfd_boolean ok
= TRUE
;
305 bfd
*abfd
= bfd_openw (dummy_name
, p
->name
);
309 bfd_nonfatal (p
->name
);
316 if (! bfd_set_format (abfd
, bfd_object
))
318 if (bfd_get_error () != bfd_error_invalid_operation
)
320 bfd_nonfatal (p
->name
);
329 if (! bfd_set_arch_mach (abfd
, a
, 0))
334 printf ("%s ", p
->name
);
337 int l
= strlen (p
->name
);
343 bfd_close_all_done (abfd
);
353 /* Print tables of all the target-architecture combinations that
354 BFD has been configured to support. */
357 display_target_tables (void)
365 colum
= getenv ("COLUMNS");
367 columns
= atoi (colum
);
372 while (bfd_target_vector
[t
] != NULL
)
376 wid
= LONGEST_ARCH
+ strlen (bfd_target_vector
[t
]->name
) + 1;
378 while (wid
< columns
&& bfd_target_vector
[t
] != NULL
)
382 newwid
= wid
+ strlen (bfd_target_vector
[t
]->name
) + 1;
383 if (newwid
>= columns
)
388 if (! display_info_table (oldt
, t
))
398 printf (_("BFD header file version %s\n"), BFD_VERSION_STRING
);
399 if (! display_target_list () || ! display_target_tables ())
405 /* Display the archive header for an element as if it were an ls -l listing:
407 Mode User\tGroup\tSize\tDate Name */
410 print_arelt_descr (FILE *file
, bfd
*abfd
, bfd_boolean verbose
)
416 if (bfd_stat_arch_elt (abfd
, &buf
) == 0)
420 time_t when
= buf
.st_mtime
;
421 const char *ctime_result
= (const char *) ctime (&when
);
423 /* POSIX format: skip weekday and seconds from ctime output. */
424 sprintf (timebuf
, "%.12s %.4s", ctime_result
+ 4, ctime_result
+ 20);
426 mode_string (buf
.st_mode
, modebuf
);
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
);
435 fprintf (file
, "%s\n", bfd_get_filename (abfd
));
438 /* Return a path for a new temporary file in the same directory
442 template_in_dir (const char *path
)
444 #define template "stXXXXXX"
445 const char *slash
= strrchr (path
, '/');
449 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
451 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
452 char *bslash
= strrchr (path
, '\\');
454 if (slash
== NULL
|| (bslash
!= NULL
&& bslash
> slash
))
456 if (slash
== NULL
&& path
[0] != '\0' && path
[1] == ':')
461 if (slash
!= (char *) NULL
)
464 tmpname
= xmalloc (len
+ sizeof (template) + 2);
465 memcpy (tmpname
, path
, len
);
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
++] = '.';
474 tmpname
[len
++] = '/';
478 tmpname
= xmalloc (sizeof (template));
482 memcpy (tmpname
+ len
, template, sizeof (template));
487 /* Return the name of a created temporary file in the same directory
491 make_tempname (char *filename
)
493 char *tmpname
= template_in_dir (filename
);
497 fd
= mkstemp (tmpname
);
499 tmpname
= mktemp (tmpname
);
502 fd
= open (tmpname
, O_RDWR
| O_CREAT
| O_EXCL
, 0600);
510 /* Return the name of a created temporary directory inside the
511 directory containing FILENAME. */
514 make_tempdir (char *filename
)
516 char *tmpname
= template_in_dir (filename
);
519 return mkdtemp (tmpname
);
521 tmpname
= mktemp (tmpname
);
524 #if defined (_WIN32) && !defined (__CYGWIN32__)
525 if (mkdir (tmpname
) != 0)
528 if (mkdir (tmpname
, 0700) != 0)
535 /* Parse a string into a VMA, with a fatal error if it can't be
539 parse_vma (const char *s
, const char *arg
)
544 ret
= bfd_scan_vma (s
, &end
, 0);
547 fatal (_("%s: bad number: %s"), arg
, s
);
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. */
557 get_file_size (const char * file_name
)
561 if (stat (file_name
, &statbuf
) < 0)
564 non_fatal (_("'%s': No such file"), file_name
);
566 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
567 file_name
, strerror (errno
));
569 else if (! S_ISREG (statbuf
.st_mode
))
570 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name
);
572 return statbuf
.st_size
;
577 /* Return the filename in a static buffer. */
580 bfd_get_archive_filename (const bfd
*abfd
)
582 static size_t curr
= 0;
586 assert (abfd
!= NULL
);
588 if (!abfd
->my_archive
)
589 return bfd_get_filename (abfd
);
591 needed
= (strlen (bfd_get_filename (abfd
->my_archive
))
592 + strlen (bfd_get_filename (abfd
)) + 3);
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. */
604 return bfd_get_filename (abfd
);
607 sprintf (buf
, "%s(%s)", bfd_get_filename (abfd
->my_archive
),
608 bfd_get_filename (abfd
));