* lib/ld-lib.exp (is_elf_format): Merge with binutils and gas versions.
[deliverable/binutils-gdb.git] / binutils / bucomm.c
CommitLineData
252b5132 1/* bucomm.c -- Bin Utils COMmon code.
485be063 2 Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
aa820537 3 2003, 2005, 2006, 2007, 2008, 2009
37cc8ec1 4 Free Software Foundation, Inc.
252b5132
RH
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
32866df7 10 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
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
b43b5d5f
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
252b5132
RH
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
3db64b00 26#include "sysdep.h"
252b5132
RH
27#include "bfd.h"
28#include "libiberty.h"
5af11cab 29#include "filenames.h"
06d86cf7 30#include "libbfd.h"
252b5132
RH
31
32#include <sys/stat.h>
33#include <time.h> /* ctime, maybe time_t */
77f762d6 34#include <assert.h>
3db64b00 35#include "bucomm.h"
252b5132
RH
36
37#ifndef HAVE_TIME_T_IN_TIME_H
38#ifndef HAVE_TIME_T_IN_TYPES_H
39typedef long time_t;
40#endif
41#endif
06d86cf7 42
2da42df6
AJ
43static const char * endian_string (enum bfd_endian);
44static int display_target_list (void);
45static int display_info_table (int, int);
46static int display_target_tables (void);
252b5132 47\f
06d86cf7 48/* Error reporting. */
252b5132
RH
49
50char *program_name;
51
52void
2da42df6 53bfd_nonfatal (const char *string)
252b5132 54{
b1f88ebe 55 const char *errmsg = bfd_errmsg (bfd_get_error ());
252b5132
RH
56
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);
61}
62
2db6cde7
NS
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:
69
70 PROGRAM:file: bfd-error-message
71 PROGRAM:file[section]: bfd-error-message
72 PROGRAM:file: printf-message: bfd-error-message
91d6fa6a 73 PROGRAM:file[section]: printf-message: bfd-error-message. */
2db6cde7
NS
74
75void
76bfd_nonfatal_message (const char *filename,
91d6fa6a
NC
77 const bfd *abfd,
78 const asection *section,
2db6cde7
NS
79 const char *format, ...)
80{
81 const char *errmsg = bfd_errmsg (bfd_get_error ());
82 const char *section_name = NULL;
83 va_list args;
84
85 va_start (args, format);
86 fprintf (stderr, "%s", program_name);
87
91d6fa6a 88 if (abfd)
2db6cde7
NS
89 {
90 if (!filename)
91d6fa6a 91 filename = bfd_get_archive_filename (abfd);
2db6cde7 92 if (section)
91d6fa6a 93 section_name = bfd_get_section_name (abfd, section);
2db6cde7
NS
94 }
95 if (section_name)
96 fprintf (stderr, ":%s[%s]", filename, section_name);
97 else
98 fprintf (stderr, ":%s", filename);
99
100 if (format)
101 {
102 fprintf (stderr, ": ");
103 vfprintf (stderr, format, args);
104 }
105 fprintf (stderr, ": %s\n", errmsg);
106 va_end (args);
107}
108
252b5132 109void
2da42df6 110bfd_fatal (const char *string)
252b5132
RH
111{
112 bfd_nonfatal (string);
113 xexit (1);
114}
115
cba12006 116void
2da42df6 117report (const char * format, va_list args)
252b5132
RH
118{
119 fprintf (stderr, "%s: ", program_name);
120 vfprintf (stderr, format, args);
121 putc ('\n', stderr);
122}
123
252b5132 124void
451dad9c 125fatal VPARAMS ((const char *format, ...))
252b5132 126{
451dad9c
AM
127 VA_OPEN (args, format);
128 VA_FIXEDARG (args, const char *, format);
252b5132 129
252b5132 130 report (format, args);
451dad9c 131 VA_CLOSE (args);
252b5132
RH
132 xexit (1);
133}
134
135void
451dad9c 136non_fatal VPARAMS ((const char *format, ...))
252b5132 137{
451dad9c
AM
138 VA_OPEN (args, format);
139 VA_FIXEDARG (args, const char *, format);
252b5132 140
252b5132 141 report (format, args);
451dad9c 142 VA_CLOSE (args);
252b5132 143}
252b5132
RH
144
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. */
149
150void
2da42df6 151set_default_bfd_target (void)
252b5132
RH
152{
153 /* The macro TARGET is defined by Makefile. */
154 const char *target = TARGET;
155
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 ()));
159}
160
b34976b6 161/* After a FALSE return from bfd_check_format_matches with
252b5132
RH
162 bfd_get_error () == bfd_error_file_ambiguously_recognized, print
163 the possible matching targets. */
164
165void
2da42df6 166list_matching_formats (char **p)
252b5132
RH
167{
168 fprintf (stderr, _("%s: Matching formats:"), program_name);
169 while (*p)
170 fprintf (stderr, " %s", *p++);
171 fputc ('\n', stderr);
172}
173
174/* List the supported targets. */
175
176void
2da42df6 177list_supported_targets (const char *name, FILE *f)
252b5132 178{
252b5132 179 int t;
48417c1a 180 const char **targ_names = bfd_target_list ();
252b5132
RH
181
182 if (name == NULL)
183 fprintf (f, _("Supported targets:"));
184 else
185 fprintf (f, _("%s: supported targets:"), name);
48417c1a
AM
186
187 for (t = 0; targ_names[t] != NULL; t++)
188 fprintf (f, " %s", targ_names[t]);
252b5132 189 fprintf (f, "\n");
48417c1a 190 free (targ_names);
252b5132 191}
2f83960e
AM
192
193/* List the supported architectures. */
194
195void
2da42df6 196list_supported_architectures (const char *name, FILE *f)
2f83960e 197{
d25576aa
NC
198 const char ** arch;
199 const char ** arches;
2f83960e
AM
200
201 if (name == NULL)
202 fprintf (f, _("Supported architectures:"));
203 else
204 fprintf (f, _("%s: supported architectures:"), name);
205
d25576aa 206 for (arch = arches = bfd_arch_list (); *arch; arch++)
2f83960e
AM
207 fprintf (f, " %s", *arch);
208 fprintf (f, "\n");
d25576aa 209 free (arches);
2f83960e 210}
252b5132 211\f
06d86cf7
NC
212/* The length of the longest architecture name + 1. */
213#define LONGEST_ARCH sizeof ("powerpc:common")
214
215static const char *
2da42df6 216endian_string (enum bfd_endian endian)
06d86cf7
NC
217{
218 switch (endian)
219 {
220 case BFD_ENDIAN_BIG: return "big endian";
221 case BFD_ENDIAN_LITTLE: return "little endian";
222 default: return "endianness unknown";
223 }
224}
225
226/* List the targets that BFD is configured to support, each followed
227 by its endianness and the architectures it supports. */
228
229static int
2da42df6 230display_target_list (void)
06d86cf7
NC
231{
232 char *dummy_name;
233 int t;
234 int ret = 1;
235
236 dummy_name = make_temp_file (NULL);
237 for (t = 0; bfd_target_vector[t]; t++)
238 {
239 const bfd_target *p = bfd_target_vector[t];
240 bfd *abfd = bfd_openw (dummy_name, p->name);
3f5e193b 241 int a;
06d86cf7
NC
242
243 printf ("%s\n (header %s, data %s)\n", p->name,
244 endian_string (p->header_byteorder),
245 endian_string (p->byteorder));
246
247 if (abfd == NULL)
248 {
249 bfd_nonfatal (dummy_name);
250 ret = 0;
251 continue;
252 }
253
254 if (! bfd_set_format (abfd, bfd_object))
255 {
256 if (bfd_get_error () != bfd_error_invalid_operation)
257 {
258 bfd_nonfatal (p->name);
259 ret = 0;
260 }
261 bfd_close_all_done (abfd);
262 continue;
263 }
264
91610c0c 265 for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
06d86cf7
NC
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);
270 }
271 unlink (dummy_name);
272 free (dummy_name);
273
274 return ret;
275}
276
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). */
280
281static int
2da42df6 282display_info_table (int first, int last)
06d86cf7
NC
283{
284 int t;
06d86cf7
NC
285 int ret = 1;
286 char *dummy_name;
3f5e193b 287 int a;
06d86cf7
NC
288
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');
294
295 dummy_name = make_temp_file (NULL);
91610c0c 296 for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
3f5e193b
NC
297 if (strcmp (bfd_printable_arch_mach ((enum bfd_architecture) a, 0),
298 "UNKNOWN!") != 0)
06d86cf7
NC
299 {
300 printf ("%*s ", (int) LONGEST_ARCH - 1,
3f5e193b 301 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
06d86cf7
NC
302 for (t = first; t < last && bfd_target_vector[t]; t++)
303 {
304 const bfd_target *p = bfd_target_vector[t];
305 bfd_boolean ok = TRUE;
306 bfd *abfd = bfd_openw (dummy_name, p->name);
307
308 if (abfd == NULL)
309 {
310 bfd_nonfatal (p->name);
311 ret = 0;
312 ok = FALSE;
313 }
314
315 if (ok)
316 {
317 if (! bfd_set_format (abfd, bfd_object))
318 {
319 if (bfd_get_error () != bfd_error_invalid_operation)
320 {
321 bfd_nonfatal (p->name);
322 ret = 0;
323 }
324 ok = FALSE;
325 }
326 }
327
328 if (ok)
329 {
3f5e193b 330 if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
06d86cf7
NC
331 ok = FALSE;
332 }
333
334 if (ok)
335 printf ("%s ", p->name);
336 else
337 {
338 int l = strlen (p->name);
339 while (l--)
340 putchar ('-');
341 putchar (' ');
342 }
343 if (abfd != NULL)
344 bfd_close_all_done (abfd);
345 }
346 putchar ('\n');
347 }
348 unlink (dummy_name);
349 free (dummy_name);
350
351 return ret;
352}
353
354/* Print tables of all the target-architecture combinations that
355 BFD has been configured to support. */
356
357static int
2da42df6 358display_target_tables (void)
06d86cf7
NC
359{
360 int t;
361 int columns;
362 int ret = 1;
363 char *colum;
364
365 columns = 0;
366 colum = getenv ("COLUMNS");
367 if (colum != NULL)
368 columns = atoi (colum);
369 if (columns == 0)
370 columns = 80;
371
372 t = 0;
373 while (bfd_target_vector[t] != NULL)
374 {
375 int oldt = t, wid;
376
377 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
378 ++t;
379 while (wid < columns && bfd_target_vector[t] != NULL)
380 {
381 int newwid;
382
383 newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
384 if (newwid >= columns)
385 break;
386 wid = newwid;
387 ++t;
388 }
389 if (! display_info_table (oldt, t))
390 ret = 0;
391 }
392
393 return ret;
394}
395
396int
2da42df6 397display_info (void)
06d86cf7
NC
398{
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;
404}
405\f
252b5132
RH
406/* Display the archive header for an element as if it were an ls -l listing:
407
408 Mode User\tGroup\tSize\tDate Name */
409
410void
2da42df6 411print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
252b5132
RH
412{
413 struct stat buf;
414
415 if (verbose)
416 {
417 if (bfd_stat_arch_elt (abfd, &buf) == 0)
418 {
419 char modebuf[11];
420 char timebuf[40];
421 time_t when = buf.st_mtime;
b1f88ebe 422 const char *ctime_result = (const char *) ctime (&when);
252b5132
RH
423
424 /* POSIX format: skip weekday and seconds from ctime output. */
425 sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
426
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);
433 }
434 }
435
436 fprintf (file, "%s\n", bfd_get_filename (abfd));
437}
438
485be063
AM
439/* Return a path for a new temporary file in the same directory
440 as file PATH. */
252b5132 441
485be063
AM
442static char *
443template_in_dir (const char *path)
252b5132 444{
485be063 445#define template "stXXXXXX"
2946671e 446 const char *slash = strrchr (path, '/');
252b5132 447 char *tmpname;
485be063 448 size_t len;
252b5132 449
5af11cab
AM
450#ifdef HAVE_DOS_BASED_FILE_SYSTEM
451 {
452 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
485be063 453 char *bslash = strrchr (path, '\\');
f9c026a8 454
2ab47eed 455 if (slash == NULL || (bslash != NULL && bslash > slash))
5af11cab 456 slash = bslash;
485be063 457 if (slash == NULL && path[0] != '\0' && path[1] == ':')
2946671e 458 slash = path + 1;
5af11cab 459 }
252b5132
RH
460#endif
461
462 if (slash != (char *) NULL)
463 {
485be063 464 len = slash - path;
3f5e193b 465 tmpname = (char *) xmalloc (len + sizeof (template) + 2);
485be063 466 memcpy (tmpname, path, len);
252b5132 467
5af11cab
AM
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. */
485be063
AM
472 if (len == 2 && tmpname[1] == ':')
473 tmpname[len++] = '.';
5af11cab 474#endif
485be063 475 tmpname[len++] = '/';
252b5132
RH
476 }
477 else
478 {
3f5e193b 479 tmpname = (char *) xmalloc (sizeof (template));
485be063 480 len = 0;
f9c026a8 481 }
485be063
AM
482
483 memcpy (tmpname + len, template, sizeof (template));
484 return tmpname;
485#undef template
486}
487
488/* Return the name of a created temporary file in the same directory
489 as FILENAME. */
490
491char *
492make_tempname (char *filename)
493{
494 char *tmpname = template_in_dir (filename);
495 int fd;
496
497#ifdef HAVE_MKSTEMP
498 fd = mkstemp (tmpname);
499#else
500 tmpname = mktemp (tmpname);
501 if (tmpname == NULL)
f9c026a8 502 return NULL;
485be063 503 fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
f9c026a8 504#endif
485be063
AM
505 if (fd == -1)
506 return NULL;
507 close (fd);
f9c026a8
NC
508 return tmpname;
509}
510
485be063
AM
511/* Return the name of a created temporary directory inside the
512 directory containing FILENAME. */
f9c026a8
NC
513
514char *
515make_tempdir (char *filename)
516{
485be063 517 char *tmpname = template_in_dir (filename);
f9c026a8 518
485be063
AM
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;
f9c026a8 531#endif
252b5132 532 return tmpname;
485be063 533#endif
252b5132
RH
534}
535
536/* Parse a string into a VMA, with a fatal error if it can't be
537 parsed. */
538
539bfd_vma
2da42df6 540parse_vma (const char *s, const char *arg)
252b5132
RH
541{
542 bfd_vma ret;
543 const char *end;
544
545 ret = bfd_scan_vma (s, &end, 0);
f462a9ea 546
252b5132
RH
547 if (*end != '\0')
548 fatal (_("%s: bad number: %s"), arg, s);
549
550 return ret;
551}
f24ddbdd
NC
552
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
a3029abd 555 error message is printed and (off_t) -1 is returned. */
f24ddbdd
NC
556
557off_t
558get_file_size (const char * file_name)
559{
560 struct stat statbuf;
561
562 if (stat (file_name, &statbuf) < 0)
563 {
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));
569 }
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;
574
52a476ee 575 return (off_t) -1;
f24ddbdd 576}
77f762d6
L
577
578/* Return the filename in a static buffer. */
579
580const char *
8d8e0703 581bfd_get_archive_filename (const bfd *abfd)
77f762d6
L
582{
583 static size_t curr = 0;
584 static char *buf;
585 size_t needed;
586
587 assert (abfd != NULL);
588
589 if (!abfd->my_archive)
590 return bfd_get_filename (abfd);
591
592 needed = (strlen (bfd_get_filename (abfd->my_archive))
593 + strlen (bfd_get_filename (abfd)) + 3);
594 if (needed > curr)
595 {
596 if (curr)
597 free (buf);
598 curr = needed + (needed >> 1);
3f5e193b 599 buf = (char *) bfd_malloc (curr);
77f762d6
L
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)
603 {
604 curr = 0;
605 return bfd_get_filename (abfd);
606 }
607 }
608 sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
609 bfd_get_filename (abfd));
610 return buf;
611}
This page took 0.434285 seconds and 4 git commands to generate.