Fix a typo in comments.
[deliverable/binutils-gdb.git] / binutils / bucomm.c
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, 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 \f
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 \f
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 \f
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 \f
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 }
This page took 0.042979 seconds and 4 git commands to generate.