+2006-10-30 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (bfd_error_type): Add bfd_error_on_input.
+ (input_bfd, input_error): New static vars.
+ (bfd_set_error): Handle bfd_error_on_input.
+ (bfd_errmsg): Likewise.
+ (bfd_perror): Simplify.
+ * archive.c (_bfd_write_archive_contents): Report errors on input.
+
2006-10-30 Alan Modra <amodra@bigpond.net.au>
* elf.c (elfcore_write_note): Pad to 4-byte boundary.
/* BFD back-end for archive files (libraries).
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
if (bfd_write_p (current))
{
bfd_set_error (bfd_error_invalid_operation);
- return FALSE;
+ goto input_err;
}
if (!current->arelt_data)
{
current->arelt_data =
bfd_ar_hdr_from_filesystem (arch, current->filename, current);
if (!current->arelt_data)
- return FALSE;
+ goto input_err;
/* Put in the file name. */
BFD_SEND (arch, _bfd_truncate_arname,
!= sizeof (*hdr))
return FALSE;
if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0)
- return FALSE;
+ goto input_err;
while (remaining)
{
unsigned int amt = DEFAULT_BUFFERSIZE;
if (bfd_bread (buffer, amt, current) != amt)
{
if (bfd_get_error () != bfd_error_system_call)
- bfd_set_error (bfd_error_malformed_archive);
- return FALSE;
+ bfd_set_error (bfd_error_file_truncated);
+ goto input_err;
}
if (bfd_bwrite (buffer, amt, arch) != amt)
return FALSE;
}
return TRUE;
+
+ input_err:
+ bfd_set_error (bfd_error_on_input, current, bfd_get_error ());
+ return FALSE;
}
\f
/* Note that the namidx for the first symbol is 0. */
. bfd_error_bad_value,
. bfd_error_file_truncated,
. bfd_error_file_too_big,
+. bfd_error_on_input,
. bfd_error_invalid_error_code
.}
.bfd_error_type;
*/
static bfd_error_type bfd_error = bfd_error_no_error;
+static bfd *input_bfd = NULL;
+static bfd_error_type input_error = bfd_error_no_error;
const char *const bfd_errmsgs[] =
{
N_("Bad value"),
N_("File truncated"),
N_("File too big"),
+ N_("Error reading %s: %s"),
N_("#<Invalid error code>")
};
bfd_set_error
SYNOPSIS
- void bfd_set_error (bfd_error_type error_tag);
+ void bfd_set_error (bfd_error_type error_tag, ...);
DESCRIPTION
Set the BFD error condition to be @var{error_tag}.
+ If @var{error_tag} is bfd_error_on_input, then this function
+ takes two more parameters, the input bfd where the error
+ occurred, and the bfd_error_type error.
*/
void
-bfd_set_error (bfd_error_type error_tag)
+bfd_set_error (bfd_error_type error_tag, ...)
{
bfd_error = error_tag;
+ if (error_tag == bfd_error_on_input)
+ {
+ /* This is an error that occurred during bfd_close when
+ writing an archive, but on one of the input files. */
+ va_list ap;
+
+ va_start (ap, error_tag);
+ input_bfd = va_arg (ap, bfd *);
+ input_error = va_arg (ap, int);
+ if (input_error >= bfd_error_on_input)
+ abort ();
+ va_end (ap);
+ }
}
/*
#ifndef errno
extern int errno;
#endif
+ if (error_tag == bfd_error_on_input)
+ {
+ char *buf;
+ const char *msg = bfd_errmsg (input_error);
+
+ if (asprintf (&buf, _(bfd_errmsgs [error_tag]), input_bfd->filename, msg)
+ != -1)
+ return buf;
+
+ /* Ick, what to do on out of memory? */
+ return msg;
+ }
+
if (error_tag == bfd_error_system_call)
return xstrerror (errno);
void
bfd_perror (const char *message)
{
- if (bfd_get_error () == bfd_error_system_call)
- /* Must be a system error then. */
- perror ((char *) message);
+ if (message == NULL || *message == '\0')
+ fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ()));
else
- {
- if (message == NULL || *message == '\0')
- fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ()));
- else
- fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ()));
- }
+ fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ()));
}
/*