Subversion Repositories Kolibri OS

Rev

Rev 5217 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5217 Rev 6324
1
/* bucomm.c -- Bin Utils COMmon code.
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, 2012
-
 
4
   Free Software Foundation, Inc.
2
   Copyright (C) 1991-2015 Free Software Foundation, Inc.
5
 
3
 
6
   This file is part of GNU Binutils.
4
   This file is part of GNU Binutils.
7
 
5
 
8
   This program is free software; you can redistribute it and/or modify
6
   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
7
   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
8
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
9
   (at your option) any later version.
12
 
10
 
13
   This program is distributed in the hope that it will be useful,
11
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
14
   GNU General Public License for more details.
17
 
15
 
18
   You should have received a copy of the GNU General Public License
16
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
17
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
19
   02110-1301, USA.  */
22

20

23
/* We might put this in a library someday so it could be dynamically
21
/* We might put this in a library someday so it could be dynamically
24
   loaded, but for now it's not necessary.  */
22
   loaded, but for now it's not necessary.  */
25
 
23
 
26
#include "sysdep.h"
24
#include "sysdep.h"
27
#include "bfd.h"
25
#include "bfd.h"
28
#include "libiberty.h"
26
#include "libiberty.h"
29
#include "filenames.h"
27
#include "filenames.h"
30
#include "libbfd.h"
28
#include "libbfd.h"
31
 
29
 
32
#include 		/* ctime, maybe time_t */
30
#include 		/* ctime, maybe time_t */
33
#include 
31
#include 
34
#include "bucomm.h"
32
#include "bucomm.h"
35
 
33
 
36
#ifndef HAVE_TIME_T_IN_TIME_H
34
#ifndef HAVE_TIME_T_IN_TIME_H
37
#ifndef HAVE_TIME_T_IN_TYPES_H
35
#ifndef HAVE_TIME_T_IN_TYPES_H
38
typedef long time_t;
36
typedef long time_t;
39
#endif
37
#endif
40
#endif
38
#endif
41
 
39
 
42
static const char * endian_string (enum bfd_endian);
40
static const char * endian_string (enum bfd_endian);
43
static int display_target_list (void);
41
static int display_target_list (void);
44
static int display_info_table (int, int);
42
static int display_info_table (int, int);
45
static int display_target_tables (void);
43
static int display_target_tables (void);
46

44

47
/* Error reporting.  */
45
/* Error reporting.  */
48
 
46
 
49
char *program_name;
47
char *program_name;
50
 
48
 
51
void
49
void
52
bfd_nonfatal (const char *string)
50
bfd_nonfatal (const char *string)
53
{
51
{
54
  const char *errmsg;
52
  const char *errmsg;
55
 
53
 
56
  errmsg = bfd_errmsg (bfd_get_error ());
54
  errmsg = bfd_errmsg (bfd_get_error ());
57
  fflush (stdout);
55
  fflush (stdout);
58
  if (string)
56
  if (string)
59
    fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
57
    fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
60
  else
58
  else
61
    fprintf (stderr, "%s: %s\n", program_name, errmsg);
59
    fprintf (stderr, "%s: %s\n", program_name, errmsg);
62
}
60
}
63
 
61
 
64
/* Issue a non fatal error message.  FILENAME, or if NULL then BFD,
62
/* Issue a non fatal error message.  FILENAME, or if NULL then BFD,
65
   are used to indicate the problematic file.  SECTION, if non NULL,
63
   are used to indicate the problematic file.  SECTION, if non NULL,
66
   is used to provide a section name.  If FORMAT is non-null, then it
64
   is used to provide a section name.  If FORMAT is non-null, then it
67
   is used to print additional information via vfprintf.  Finally the
65
   is used to print additional information via vfprintf.  Finally the
68
   bfd error message is printed.  In summary, error messages are of
66
   bfd error message is printed.  In summary, error messages are of
69
   one of the following forms:
67
   one of the following forms:
70
 
68
 
71
   PROGRAM:file: bfd-error-message
69
   PROGRAM:file: bfd-error-message
72
   PROGRAM:file[section]: bfd-error-message
70
   PROGRAM:file[section]: bfd-error-message
73
   PROGRAM:file: printf-message: bfd-error-message
71
   PROGRAM:file: printf-message: bfd-error-message
74
   PROGRAM:file[section]: printf-message: bfd-error-message.  */
72
   PROGRAM:file[section]: printf-message: bfd-error-message.  */
75
 
73
 
76
void
74
void
77
bfd_nonfatal_message (const char *filename,
75
bfd_nonfatal_message (const char *filename,
78
		      const bfd *abfd,
76
		      const bfd *abfd,
79
		      const asection *section,
77
		      const asection *section,
80
		      const char *format, ...)
78
		      const char *format, ...)
