file arclinux_prof.sh was initially added on branch binutils-arc-20081103-branch.
[binutils.git] / binutils / bucomm.c
blobe006e615bbcd76521f32808cd1066bd799fc192d
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
21 02110-1301, USA. */
23 /* We might put this in a library someday so it could be dynamically
24 loaded, but for now it's not necessary. */
26 #include "sysdep.h"
27 #include "bfd.h"
28 #include "libiberty.h"
29 #include "filenames.h"
30 #include "libbfd.h"
32 #include <sys/stat.h>
33 #include <time.h> /* ctime, maybe time_t */
34 #include <assert.h>
35 #include "bucomm.h"
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
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. */
50 char *program_name;
52 void
53 bfd_nonfatal (const char *string)
55 const char *errmsg = bfd_errmsg (bfd_get_error ());
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);
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
76 void
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;
83 va_list args;
85 va_start (args, format);
86 fprintf (stderr, "%s", program_name);
88 if (bfd)
90 if (!filename)
91 filename = bfd_get_archive_filename (bfd);
92 if (section)
93 section_name = bfd_get_section_name (bfd, section);
95 if (section_name)
96 fprintf (stderr, ":%s[%s]", filename, section_name);
97 else
98 fprintf (stderr, ":%s", filename);
100 if (format)
102 fprintf (stderr, ": ");
103 vfprintf (stderr, format, args);
105 fprintf (stderr, ": %s\n", errmsg);
106 va_end (args);
109 void
110 bfd_fatal (const char *string)
112 bfd_nonfatal (string);
113 xexit (1);
116 void
117 report (const char * format, va_list args)
119 fprintf (stderr, "%s: ", program_name);
120 vfprintf (stderr, format, args);
121 putc ('\n', stderr);
124 void
125 fatal VPARAMS ((const char *format, ...))
127 VA_OPEN (args, format);
128 VA_FIXEDARG (args, const char *, format);
130 report (format, args);
131 VA_CLOSE (args);
132 xexit (1);
135 void
136 non_fatal VPARAMS ((const char *format, ...))
138 VA_OPEN (args, format);
139 VA_FIXEDARG (args, const char *, format);
141 report (format, args);
142 VA_CLOSE (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
148 different target. */
150 void
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. */
165 void
166 list_matching_formats (char **p)
168 fprintf (stderr, _("%s: Matching formats:"), program_name);
169 while (*p)
170 fprintf (stderr, " %s", *p++);
171 fputc ('\n', stderr);
174 /* List the supported targets. */
176 void
177 list_supported_targets (const char *name, FILE *f)
179 int t;
180 const char **targ_names = bfd_target_list ();
182 if (name == NULL)
183 fprintf (f, _("Supported targets:"));
184 else
185 fprintf (f, _("%s: supported targets:"), name);
187 for (t = 0; targ_names[t] != NULL; t++)
188 fprintf (f, " %s", targ_names[t]);
189 fprintf (f, "\n");
190 free (targ_names);
193 /* List the supported architectures. */
195 void
196 list_supported_architectures (const char *name, FILE *f)
198 const char ** arch;
199 const char ** arches;
201 if (name == NULL)
202 fprintf (f, _("Supported architectures:"));
203 else
204 fprintf (f, _("%s: supported architectures:"), name);
206 for (arch = arches = bfd_arch_list (); *arch; arch++)
207 fprintf (f, " %s", *arch);
208 fprintf (f, "\n");
209 free (arches);
212 /* The length of the longest architecture name + 1. */
213 #define LONGEST_ARCH sizeof ("powerpc:common")
215 static const char *
216 endian_string (enum bfd_endian endian)
218 switch (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. */
229 static int
230 display_target_list (void)
232 char *dummy_name;
233 int t;
234 int ret = 1;
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 int a;
243 printf ("%s\n (header %s, data %s)\n", p->name,
244 endian_string (p->header_byteorder),
245 endian_string (p->byteorder));
247 if (abfd == NULL)
249 bfd_nonfatal (dummy_name);
250 ret = 0;
251 continue;
254 if (! bfd_set_format (abfd, bfd_object))
256 if (bfd_get_error () != bfd_error_invalid_operation)
258 bfd_nonfatal (p->name);
259 ret = 0;
261 bfd_close_all_done (abfd);
262 continue;
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);
271 unlink (dummy_name);
272 free (dummy_name);
274 return ret;
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). */
281 static int
282 display_info_table (int first, int last)
284 int t;
285 int ret = 1;
286 char *dummy_name;
287 int 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);
293 putchar ('\n');
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)
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++)
304 const bfd_target *p = bfd_target_vector[t];
305 bfd_boolean ok = TRUE;
306 bfd *abfd = bfd_openw (dummy_name, p->name);
308 if (abfd == NULL)
310 bfd_nonfatal (p->name);
311 ret = 0;
312 ok = FALSE;
315 if (ok)
317 if (! bfd_set_format (abfd, bfd_object))
319 if (bfd_get_error () != bfd_error_invalid_operation)
321 bfd_nonfatal (p->name);
322 ret = 0;
324 ok = FALSE;
328 if (ok)
330 if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
331 ok = FALSE;
334 if (ok)
335 printf ("%s ", p->name);
336 else
338 int l = strlen (p->name);
339 while (l--)
340 putchar ('-');
341 putchar (' ');
343 if (abfd != NULL)
344 bfd_close_all_done (abfd);
346 putchar ('\n');
348 unlink (dummy_name);
349 free (dummy_name);
351 return ret;
354 /* Print tables of all the target-architecture combinations that
355 BFD has been configured to support. */
357 static int
358 display_target_tables (void)
360 int t;
361 int columns;
362 int ret = 1;
363 char *colum;
365 columns = 0;
366 colum = getenv ("COLUMNS");
367 if (colum != NULL)
368 columns = atoi (colum);
369 if (columns == 0)
370 columns = 80;
372 t = 0;
373 while (bfd_target_vector[t] != NULL)
375 int oldt = t, wid;
377 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
378 ++t;
379 while (wid < columns && bfd_target_vector[t] != NULL)
381 int newwid;
383 newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
384 if (newwid >= columns)
385 break;
386 wid = newwid;
387 ++t;
389 if (! display_info_table (oldt, t))
390 ret = 0;
393 return ret;
397 display_info (void)
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;
406 /* Display the archive header for an element as if it were an ls -l listing:
408 Mode User\tGroup\tSize\tDate Name */
410 void
411 print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
413 struct stat buf;
415 if (verbose)
417 if (bfd_stat_arch_elt (abfd, &buf) == 0)
419 char modebuf[11];
420 char timebuf[40];
421 time_t when = buf.st_mtime;
422 const char *ctime_result = (const char *) ctime (&when);
424 /* POSIX format: skip weekday and seconds from ctime output. */
425 sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
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);
436 fprintf (file, "%s\n", bfd_get_filename (abfd));
439 /* Return a path for a new temporary file in the same directory
440 as file PATH. */
442 static char *
443 template_in_dir (const char *path)
445 #define template "stXXXXXX"
446 const char *slash = strrchr (path, '/');
447 char *tmpname;
448 size_t len;
450 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
452 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
453 char *bslash = strrchr (path, '\\');
455 if (slash == NULL || (bslash != NULL && bslash > slash))
456 slash = bslash;
457 if (slash == NULL && path[0] != '\0' && path[1] == ':')
458 slash = path + 1;
460 #endif
462 if (slash != (char *) NULL)
464 len = slash - path;
465 tmpname = (char *) xmalloc (len + sizeof (template) + 2);
466 memcpy (tmpname, path, len);
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++] = '/';
477 else
479 tmpname = (char *) xmalloc (sizeof (template));
480 len = 0;
483 memcpy (tmpname + len, template, sizeof (template));
484 return tmpname;
485 #undef template
488 /* Return the name of a created temporary file in the same directory
489 as FILENAME. */
491 char *
492 make_tempname (char *filename)
494 char *tmpname = template_in_dir (filename);
495 int fd;
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;
511 /* Return the name of a created temporary directory inside the
512 directory containing FILENAME. */
514 char *
515 make_tempdir (char *filename)
517 char *tmpname = template_in_dir (filename);
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
536 /* Parse a string into a VMA, with a fatal error if it can't be
537 parsed. */
539 bfd_vma
540 parse_vma (const char *s, const char *arg)
542 bfd_vma ret;
543 const char *end;
545 ret = bfd_scan_vma (s, &end, 0);
547 if (*end != '\0')
548 fatal (_("%s: bad number: %s"), arg, s);
550 return ret;
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. */
557 off_t
558 get_file_size (const char * file_name)
560 struct stat statbuf;
562 if (stat (file_name, &statbuf) < 0)
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));
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;
575 return (off_t) -1;
578 /* Return the filename in a static buffer. */
580 const char *
581 bfd_get_archive_filename (const bfd *abfd)
583 static size_t curr = 0;
584 static char *buf;
585 size_t needed;
587 assert (abfd != NULL);
589 if (!abfd->my_archive)
590 return bfd_get_filename (abfd);
592 needed = (strlen (bfd_get_filename (abfd->my_archive))
593 + strlen (bfd_get_filename (abfd)) + 3);
594 if (needed > curr)
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)
604 curr = 0;
605 return bfd_get_filename (abfd);
608 sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
609 bfd_get_filename (abfd));
610 return buf;