133965Sjdp/* bucomm.c -- Bin Utils COMmon code.
2218822Sdim   Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
3218822Sdim   2003, 2006, 2007
460484Sobrien   Free Software Foundation, Inc.
533965Sjdp
633965Sjdp   This file is part of GNU Binutils.
733965Sjdp
833965Sjdp   This program is free software; you can redistribute it and/or modify
933965Sjdp   it under the terms of the GNU General Public License as published by
1033965Sjdp   the Free Software Foundation; either version 2 of the License, or
1133965Sjdp   (at your option) any later version.
1233965Sjdp
1333965Sjdp   This program is distributed in the hope that it will be useful,
1433965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1533965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1633965Sjdp   GNU General Public License for more details.
1733965Sjdp
1833965Sjdp   You should have received a copy of the GNU General Public License
1933965Sjdp   along with this program; if not, write to the Free Software
20218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21218822Sdim   02110-1301, USA.  */
2233965Sjdp
2333965Sjdp/* We might put this in a library someday so it could be dynamically
2433965Sjdp   loaded, but for now it's not necessary.  */
2533965Sjdp
26218822Sdim#include "sysdep.h"
2733965Sjdp#include "bfd.h"
2833965Sjdp#include "libiberty.h"
2961843Sobrien#include "filenames.h"
30130561Sobrien#include "libbfd.h"
3133965Sjdp
3233965Sjdp#include <sys/stat.h>
3333965Sjdp#include <time.h>		/* ctime, maybe time_t */
34218822Sdim#include <assert.h>
35218822Sdim#include "bucomm.h"
3633965Sjdp
3733965Sjdp#ifndef HAVE_TIME_T_IN_TIME_H
3833965Sjdp#ifndef HAVE_TIME_T_IN_TYPES_H
3933965Sjdptypedef long time_t;
4033965Sjdp#endif
4133965Sjdp#endif
42130561Sobrien
43130561Sobrienstatic const char * endian_string (enum bfd_endian);
44130561Sobrienstatic int display_target_list (void);
45130561Sobrienstatic int display_info_table (int, int);
46130561Sobrienstatic int display_target_tables (void);
4733965Sjdp
48130561Sobrien/* Error reporting.  */
4933965Sjdp
5033965Sjdpchar *program_name;
5133965Sjdp
5233965Sjdpvoid
53130561Sobrienbfd_nonfatal (const char *string)
5433965Sjdp{
55104834Sobrien  const char *errmsg = bfd_errmsg (bfd_get_error ());
5633965Sjdp
5733965Sjdp  if (string)
5833965Sjdp    fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
5933965Sjdp  else
6033965Sjdp    fprintf (stderr, "%s: %s\n", program_name, errmsg);
6133965Sjdp}
6233965Sjdp
6333965Sjdpvoid
64130561Sobrienbfd_fatal (const char *string)
6533965Sjdp{
6633965Sjdp  bfd_nonfatal (string);
6733965Sjdp  xexit (1);
6833965Sjdp}
6933965Sjdp
7060484Sobrienvoid
71130561Sobrienreport (const char * format, va_list args)
7260484Sobrien{
7360484Sobrien  fprintf (stderr, "%s: ", program_name);
7460484Sobrien  vfprintf (stderr, format, args);
7560484Sobrien  putc ('\n', stderr);
7660484Sobrien}
7760484Sobrien
7833965Sjdpvoid
7989857Sobrienfatal VPARAMS ((const char *format, ...))
8033965Sjdp{
8189857Sobrien  VA_OPEN (args, format);
8289857Sobrien  VA_FIXEDARG (args, const char *, format);
8333965Sjdp
8460484Sobrien  report (format, args);
8589857Sobrien  VA_CLOSE (args);
8633965Sjdp  xexit (1);
8733965Sjdp}
8860484Sobrien
8960484Sobrienvoid
9089857Sobriennon_fatal VPARAMS ((const char *format, ...))
9160484Sobrien{
9289857Sobrien  VA_OPEN (args, format);
9389857Sobrien  VA_FIXEDARG (args, const char *, format);
9460484Sobrien
9560484Sobrien  report (format, args);
9689857Sobrien  VA_CLOSE (args);
9760484Sobrien}
9833965Sjdp
9933965Sjdp/* Set the default BFD target based on the configured target.  Doing
10033965Sjdp   this permits the binutils to be configured for a particular target,
10133965Sjdp   and linked against a shared BFD library which was configured for a
10233965Sjdp   different target.  */
10333965Sjdp
10433965Sjdpvoid
105130561Sobrienset_default_bfd_target (void)
10633965Sjdp{
10733965Sjdp  /* The macro TARGET is defined by Makefile.  */
10833965Sjdp  const char *target = TARGET;
10933965Sjdp
11033965Sjdp  if (! bfd_set_default_target (target))
11160484Sobrien    fatal (_("can't set BFD default target to `%s': %s"),
11260484Sobrien	   target, bfd_errmsg (bfd_get_error ()));
11333965Sjdp}
11433965Sjdp
115130561Sobrien/* After a FALSE return from bfd_check_format_matches with
11633965Sjdp   bfd_get_error () == bfd_error_file_ambiguously_recognized, print
11733965Sjdp   the possible matching targets.  */
11833965Sjdp
11933965Sjdpvoid
120130561Sobrienlist_matching_formats (char **p)
12133965Sjdp{
12260484Sobrien  fprintf (stderr, _("%s: Matching formats:"), program_name);
12333965Sjdp  while (*p)
12460484Sobrien    fprintf (stderr, " %s", *p++);
12560484Sobrien  fputc ('\n', stderr);
12633965Sjdp}
12733965Sjdp
12833965Sjdp/* List the supported targets.  */
12933965Sjdp
13033965Sjdpvoid
131130561Sobrienlist_supported_targets (const char *name, FILE *f)
13233965Sjdp{
13333965Sjdp  int t;
134107492Sobrien  const char **targ_names = bfd_target_list ();
13533965Sjdp
13633965Sjdp  if (name == NULL)
13760484Sobrien    fprintf (f, _("Supported targets:"));
13833965Sjdp  else
13960484Sobrien    fprintf (f, _("%s: supported targets:"), name);
140107492Sobrien
141107492Sobrien  for (t = 0; targ_names[t] != NULL; t++)
142107492Sobrien    fprintf (f, " %s", targ_names[t]);
14333965Sjdp  fprintf (f, "\n");
144107492Sobrien  free (targ_names);
14533965Sjdp}
14689857Sobrien
14789857Sobrien/* List the supported architectures.  */
14889857Sobrien
14989857Sobrienvoid
150130561Sobrienlist_supported_architectures (const char *name, FILE *f)
15189857Sobrien{
152130561Sobrien  const char **arch;
15389857Sobrien
15489857Sobrien  if (name == NULL)
15589857Sobrien    fprintf (f, _("Supported architectures:"));
15689857Sobrien  else
15789857Sobrien    fprintf (f, _("%s: supported architectures:"), name);
15889857Sobrien
15989857Sobrien  for (arch = bfd_arch_list (); *arch; arch++)
16089857Sobrien    fprintf (f, " %s", *arch);
16189857Sobrien  fprintf (f, "\n");
16289857Sobrien}
16333965Sjdp
164130561Sobrien/* The length of the longest architecture name + 1.  */
165130561Sobrien#define LONGEST_ARCH sizeof ("powerpc:common")
166130561Sobrien
167130561Sobrienstatic const char *
168130561Sobrienendian_string (enum bfd_endian endian)
169130561Sobrien{
170130561Sobrien  switch (endian)
171130561Sobrien    {
172130561Sobrien    case BFD_ENDIAN_BIG: return "big endian";
173130561Sobrien    case BFD_ENDIAN_LITTLE: return "little endian";
174130561Sobrien    default: return "endianness unknown";
175130561Sobrien    }
176130561Sobrien}
177130561Sobrien
178130561Sobrien/* List the targets that BFD is configured to support, each followed
179130561Sobrien   by its endianness and the architectures it supports.  */
180130561Sobrien
181130561Sobrienstatic int
182130561Sobriendisplay_target_list (void)
183130561Sobrien{
184130561Sobrien  char *dummy_name;
185130561Sobrien  int t;
186130561Sobrien  int ret = 1;
187130561Sobrien
188130561Sobrien  dummy_name = make_temp_file (NULL);
189130561Sobrien  for (t = 0; bfd_target_vector[t]; t++)
190130561Sobrien    {
191130561Sobrien      const bfd_target *p = bfd_target_vector[t];
192130561Sobrien      bfd *abfd = bfd_openw (dummy_name, p->name);
193218822Sdim      enum bfd_architecture a;
194130561Sobrien
195130561Sobrien      printf ("%s\n (header %s, data %s)\n", p->name,
196130561Sobrien	      endian_string (p->header_byteorder),
197130561Sobrien	      endian_string (p->byteorder));
198130561Sobrien
199130561Sobrien      if (abfd == NULL)
200130561Sobrien	{
201130561Sobrien          bfd_nonfatal (dummy_name);
202130561Sobrien          ret = 0;
203130561Sobrien	  continue;
204130561Sobrien	}
205130561Sobrien
206130561Sobrien      if (! bfd_set_format (abfd, bfd_object))
207130561Sobrien	{
208130561Sobrien	  if (bfd_get_error () != bfd_error_invalid_operation)
209130561Sobrien            {
210130561Sobrien	      bfd_nonfatal (p->name);
211130561Sobrien              ret = 0;
212130561Sobrien            }
213130561Sobrien	  bfd_close_all_done (abfd);
214130561Sobrien	  continue;
215130561Sobrien	}
216130561Sobrien
217218822Sdim      for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
218130561Sobrien	if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
219130561Sobrien	  printf ("  %s\n",
220130561Sobrien		  bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
221130561Sobrien      bfd_close_all_done (abfd);
222130561Sobrien    }
223130561Sobrien  unlink (dummy_name);
224130561Sobrien  free (dummy_name);
225130561Sobrien
226130561Sobrien  return ret;
227130561Sobrien}
228130561Sobrien
229130561Sobrien/* Print a table showing which architectures are supported for entries
230130561Sobrien   FIRST through LAST-1 of bfd_target_vector (targets across,
231130561Sobrien   architectures down).  */
232130561Sobrien
233130561Sobrienstatic int
234130561Sobriendisplay_info_table (int first, int last)
235130561Sobrien{
236130561Sobrien  int t;
237130561Sobrien  int ret = 1;
238130561Sobrien  char *dummy_name;
239218822Sdim  enum bfd_architecture a;
240130561Sobrien
241130561Sobrien  /* Print heading of target names.  */
242130561Sobrien  printf ("\n%*s", (int) LONGEST_ARCH, " ");
243130561Sobrien  for (t = first; t < last && bfd_target_vector[t]; t++)
244130561Sobrien    printf ("%s ", bfd_target_vector[t]->name);
245130561Sobrien  putchar ('\n');
246130561Sobrien
247130561Sobrien  dummy_name = make_temp_file (NULL);
248218822Sdim  for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
249130561Sobrien    if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
250130561Sobrien      {
251130561Sobrien	printf ("%*s ", (int) LONGEST_ARCH - 1,
252130561Sobrien		bfd_printable_arch_mach (a, 0));
253130561Sobrien	for (t = first; t < last && bfd_target_vector[t]; t++)
254130561Sobrien	  {
255130561Sobrien	    const bfd_target *p = bfd_target_vector[t];
256130561Sobrien	    bfd_boolean ok = TRUE;
257130561Sobrien	    bfd *abfd = bfd_openw (dummy_name, p->name);
258130561Sobrien
259130561Sobrien	    if (abfd == NULL)
260130561Sobrien	      {
261130561Sobrien		bfd_nonfatal (p->name);
262130561Sobrien                ret = 0;
263130561Sobrien		ok = FALSE;
264130561Sobrien	      }
265130561Sobrien
266130561Sobrien	    if (ok)
267130561Sobrien	      {
268130561Sobrien		if (! bfd_set_format (abfd, bfd_object))
269130561Sobrien		  {
270130561Sobrien		    if (bfd_get_error () != bfd_error_invalid_operation)
271130561Sobrien                      {
272130561Sobrien		        bfd_nonfatal (p->name);
273130561Sobrien                        ret = 0;
274130561Sobrien                      }
275130561Sobrien		    ok = FALSE;
276130561Sobrien		  }
277130561Sobrien	      }
278130561Sobrien
279130561Sobrien	    if (ok)
280130561Sobrien	      {
281130561Sobrien		if (! bfd_set_arch_mach (abfd, a, 0))
282130561Sobrien		  ok = FALSE;
283130561Sobrien	      }
284130561Sobrien
285130561Sobrien	    if (ok)
286130561Sobrien	      printf ("%s ", p->name);
287130561Sobrien	    else
288130561Sobrien	      {
289130561Sobrien		int l = strlen (p->name);
290130561Sobrien		while (l--)
291130561Sobrien		  putchar ('-');
292130561Sobrien		putchar (' ');
293130561Sobrien	      }
294130561Sobrien	    if (abfd != NULL)
295130561Sobrien	      bfd_close_all_done (abfd);
296130561Sobrien	  }
297130561Sobrien	putchar ('\n');
298130561Sobrien      }
299130561Sobrien  unlink (dummy_name);
300130561Sobrien  free (dummy_name);
301130561Sobrien
302130561Sobrien  return ret;
303130561Sobrien}
304130561Sobrien
305130561Sobrien/* Print tables of all the target-architecture combinations that
306130561Sobrien   BFD has been configured to support.  */
307130561Sobrien
308130561Sobrienstatic int
309130561Sobriendisplay_target_tables (void)
310130561Sobrien{
311130561Sobrien  int t;
312130561Sobrien  int columns;
313130561Sobrien  int ret = 1;
314130561Sobrien  char *colum;
315130561Sobrien
316130561Sobrien  columns = 0;
317130561Sobrien  colum = getenv ("COLUMNS");
318130561Sobrien  if (colum != NULL)
319130561Sobrien    columns = atoi (colum);
320130561Sobrien  if (columns == 0)
321130561Sobrien    columns = 80;
322130561Sobrien
323130561Sobrien  t = 0;
324130561Sobrien  while (bfd_target_vector[t] != NULL)
325130561Sobrien    {
326130561Sobrien      int oldt = t, wid;
327130561Sobrien
328130561Sobrien      wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
329130561Sobrien      ++t;
330130561Sobrien      while (wid < columns && bfd_target_vector[t] != NULL)
331130561Sobrien	{
332130561Sobrien	  int newwid;
333130561Sobrien
334130561Sobrien	  newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
335130561Sobrien	  if (newwid >= columns)
336130561Sobrien	    break;
337130561Sobrien	  wid = newwid;
338130561Sobrien	  ++t;
339130561Sobrien	}
340130561Sobrien      if (! display_info_table (oldt, t))
341130561Sobrien        ret = 0;
342130561Sobrien    }
343130561Sobrien
344130561Sobrien  return ret;
345130561Sobrien}
346130561Sobrien
347130561Sobrienint
348130561Sobriendisplay_info (void)
349130561Sobrien{
350130561Sobrien  printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
351130561Sobrien  if (! display_target_list () || ! display_target_tables ())
352130561Sobrien    return 1;
353130561Sobrien  else
354130561Sobrien    return 0;
355130561Sobrien}
356130561Sobrien
35733965Sjdp/* Display the archive header for an element as if it were an ls -l listing:
35833965Sjdp
35933965Sjdp   Mode       User\tGroup\tSize\tDate               Name */
36033965Sjdp
36133965Sjdpvoid
362130561Sobrienprint_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
36333965Sjdp{
36433965Sjdp  struct stat buf;
36533965Sjdp
36633965Sjdp  if (verbose)
36733965Sjdp    {
36833965Sjdp      if (bfd_stat_arch_elt (abfd, &buf) == 0)
36933965Sjdp	{
37033965Sjdp	  char modebuf[11];
37133965Sjdp	  char timebuf[40];
37233965Sjdp	  time_t when = buf.st_mtime;
373104834Sobrien	  const char *ctime_result = (const char *) ctime (&when);
37433965Sjdp
37533965Sjdp	  /* POSIX format:  skip weekday and seconds from ctime output.  */
37633965Sjdp	  sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
37733965Sjdp
37833965Sjdp	  mode_string (buf.st_mode, modebuf);
37933965Sjdp	  modebuf[10] = '\0';
38033965Sjdp	  /* POSIX 1003.2/D11 says to skip first character (entry type).  */
38133965Sjdp	  fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
38233965Sjdp		   (long) buf.st_uid, (long) buf.st_gid,
38333965Sjdp		   (long) buf.st_size, timebuf);
38433965Sjdp	}
38533965Sjdp    }
38633965Sjdp
38733965Sjdp  fprintf (file, "%s\n", bfd_get_filename (abfd));
38833965Sjdp}
38933965Sjdp
390218822Sdim/* Return a path for a new temporary file in the same directory
391218822Sdim   as file PATH.  */
39233965Sjdp
393218822Sdimstatic char *
394218822Sdimtemplate_in_dir (const char *path)
39533965Sjdp{
396218822Sdim#define template "stXXXXXX"
397218822Sdim  const char *slash = strrchr (path, '/');
39833965Sjdp  char *tmpname;
399218822Sdim  size_t len;
40033965Sjdp
40161843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM
40261843Sobrien  {
40361843Sobrien    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
404218822Sdim    char *bslash = strrchr (path, '\\');
405218822Sdim
40677298Sobrien    if (slash == NULL || (bslash != NULL && bslash > slash))
40761843Sobrien      slash = bslash;
408218822Sdim    if (slash == NULL && path[0] != '\0' && path[1] == ':')
409218822Sdim      slash = path + 1;
41061843Sobrien  }
41138889Sjdp#endif
41238889Sjdp
41333965Sjdp  if (slash != (char *) NULL)
41433965Sjdp    {
415218822Sdim      len = slash - path;
416218822Sdim      tmpname = xmalloc (len + sizeof (template) + 2);
417218822Sdim      memcpy (tmpname, path, len);
41838889Sjdp
41961843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM
42061843Sobrien      /* If tmpname is "X:", appending a slash will make it a root
42161843Sobrien	 directory on drive X, which is NOT the same as the current
42261843Sobrien	 directory on drive X.  */
423218822Sdim      if (len == 2 && tmpname[1] == ':')
424218822Sdim	tmpname[len++] = '.';
42561843Sobrien#endif
426218822Sdim      tmpname[len++] = '/';
42733965Sjdp    }
42833965Sjdp  else
42933965Sjdp    {
43033965Sjdp      tmpname = xmalloc (sizeof (template));
431218822Sdim      len = 0;
43233965Sjdp    }
433218822Sdim
434218822Sdim  memcpy (tmpname + len, template, sizeof (template));
43533965Sjdp  return tmpname;
436218822Sdim#undef template
43733965Sjdp}
43833965Sjdp
439218822Sdim/* Return the name of a created temporary file in the same directory
440218822Sdim   as FILENAME.  */
441218822Sdim
442218822Sdimchar *
443218822Sdimmake_tempname (char *filename)
444218822Sdim{
445218822Sdim  char *tmpname = template_in_dir (filename);
446218822Sdim  int fd;
447218822Sdim
448218822Sdim#ifdef HAVE_MKSTEMP
449218822Sdim  fd = mkstemp (tmpname);
450218822Sdim#else
451218822Sdim  tmpname = mktemp (tmpname);
452218822Sdim  if (tmpname == NULL)
453218822Sdim    return NULL;
454218822Sdim  fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
455218822Sdim#endif
456218822Sdim  if (fd == -1)
457218822Sdim    return NULL;
458218822Sdim  close (fd);
459218822Sdim  return tmpname;
460218822Sdim}
461218822Sdim
462218822Sdim/* Return the name of a created temporary directory inside the
463218822Sdim   directory containing FILENAME.  */
464218822Sdim
465218822Sdimchar *
466218822Sdimmake_tempdir (char *filename)
467218822Sdim{
468218822Sdim  char *tmpname = template_in_dir (filename);
469218822Sdim
470218822Sdim#ifdef HAVE_MKDTEMP
471218822Sdim  return mkdtemp (tmpname);
472218822Sdim#else
473218822Sdim  tmpname = mktemp (tmpname);
474218822Sdim  if (tmpname == NULL)
475218822Sdim    return NULL;
476218822Sdim#if defined (_WIN32) && !defined (__CYGWIN32__)
477218822Sdim  if (mkdir (tmpname) != 0)
478218822Sdim    return NULL;
479218822Sdim#else
480218822Sdim  if (mkdir (tmpname, 0700) != 0)
481218822Sdim    return NULL;
482218822Sdim#endif
483218822Sdim  return tmpname;
484218822Sdim#endif
485218822Sdim}
486218822Sdim
48733965Sjdp/* Parse a string into a VMA, with a fatal error if it can't be
48833965Sjdp   parsed.  */
48933965Sjdp
49033965Sjdpbfd_vma
491130561Sobrienparse_vma (const char *s, const char *arg)
49233965Sjdp{
49333965Sjdp  bfd_vma ret;
49433965Sjdp  const char *end;
49533965Sjdp
49633965Sjdp  ret = bfd_scan_vma (s, &end, 0);
497104834Sobrien
49833965Sjdp  if (*end != '\0')
49960484Sobrien    fatal (_("%s: bad number: %s"), arg, s);
50060484Sobrien
50133965Sjdp  return ret;
50233965Sjdp}
503130561Sobrien
504130561Sobrien/* Returns the size of the named file.  If the file does not
505130561Sobrien   exist, or if it is not a real file, then a suitable non-fatal
506130561Sobrien   error message is printed and zero is returned.  */
507130561Sobrien
508130561Sobrienoff_t
509130561Sobrienget_file_size (const char * file_name)
510130561Sobrien{
511130561Sobrien  struct stat statbuf;
512130561Sobrien
513130561Sobrien  if (stat (file_name, &statbuf) < 0)
514130561Sobrien    {
515130561Sobrien      if (errno == ENOENT)
516130561Sobrien	non_fatal (_("'%s': No such file"), file_name);
517130561Sobrien      else
518130561Sobrien	non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
519130561Sobrien		   file_name, strerror (errno));
520130561Sobrien    }
521130561Sobrien  else if (! S_ISREG (statbuf.st_mode))
522130561Sobrien    non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
523130561Sobrien  else
524130561Sobrien    return statbuf.st_size;
525130561Sobrien
526130561Sobrien  return 0;
527130561Sobrien}
528218822Sdim
529218822Sdim/* Return the filename in a static buffer.  */
530218822Sdim
531218822Sdimconst char *
532218822Sdimbfd_get_archive_filename (bfd *abfd)
533218822Sdim{
534218822Sdim  static size_t curr = 0;
535218822Sdim  static char *buf;
536218822Sdim  size_t needed;
537218822Sdim
538218822Sdim  assert (abfd != NULL);
539218822Sdim
540218822Sdim  if (!abfd->my_archive)
541218822Sdim    return bfd_get_filename (abfd);
542218822Sdim
543218822Sdim  needed = (strlen (bfd_get_filename (abfd->my_archive))
544218822Sdim	    + strlen (bfd_get_filename (abfd)) + 3);
545218822Sdim  if (needed > curr)
546218822Sdim    {
547218822Sdim      if (curr)
548218822Sdim	free (buf);
549218822Sdim      curr = needed + (needed >> 1);
550218822Sdim      buf = bfd_malloc (curr);
551218822Sdim      /* If we can't malloc, fail safe by returning just the file name.
552218822Sdim	 This function is only used when building error messages.  */
553218822Sdim      if (!buf)
554218822Sdim	{
555218822Sdim	  curr = 0;
556218822Sdim	  return bfd_get_filename (abfd);
557218822Sdim	}
558218822Sdim    }
559218822Sdim  sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
560218822Sdim	   bfd_get_filename (abfd));
561218822Sdim  return buf;
562218822Sdim}
563