81
{
79
{
82
  const char *errmsg;
80
  const char *errmsg;
83
  const char *section_name;
81
  const char *section_name;
84
  va_list args;
82
  va_list args;
85
 
83
 
86
  errmsg = bfd_errmsg (bfd_get_error ());
84
  errmsg = bfd_errmsg (bfd_get_error ());
87
  fflush (stdout);
85
  fflush (stdout);
88
  section_name = NULL;
86
  section_name = NULL;
89
  va_start (args, format);
87
  va_start (args, format);
90
  fprintf (stderr, "%s", program_name);
88
  fprintf (stderr, "%s", program_name);
91
 
89
 
92
  if (abfd)
90
  if (abfd)
93
    {
91
    {
94
      if (!filename)
92
      if (!filename)
95
	filename = bfd_get_archive_filename (abfd);
93
	filename = bfd_get_archive_filename (abfd);
96
      if (section)
94
      if (section)
97
	section_name = bfd_get_section_name (abfd, section);
95
	section_name = bfd_get_section_name (abfd, section);
98
    }
96
    }
99
  if (section_name)
97
  if (section_name)
100
    fprintf (stderr, ":%s[%s]", filename, section_name);
98
    fprintf (stderr, ":%s[%s]", filename, section_name);
101
  else
99
  else
102
    fprintf (stderr, ":%s", filename);
100
    fprintf (stderr, ":%s", filename);
103
 
101
 
104
  if (format)
102
  if (format)
105
    {
103
    {
106
      fprintf (stderr, ": ");
104
      fprintf (stderr, ": ");
107
      vfprintf (stderr, format, args);
105
      vfprintf (stderr, format, args);
108
    }
106
    }
109
  fprintf (stderr, ": %s\n", errmsg);
107
  fprintf (stderr, ": %s\n", errmsg);
110
  va_end (args);
108
  va_end (args);
111
}
109
}
112
 
110
 
113
void
111
void
114
bfd_fatal (const char *string)
112
bfd_fatal (const char *string)
115
{
113
{
116
  bfd_nonfatal (string);
114
  bfd_nonfatal (string);
117
  xexit (1);
115
  xexit (1);
118
}
116
}
119
 
117
 
120
void
118
void
121
report (const char * format, va_list args)
119
report (const char * format, va_list args)
122
{
120
{
123
  fflush (stdout);
121
  fflush (stdout);
124
  fprintf (stderr, "%s: ", program_name);
122
  fprintf (stderr, "%s: ", program_name);
125
  vfprintf (stderr, format, args);
123
  vfprintf (stderr, format, args);
126
  putc ('\n', stderr);
124
  putc ('\n', stderr);
127
}
125
}
128
 
126
 
129
void
127
void
130
fatal VPARAMS ((const char *format, ...))
128
fatal (const char *format, ...)
131
{
129
{
132
  VA_OPEN (args, format);
130
  va_list args;
-
 
131
 
133
  VA_FIXEDARG (args, const char *, format);
132
  va_start (args, format);
134
 
133
 
135
  report (format, args);
134
  report (format, args);
136
  VA_CLOSE (args);
135
  va_end (args);
137
  xexit (1);
136
  xexit (1);
138
}
137
}
139
 
138
 
140
void
139
void
141
non_fatal VPARAMS ((const char *format, ...))
140
non_fatal (const char *format, ...)
142
{
141
{
143
  VA_OPEN (args, format);
142
  va_list args;
-
 
143
 
144
  VA_FIXEDARG (args, const char *, format);
144
  va_start (args, format);
145
 
145
 
146
  report (format, args);
146
  report (format, args);
147
  VA_CLOSE (args);
147
  va_end (args);
148
}
148
}
149
 
149
 
150
/* Set the default BFD target based on the configured target.  Doing
150
/* Set the default BFD target based on the configured target.  Doing
151
   this permits the binutils to be configured for a particular target,
151
   this permits the binutils to be configured for a particular target,
152
   and linked against a shared BFD library which was configured for a
152
   and linked against a shared BFD library which was configured for a
153
   different target.  */
153
   different target.  */
154
 
154
 
155
void
155
void
156
set_default_bfd_target (void)
156
set_default_bfd_target (void)
157
{
157
{
158
  /* The macro TARGET is defined by Makefile.  */
158
  /* The macro TARGET is defined by Makefile.  */
159
  const char *target = TARGET;
159
  const char *target = TARGET;
160
 
160
 
161
  if (! bfd_set_default_target (target))
161
  if (! bfd_set_default_target (target))
162
    fatal (_("can't set BFD default target to `%s': %s"),
162
    fatal (_("can't set BFD default target to `%s': %s"),
163
	   target, bfd_errmsg (bfd_get_error ()));
163
	   target, bfd_errmsg (bfd_get_error ()));
164
}
164
}
165
 
