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