165
 
166
/* After a FALSE return from bfd_check_format_matches with
166
/* After a FALSE return from bfd_check_format_matches with
167
   bfd_get_error () == bfd_error_file_ambiguously_recognized, print
167
   bfd_get_error () == bfd_error_file_ambiguously_recognized, print
168
   the possible matching targets.  */
168
   the possible matching targets.  */
169
 
169
 
170
void
170
void
171
list_matching_formats (char **p)
171
list_matching_formats (char **p)
172
{
172
{
173
  fflush (stdout);
173
  fflush (stdout);
174
  fprintf (stderr, _("%s: Matching formats:"), program_name);
174
  fprintf (stderr, _("%s: Matching formats:"), program_name);
175
  while (*p)
175
  while (*p)
176
    fprintf (stderr, " %s", *p++);
176
    fprintf (stderr, " %s", *p++);
177
  fputc ('\n', stderr);
177
  fputc ('\n', stderr);
178
}
178
}
179
 
179
 
180
/* List the supported targets.  */
180
/* List the supported targets.  */
181
 
181
 
182
void
182
void
183
list_supported_targets (const char *name, FILE *f)
183
list_supported_targets (const char *name, FILE *f)
184
{
184
{
185
  int t;
185
  int t;
186
  const char **targ_names;
186
  const char **targ_names;
187
 
187
 
188
  if (name == NULL)
188
  if (name == NULL)
189
    fprintf (f, _("Supported targets:"));
189
    fprintf (f, _("Supported targets:"));
190
  else
190
  else
191
    fprintf (f, _("%s: supported targets:"), name);
191
    fprintf (f, _("%s: supported targets:"), name);
192
 
192
 
193
  targ_names = bfd_target_list ();
193
  targ_names = bfd_target_list ();
194
  for (t = 0; targ_names[t] != NULL; t++)
194
  for (t = 0; targ_names[t] != NULL; t++)
195
    fprintf (f, " %s", targ_names[t]);
195
    fprintf (f, " %s", targ_names[t]);
196
  fprintf (f, "\n");
196
  fprintf (f, "\n");
197
  free (targ_names);
197
  free (targ_names);
198
}
198
}
199
 
199
 
200
/* List the supported architectures.  */
200
/* List the supported architectures.  */
201
 
201
 
202
void
202
void
203
list_supported_architectures (const char *name, FILE *f)
203
list_supported_architectures (const char *name, FILE *f)
204
{
204
{
205
  const char ** arch;
205
  const char ** arch;
206
  const char ** arches;
206
  const char ** arches;
207
 
207
 
208
  if (name == NULL)
208
  if (name == NULL)
209
    fprintf (f, _("Supported architectures:"));
209
    fprintf (f, _("Supported architectures:"));
210
  else
210
  else
211
    fprintf (f, _("%s: supported architectures:"), name);
211
    fprintf (f, _("%s: supported architectures:"), name);
212
 
212
 
213
  for (arch = arches = bfd_arch_list (); *arch; arch++)
213
  for (arch = arches = bfd_arch_list (); *arch; arch++)
214
    fprintf (f, " %s", *arch);
214
    fprintf (f, " %s", *arch);
215
  fprintf (f, "\n");
215
  fprintf (f, "\n");
216
  free (arches);
216
  free (arches);
217
}
217
}
218

218

219
/* The length of the longest architecture name + 1.  */
219
/* The length of the longest architecture name + 1.  */
220
#define LONGEST_ARCH sizeof ("powerpc:common")
220
#define LONGEST_ARCH sizeof ("powerpc:common")
221
 
221
 
222
static const char *
222
static const char *
223
endian_string (enum bfd_endian endian)
223
endian_string (enum bfd_endian endian)
224
{
224
{
225
  switch (endian)
225
  switch (endian)
226
    {
226
    {
227
    case BFD_ENDIAN_BIG: return _("big endian");
227
    case BFD_ENDIAN_BIG: return _("big endian");
228
    case BFD_ENDIAN_LITTLE: return _("little endian");
228
    case BFD_ENDIAN_LITTLE: return _("little endian");
229
    default: return _("endianness unknown");
229
    default: return _("endianness unknown");
230
    }
230
    }
231
}
231
}
232
 
232
 
233
/* List the targets that BFD is configured to support, each followed
233
/* List the targets that BFD is configured to support, each followed
234
   by its endianness and the architectures it supports.  */
234
   by its endianness and the architectures it supports.  */
235
 
235
 
236
static int
236
static int
237
display_target_list (void)
237
display_target_list (void)
238
{
238
{
239
  char *dummy_name;
239
  char *dummy_name;
240
  int t;
240
  int t;
241
  int ret = 1;
241
  int ret = 1;
242
 
242
 
243
  dummy_name = make_temp_file (NULL);
243
  dummy_name = make_temp_file (NULL);
244
  for (t = 0; bfd_target_vector[t]; t++)
244
  for (t = 0; bfd_target_vector[t]; t++)
245
    {
245
    {
246
      const bfd_target *p = bfd_target_vector[t];
246
      const bfd_target *p = bfd_target_vector[t];
247
      bfd *abfd = bfd_openw (dummy_name, p->name);
247
      bfd *abfd = bfd_openw (dummy_name, p->name);
248
      int a;
248
      int a;
249
 
249
 
250
      printf (_("%s\n (header %s, data %s)\n"), p->name,
250
      printf (_("%s\n (header %s, data %s)\n"), p->name,
251
	      endian_string (p->header_byteorder),
251
	      endian_string (p->header_byteorder),
252
	      endian_string (p->byteorder));
252
	      endian_string (p->byteorder));
253
 
253
 
254
      if (abfd == NULL)
254
      if (abfd == NULL)
255
	{
255
	{
256
          bfd_nonfatal (dummy_name);
256
          bfd_nonfatal (dummy_name);
257
          ret = 0;
257
          ret = 0;
258
	  continue;
258
	  continue;
259
	}
259
	}
260
 
260
 
261
      if (! bfd_set_format (abfd, bfd_object))
261
      if (! bfd_set_format (abfd, bfd_object))
262
	{
262
	{
263
	  if (bfd_get_error () != bfd_error_invalid_operation)
263
	  if (bfd_get_error () != bfd_error_invalid_operation)
264
            {
264
            {
265
	      bfd_nonfatal (p->name);
265
	      bfd_nonfatal (p->name);
266
              ret = 0;
266
              ret = 0;
267
            }
267
            }
268
	  bfd_close_all_done (abfd);
268
	  bfd_close_all_done (abfd);
269
	  continue;
269
	  continue;
270
	}
270
	}
271
 
271
 
272
      for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
272
      for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
273
	if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
273
	if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
274
	  printf ("  %s\n",
274
	  printf ("  %s\n",
275
		  bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
275
		  bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
276
      bfd_close_all_done (abfd);
276
      bfd_close_all_done (abfd);
277
    }
277
    }
278
  unlink (dummy_name);
278
  unlink (dummy_name);
279
  free (dummy_name);
279
  free (dummy_name);
280
 
280
 
281
  return ret;
281
  return ret;
282
}
282
}
283
 
283
 
284
/* Print a table showing which architectures are supported for entries
284
/* Print a table showing which architectures are supported for entries
285
   FIRST through LAST-1 of bfd_target_vector (targets across,
285
   FIRST through LAST-1 of bfd_target_vector (targets across,
286
   architectures down).  */
286
   architectures down).  */
287
 
287
 
288
static int
288
static int
289
display_info_table (int first, int last)
289
display_info_table (int first, int last)
290
{
290
{
291
  int t;
291
  int t;
292
  int ret = 1;
292
  int ret = 1;
293
  char *dummy_name;
293
  char *dummy_name;
294
  int a;
294
  int a;
295
 
295
 
296
  /* Print heading of target names.  */
296
  /* Print heading of target names.  */
297
  printf ("\n%*s", (int) LONGEST_ARCH, " ");
297
  printf ("\n%*s", (int) LONGEST_ARCH, " ");
298
  for (t = first; t < last && bfd_target_vector[t]; t++)
298
  for (t = first; t < last && bfd_target_vector[t]; t++)
299
    printf ("%s ", bfd_target_vector[t]->name);
299
    printf ("%s ", bfd_target_vector[t]->name);
300
  putchar ('\n');
300
  putchar ('\n');
301
 
301
 
302
  dummy_name = make_temp_file (NULL);
302
  dummy_name = make_temp_file (NULL);
303
  for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
303
  for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
304
    if (strcmp (bfd_printable_arch_mach ((enum bfd_architecture) a, 0),
304
    if (strcmp (bfd_printable_arch_mach ((enum bfd_architecture) a, 0),
305
                "UNKNOWN!") != 0)
305
                "UNKNOWN!") != 0)
306
      {
306
      {
307
	printf ("%*s ", (int) LONGEST_ARCH - 1,
307
	printf ("%*s ", (int) LONGEST_ARCH - 1,
308
		bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
308
		bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
309
	for (t = first; t < last && bfd_target_vector[t]; t++)
309
	for (t = first; t < last && bfd_target_vector[t]; t++)
310
	  {
310
	  {
311
	    const bfd_target *p = bfd_target_vector[t];
311
	    const bfd_target *p = bfd_target_vector[t];
312
	    bfd_boolean ok = TRUE;
312
	    bfd_boolean ok = TRUE;
313
	    bfd *abfd = bfd_openw (dummy_name, p->name);
313
	    bfd *abfd = bfd_openw (dummy_name, p->name);
314
 
314
 
315
	    if (abfd == NULL)
315
	    if (abfd == NULL)
316
	      {
316
	      {
317
		bfd_nonfatal (p->name);
317
		bfd_nonfatal (p->name);
318
                ret = 0;
318
                ret = 0;
319
		ok = FALSE;
319
		ok = FALSE;
320
	      }
320
	      }
321
 
321
 
322
	    if (ok)
322
	    if (ok)
323
	      {
323
	      {
324
		if (! bfd_set_format (abfd, bfd_object))
324
		if (! bfd_set_format (abfd, bfd_object))
325
		  {
325
		  {
326
		    if (bfd_get_error () != bfd_error_invalid_operation)
326
		    if (bfd_get_error () != bfd_error_invalid_operation)
327
                      {
327
                      {
328
		        bfd_nonfatal (p->name);
328
		        bfd_nonfatal (p->name);
329
                        ret = 0;
329
                        ret = 0;
330
                      }
330
                      }
331
		    ok = FALSE;
331
		    ok = FALSE;
332
		  }
332
		  }
333
	      }
333
	      }
334
 
334
 
335
	    if (ok)
335
	    if (ok)
336
	      {
336
	      {
337
		if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
337
		if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
338
		  ok = FALSE;
338
		  ok = FALSE;
339
	      }
339
	      }
340
 
340
 
341
	    if (ok)
341
	    if (ok)
342
	      printf ("%s ", p->name);
342
	      printf ("%s ", p->name);
343
	    else
343
	    else
344
	      {
344
	      {
345
		int l = strlen (p->name);
345
		int l = strlen (p->name);
346
		while (l--)
346
		while (l--)
347
		  putchar ('-');
347
		  putchar ('-');
348
		putchar (' ');
348
		putchar (' ');
349
	      }
349
	      }
350
	    if (abfd != NULL)
350
	    if (abfd != NULL)
351
	      bfd_close_all_done (abfd);
351
	      bfd_close_all_done (abfd);
352
	  }
352
	  }
353
	putchar ('\n');
353
	putchar ('\n');
354
      }
354
      }
355
  unlink (dummy_name);
355
  unlink (dummy_name);
356
  free (dummy_name);
356
  free (dummy_name);
357
 
357
 
358
  return ret;
358
  return ret;
359
}
359
}
360
 
360
 
361
/* Print tables of all the target-architecture combinations that
361
/* Print tables of all the target-architecture combinations that
362
   BFD has been configured to support.  */
362
   BFD has been configured to support.  */
363
 
363
 
364
static int
364
static int
365
display_target_tables (void)
365
display_target_tables (void)
366
{
366
{
367
  int t;
367
  int t;
368
  int columns;
368
  int columns;
369
  int ret = 1;
369
  int ret = 1;
370
  char *colum;
370
  char *colum;
371
 
371
 
372
  columns = 0;
372
  columns = 0;
373
  colum = getenv ("COLUMNS");
373
  colum = getenv ("COLUMNS");
374
  if (colum != NULL)
374
  if (colum != NULL)
375
    columns = atoi (colum);
375
    columns = atoi (colum);
376
  if (columns == 0)
376
  if (columns == 0)
377
    columns = 80;
377
    columns = 80;
378
 
378
 
379
  t = 0;
379
  t = 0;
380
  while (bfd_target_vector[t] != NULL)
380
  while (bfd_target_vector[t] != NULL)
381
    {
381
    {
382
      int oldt = t, wid;
382
      int oldt = t, wid;
383
 
383
 
384
      wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
384
      wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
385
      ++t;
385
      ++t;
386
      while (wid < columns && bfd_target_vector[t] != NULL)
386
      while (wid < columns && bfd_target_vector[t] != NULL)
387
	{
387
	{
388
	  int newwid;
388
	  int newwid;
389
 
389
 
390
	  newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
390
	  newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
391
	  if (newwid >= columns)
391
	  if (newwid >= columns)
392
	    break;
392
	    break;
393
	  wid = newwid;
393
	  wid = newwid;
394
	  ++t;
394
	  ++t;
395
	}
395
	}
396
      if (! display_info_table (oldt, t))
396
      if (! display_info_table (oldt, t))
397
        ret = 0;
397
        ret = 0;
398
    }
398
    }
399
 
399
 
400
  return ret;
400
  return ret;
401
}
401
}
402
 
402
 
403
int
403
int
404
display_info (void)
404
display_info (void)
405
{
405
{
406
  printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
406
  printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
407
  if (! display_target_list () || ! display_target_tables ())
407
  if (! display_target_list () || ! display_target_tables ())
408
    return 1;
408
    return 1;
409
  else
409
  else
410
    return 0;
410
    return 0;
411
}
411
}
412

412

413
/* Display the archive header for an element as if it were an ls -l listing:
413
/* Display the archive header for an element as if it were an ls -l listing:
414
 
414
 
415
   Mode       User\tGroup\tSize\tDate               Name */
415
   Mode       User\tGroup\tSize\tDate               Name */
416
 
416
 
417
void
417
void
418
print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
418
print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
419
{
419
{
420
  struct stat buf;
420
  struct stat buf;
421
 
421
 
422
  if (verbose)
422
  if (verbose)
423
    {
423
    {
424
      if (bfd_stat_arch_elt (abfd, &buf) == 0)
424
      if (bfd_stat_arch_elt (abfd, &buf) == 0)
425
	{
425
	{
426
	  char modebuf[11];
426
	  char modebuf[11];
427
	  char timebuf[40];
427
	  char timebuf[40];
428
	  time_t when = buf.st_mtime;
428
	  time_t when = buf.st_mtime;
429
	  const char *ctime_result = (const char *) ctime (&when);
429
	  const char *ctime_result = (const char *) ctime (&when);
430
	  bfd_size_type size;
430
	  bfd_size_type size;
-
 
431
 
-
 
432
	  /* PR binutils/17605: Check for corrupt time values.  */
-
 
433
	  if (ctime_result == NULL)
-
 
434
	    sprintf (timebuf, _("
431
 
435
	  else
432
	  /* POSIX format:  skip weekday and seconds from ctime output.  */
436
	  /* POSIX format:  skip weekday and seconds from ctime output.  */
433
	  sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
437
	  sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
434
 
438
 
435
	  mode_string (buf.st_mode, modebuf);
439
	  mode_string (buf.st_mode, modebuf);
436
	  modebuf[10] = '\0';
440
	  modebuf[10] = '\0';
437
	  size = buf.st_size;
441
	  size = buf.st_size;
438
	  /* POSIX 1003.2/D11 says to skip first character (entry type).  */
442
	  /* POSIX 1003.2/D11 says to skip first character (entry type).  */
439
	  fprintf (file, "%s %ld/%ld %6" BFD_VMA_FMT "u %s ", modebuf + 1,
443
	  fprintf (file, "%s %ld/%ld %6" BFD_VMA_FMT "u %s ", modebuf + 1,
440
		   (long) buf.st_uid, (long) buf.st_gid,
444
		   (long) buf.st_uid, (long) buf.st_gid,
441
		   size, timebuf);
445
		   size, timebuf);
442
	}
446
	}
443
    }
447
    }
444
 
448
 
445
  fprintf (file, "%s\n", bfd_get_filename (abfd));
449
  fprintf (file, "%s\n", bfd_get_filename (abfd));
446
}
450
}
447
 
451
 
448
/* Return a path for a new temporary file in the same directory
452
/* Return a path for a new temporary file in the same directory
449
   as file PATH.  */
453
   as file PATH.  */
450
 
454
 
451
static char *
455
static char *
452
template_in_dir (const char *path)
456
template_in_dir (const char *path)
453
{
457
{
454
#define template "stXXXXXX"
458
#define template "stXXXXXX"
455
  const char *slash = strrchr (path, '/');
459
  const char *slash = strrchr (path, '/');
456
  char *tmpname;
460
  char *tmpname;
457
  size_t len;
461
  size_t len;
458
 
462
 
459
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
463
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
460
  {
464
  {
461
    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
465
    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
462
    char *bslash = strrchr (path, '\\');
466
    char *bslash = strrchr (path, '\\');
463
 
467
 
464
    if (slash == NULL || (bslash != NULL && bslash > slash))
468
    if (slash == NULL || (bslash != NULL && bslash > slash))
465
      slash = bslash;
469
      slash = bslash;
466
    if (slash == NULL && path[0] != '\0' && path[1] == ':')
470
    if (slash == NULL && path[0] != '\0' && path[1] == ':')
467
      slash = path + 1;
471
      slash = path + 1;
468
  }
472
  }
469
#endif
473
#endif
470
 
474
 
471
  if (slash != (char *) NULL)
475
  if (slash != (char *) NULL)
472
    {
476
    {
473
      len = slash - path;
477
      len = slash - path;
474
      tmpname = (char *) xmalloc (len + sizeof (template) + 2);
478
      tmpname = (char *) xmalloc (len + sizeof (template) + 2);
475
      memcpy (tmpname, path, len);
479
      memcpy (tmpname, path, len);
476
 
480
 
477
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
481
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
478
      /* If tmpname is "X:", appending a slash will make it a root
482
      /* If tmpname is "X:", appending a slash will make it a root
479
	 directory on drive X, which is NOT the same as the current
483
	 directory on drive X, which is NOT the same as the current
480
	 directory on drive X.  */
484
	 directory on drive X.  */
481
      if (len == 2 && tmpname[1] == ':')
485
      if (len == 2 && tmpname[1] == ':')
482
	tmpname[len++] = '.';
486
	tmpname[len++] = '.';
483
#endif
487
#endif
484
      tmpname[len++] = '/';
488
      tmpname[len++] = '/';
485
    }
489
    }
486
  else
490
  else
487
    {
491
    {
488
      tmpname = (char *) xmalloc (sizeof (template));
492
      tmpname = (char *) xmalloc (sizeof (template));
489
      len = 0;
493
      len = 0;
490
    }
494
    }
491
 
495
 
492
  memcpy (tmpname + len, template, sizeof (template));
496
  memcpy (tmpname + len, template, sizeof (template));
493
  return tmpname;
497
  return tmpname;
494
#undef template
498
#undef template
495
}
499
}
496
 
500
 
497
/* Return the name of a created temporary file in the same directory
501
/* Return the name of a created temporary file in the same directory
498
   as FILENAME.  */
502
   as FILENAME.  */
499
 
503
 
500
char *
504
char *
501
make_tempname (char *filename)
505
make_tempname (char *filename)
502
{
506
{
503
  char *tmpname = template_in_dir (filename);
507
  char *tmpname = template_in_dir (filename);
504
  int fd;
508
  int fd;
505
 
509
 
506
#ifdef HAVE_MKSTEMP
510
#ifdef HAVE_MKSTEMP
507
  fd = mkstemp (tmpname);
511
  fd = mkstemp (tmpname);
508
#else
512
#else
509
  tmpname = mktemp (tmpname);
513
  tmpname = mktemp (tmpname);
510
  if (tmpname == NULL)
514
  if (tmpname == NULL)
511
    return NULL;
515
    return NULL;
512
  fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
516
  fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
513
#endif
517
#endif
514
  if (fd == -1)
518
  if (fd == -1)
515
    {
519
    {
516
      free (tmpname);
520
      free (tmpname);
517
      return NULL;
521
      return NULL;
518
    }
522
    }
519
  close (fd);
523
  close (fd);
520
  return tmpname;
524
  return tmpname;
521
}
525
}
522
 
526
 
523
/* Return the name of a created temporary directory inside the
527
/* Return the name of a created temporary directory inside the
524
   directory containing FILENAME.  */
528
   directory containing FILENAME.  */
525
 
529
 
526
char *
530
char *
527
make_tempdir (char *filename)
531
make_tempdir (char *filename)
528
{
532
{
529
  char *tmpname = template_in_dir (filename);
533
  char *tmpname = template_in_dir (filename);
530
 
534
 
531
/*
535
/*
532
#ifdef HAVE_MKDTEMP
536
#ifdef HAVE_MKDTEMP
533
  return mkdtemp (tmpname);
537
  return mkdtemp (tmpname);
534
#else
538
#else
535
  tmpname = mktemp (tmpname);
539
  tmpname = mktemp (tmpname);
536
  if (tmpname == NULL)
540
  if (tmpname == NULL)
537
    return NULL;
541
    return NULL;
538
#if defined (_WIN32) && !defined (__CYGWIN32__)
542
#if defined (_WIN32) && !defined (__CYGWIN32__)
539
  if (mkdir (tmpname) != 0)
543
  if (mkdir (tmpname) != 0)
540
    return NULL;
544
    return NULL;
541
#else
545
#else
542
  if (mkdir (tmpname, 0700) != 0)
546
  if (mkdir (tmpname, 0700) != 0)
543
    return NULL;
547
    return NULL;
544
#endif
548
#endif
545
  return tmpname;
549
  return tmpname;
546
#endif
550
#endif
547
*/
551
*/
548
  return NULL;
552
  return NULL;
549
}
553
}
550
 
554
 
551
/* Parse a string into a VMA, with a fatal error if it can't be
555
/* Parse a string into a VMA, with a fatal error if it can't be
552
   parsed.  */
556
   parsed.  */
553
 
557
 
554
bfd_vma
558
bfd_vma
555
parse_vma (const char *s, const char *arg)
559
parse_vma (const char *s, const char *arg)
556
{
560
{
557
  bfd_vma ret;
561
  bfd_vma ret;
558
  const char *end;
562
  const char *end;
559
 
563
 
560
  ret = bfd_scan_vma (s, &end, 0);
564
  ret = bfd_scan_vma (s, &end, 0);
561
 
565
 
562
  if (*end != '\0')
566
  if (*end != '\0')
563
    fatal (_("%s: bad number: %s"), arg, s);
567
    fatal (_("%s: bad number: %s"), arg, s);
564
 
568
 
565
  return ret;
569
  return ret;
566
}
570
}
567
 
571
 
568
/* Returns the size of the named file.  If the file does not
572
/* Returns the size of the named file.  If the file does not
569
   exist, or if it is not a real file, then a suitable non-fatal
573
   exist, or if it is not a real file, then a suitable non-fatal
570
   error message is printed and (off_t) -1 is returned.  */
574
   error message is printed and (off_t) -1 is returned.  */
571
 
575
 
572
off_t
576
off_t
573
get_file_size (const char * file_name)
577
get_file_size (const char * file_name)
574
{
578
{
575
  struct stat statbuf;
579
  struct stat statbuf;
576
 
580
 
577
  if (stat (file_name, &statbuf) < 0)
581
  if (stat (file_name, &statbuf) < 0)
578
    {
582
    {
579
      if (errno == ENOENT)
583
      if (errno == ENOENT)
580
	non_fatal (_("'%s': No such file"), file_name);
584
	non_fatal (_("'%s': No such file"), file_name);
581
      else
585
      else
582
	non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
586
	non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
583
		   file_name, strerror (errno));
587
		   file_name, strerror (errno));
584
    }
588
    }
585
  else if (! S_ISREG (statbuf.st_mode))
589
  else if (! S_ISREG (statbuf.st_mode))
586
    non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
590
    non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
587
  else if (statbuf.st_size < 0)
591
  else if (statbuf.st_size < 0)
588
    non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
592
    non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
589
               file_name);
593
               file_name);
590
  else
594
  else
591
    return statbuf.st_size;
595
    return statbuf.st_size;
592
 
596
 
593
  return (off_t) -1;
597
  return (off_t) -1;
594
}
598
}
595
 
599
 
596
/* Return the filename in a static buffer.  */
600
/* Return the filename in a static buffer.  */
597
 
601
 
598
const char *
602
const char *
599
bfd_get_archive_filename (const bfd *abfd)
603
bfd_get_archive_filename (const bfd *abfd)
600
{
604
{
601
  static size_t curr = 0;
605
  static size_t curr = 0;
602
  static char *buf;
606
  static char *buf;
603
  size_t needed;
607
  size_t needed;
604
 
608
 
605
  assert (abfd != NULL);
609
  assert (abfd != NULL);
606
 
610
 
607
  if (!abfd->my_archive)
611
  if (!abfd->my_archive)
608
    return bfd_get_filename (abfd);
612
    return bfd_get_filename (abfd);
609
 
613
 
610
  needed = (strlen (bfd_get_filename (abfd->my_archive))
614
  needed = (strlen (bfd_get_filename (abfd->my_archive))
611
	    + strlen (bfd_get_filename (abfd)) + 3);
615
	    + strlen (bfd_get_filename (abfd)) + 3);
612
  if (needed > curr)
616
  if (needed > curr)
613
    {
617
    {
614
      if (curr)
618
      if (curr)
615
	free (buf);
619
	free (buf);
616
      curr = needed + (needed >> 1);
620
      curr = needed + (needed >> 1);
617
      buf = (char *) bfd_malloc (curr);
621
      buf = (char *) bfd_malloc (curr);
618
      /* If we can't malloc, fail safe by returning just the file name.
622
      /* If we can't malloc, fail safe by returning just the file name.
619
	 This function is only used when building error messages.  */
623
	 This function is only used when building error messages.  */
620
      if (!buf)
624
      if (!buf)
621
	{
625
	{
622
	  curr = 0;
626
	  curr = 0;
623
	  return bfd_get_filename (abfd);
627
	  return bfd_get_filename (abfd);
624
	}
628
	}
625
    }
629
    }
626
  sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
630
  sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
627
	   bfd_get_filename (abfd));
631
	   bfd_get_filename (abfd));
628
  return buf;
632
  return buf;
629
}
633
}
-
 
634
 
-
 
635
/* Returns TRUE iff PATHNAME, a filename of an archive member,
-
 
636
   is valid for writing.  For security reasons absolute paths
-
 
637
   and paths containing /../ are not allowed.  See PR 17533.  */
-
 
638
 
-
 
639
bfd_boolean
-
 
640
is_valid_archive_path (char const * pathname)
-
 
641
{
-
 
642
  const char * n = pathname;
-
 
643
 
-
 
644
  if (IS_ABSOLUTE_PATH (n))
-
 
645
    return FALSE;
-
 
646
 
-
 
647
  while (*n)
-
 
648
    {
-
 
649
      if (*n == '.' && *++n == '.' && ( ! *++n || IS_DIR_SEPARATOR (*n)))
-
 
650
	return FALSE;
-
 
651
 
-
 
652
      while (*n && ! IS_DIR_SEPARATOR (*n))
-
 
653
	n++;
-
 
654
      while (IS_DIR_SEPARATOR (*n))
-
 
655
	n++;
-
 
656
    }
-
 
657
 
-
 
658
  return TRUE;
-
 
659
}