aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/Makefile.am2
-rw-r--r--bfd/Makefile.in2
-rw-r--r--bfd/bfd-in2.h7
-rw-r--r--bfd/bfd.c176
-rw-r--r--bfd/elfcode.h13
-rw-r--r--bfd/format.c85
-rw-r--r--bfd/libbfd.h11
-rw-r--r--bfd/peicode.h13
-rw-r--r--bfd/targets.c45
9 files changed, 279 insertions, 75 deletions
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index da55a0b..6d8722e 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -932,7 +932,7 @@ BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c \
syms.c bfd.c archive.c corefile.c targets.c format.c \
linker.c simple.c compress.c
BFD64_H_FILES = archive64.c
-LIBBFD_H_FILES = libbfd-in.h libbfd.c bfdio.c bfdwin.c \
+LIBBFD_H_FILES = libbfd-in.h libbfd.c bfd.c bfdio.c bfdwin.c \
cache.c reloc.c section.c targets.c archures.c linker.c
LIBCOFF_H_FILES = libcoff-in.h coffcode.h
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 60252f2..5cd2f37 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1226,7 +1226,7 @@ BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c \
linker.c simple.c compress.c
BFD64_H_FILES = archive64.c
-LIBBFD_H_FILES = libbfd-in.h libbfd.c bfdio.c bfdwin.c \
+LIBBFD_H_FILES = libbfd-in.h libbfd.c bfd.c bfdio.c bfdwin.c \
cache.c reloc.c section.c targets.c archures.c linker.c
LIBCOFF_H_FILES = libcoff-in.h coffcode.h
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index d407e59..297ce12 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7816,6 +7816,13 @@ bfd_keep_unused_section_symbols (const bfd *abfd)
return abfd->xvec->keep_unused_section_symbols;
}
+/* Cached _bfd_check_format messages are put in this. */
+struct per_xvec_message
+{
+ struct per_xvec_message *next;
+ char message[];
+};
+
bool bfd_set_default_target (const char *name);
const bfd_target *bfd_find_target (const char *target_name, bfd *abfd);
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 8d9c9c6..12cb4bc 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -890,6 +890,10 @@ union _bfd_doprnt_args
} type;
};
+/* Maximum number of _bfd_error_handler args. Don't increase this
+ without changing the code handling positional parameters. */
+#define MAX_ARGS 9
+
/* This macro and _bfd_doprnt taken from libiberty _doprnt.c, tidied a
little and extended to handle '%pA', '%pB' and positional parameters. */
@@ -897,11 +901,14 @@ union _bfd_doprnt_args
do \
{ \
TYPE value = (TYPE) args[arg_no].FIELD; \
- result = fprintf (stream, specifier, value); \
+ result = print (stream, specifier, value); \
} while (0)
+typedef int (*print_func) (void *, const char *, ...);
+
static int
-_bfd_doprnt (FILE *stream, const char *format, union _bfd_doprnt_args *args)
+_bfd_doprnt (print_func print, void *stream, const char *format,
+ union _bfd_doprnt_args *args)
{
const char *ptr = format;
char specifier[128];
@@ -917,9 +924,9 @@ _bfd_doprnt (FILE *stream, const char *format, union _bfd_doprnt_args *args)
/* While we have regular characters, print them. */
char *end = strchr (ptr, '%');
if (end != NULL)
- result = fprintf (stream, "%.*s", (int) (end - ptr), ptr);
+ result = print (stream, "%.*s", (int) (end - ptr), ptr);
else
- result = fprintf (stream, "%s", ptr);
+ result = print (stream, "%s", ptr);
ptr += result;
}
else if (ptr[1] == '%')
@@ -1103,9 +1110,9 @@ _bfd_doprnt (FILE *stream, const char *format, union _bfd_doprnt_args *args)
sec)) != NULL)
group = ci->name;
if (group != NULL)
- result = fprintf (stream, "%s[%s]", sec->name, group);
+ result = print (stream, "%s[%s]", sec->name, group);
else
- result = fprintf (stream, "%s", sec->name);
+ result = print (stream, "%s", sec->name);
}
else if (*ptr == 'B')
{
@@ -1119,11 +1126,11 @@ _bfd_doprnt (FILE *stream, const char *format, union _bfd_doprnt_args *args)
abort ();
else if (abfd->my_archive
&& !bfd_is_thin_archive (abfd->my_archive))
- result = fprintf (stream, "%s(%s)",
- bfd_get_filename (abfd->my_archive),
- bfd_get_filename (abfd));
+ result = print (stream, "%s(%s)",
+ bfd_get_filename (abfd->my_archive),
+ bfd_get_filename (abfd));
else
- result = fprintf (stream, "%s", bfd_get_filename (abfd));
+ result = print (stream, "%s", bfd_get_filename (abfd));
}
else
PRINT_TYPE (void *, p);
@@ -1144,11 +1151,14 @@ _bfd_doprnt (FILE *stream, const char *format, union _bfd_doprnt_args *args)
/* First pass over FORMAT to gather ARGS. Returns number of args. */
static unsigned int
-_bfd_doprnt_scan (const char *format, union _bfd_doprnt_args *args)
+_bfd_doprnt_scan (const char *format, va_list ap, union _bfd_doprnt_args *args)
{
const char *ptr = format;
unsigned int arg_count = 0;
+ for (unsigned int i = 0; i < MAX_ARGS; i++)
+ args[i].type = Bad;
+
while (*ptr != '\0')
{
if (*ptr != '%')
@@ -1190,7 +1200,7 @@ _bfd_doprnt_scan (const char *format, union _bfd_doprnt_args *args)
arg_index = *ptr - '1';
ptr += 2;
}
- if (arg_index >= 9)
+ if (arg_index >= MAX_ARGS)
abort ();
args[arg_index].type = Int;
arg_count++;
@@ -1215,7 +1225,7 @@ _bfd_doprnt_scan (const char *format, union _bfd_doprnt_args *args)
arg_index = *ptr - '1';
ptr += 2;
}
- if (arg_index >= 9)
+ if (arg_index >= MAX_ARGS)
abort ();
args[arg_index].type = Int;
arg_count++;
@@ -1303,27 +1313,14 @@ _bfd_doprnt_scan (const char *format, union _bfd_doprnt_args *args)
abort();
}
- if (arg_no >= 9)
+ if (arg_no >= MAX_ARGS)
abort ();
args[arg_no].type = arg_type;
arg_count++;
}
}
- return arg_count;
-}
-
-static void
-error_handler_internal (const char *fmt, va_list ap)
-{
- unsigned int i, arg_count;
- union _bfd_doprnt_args args[9];
-
- for (i = 0; i < sizeof (args) / sizeof (args[0]); i++)
- args[i].type = Bad;
-
- arg_count = _bfd_doprnt_scan (fmt, args);
- for (i = 0; i < arg_count; i++)
+ for (unsigned int i = 0; i < arg_count; i++)
{
switch (args[i].type)
{
@@ -1350,15 +1347,24 @@ error_handler_internal (const char *fmt, va_list ap)
}
}
+ return arg_count;
+}
+
+/* The standard error handler that prints to stderr. */
+
+static void
+error_handler_fprintf (const char *fmt, va_list ap)
+{
+ union _bfd_doprnt_args args[MAX_ARGS];
+
+ _bfd_doprnt_scan (fmt, ap, args);
+
/* PR 4992: Don't interrupt output being sent to stdout. */
fflush (stdout);
- if (_bfd_error_program_name != NULL)
- fprintf (stderr, "%s: ", _bfd_error_program_name);
- else
- fprintf (stderr, "BFD: ");
+ fprintf (stderr, "%s: ", _bfd_get_error_program_name ());
- _bfd_doprnt (stderr, fmt, args);
+ _bfd_doprnt ((print_func) fprintf, stderr, fmt, args);
/* On AIX, putc is implemented as a macro that triggers a -Wunused-value
warning, so use the fputc function to avoid it. */
@@ -1366,13 +1372,77 @@ error_handler_internal (const char *fmt, va_list ap)
fflush (stderr);
}
+/* Control printing to a string buffer. */
+struct buf_stream
+{
+ char *ptr;
+ int left;
+};
+
+/* An fprintf like function that instead prints to a string buffer. */
+
+static int
+err_sprintf (void *stream, const char *fmt, ...)
+{
+ struct buf_stream *s = stream;
+ va_list ap;
+
+ va_start (ap, fmt);
+ int total = vsnprintf (s->ptr, s->left, fmt, ap);
+ va_end (ap);
+ if (total < 0)
+ ;
+ else if (total > s->left)
+ {
+ s->ptr += s->left;
+ s->left = 0;
+ }
+ else
+ {
+ s->ptr += total;
+ s->left -= total;
+ }
+ return total;
+}
+
+/* Communicate the bfd processed by bfd_check_format_matches to the
+ error handling function error_handler_sprintf. */
+
+static bfd *error_handler_bfd;
+
+/* An error handler that prints to a string, then dups that string to
+ a per-xvec cache. */
+
+static void
+error_handler_sprintf (const char *fmt, va_list ap)
+{
+ union _bfd_doprnt_args args[MAX_ARGS];
+ char error_buf[1024];
+ struct buf_stream error_stream;
+
+ _bfd_doprnt_scan (fmt, ap, args);
+
+ error_stream.ptr = error_buf;
+ error_stream.left = sizeof (error_buf);
+ _bfd_doprnt (err_sprintf, &error_stream, fmt, args);
+
+ size_t len = error_stream.ptr - error_buf;
+ struct per_xvec_message **warn
+ = _bfd_per_xvec_warn (error_handler_bfd->xvec, len + 1);
+ if (*warn)
+ {
+ memcpy ((*warn)->message, error_buf, len);
+ (*warn)->message[len] = 0;
+ }
+}
+
/* This is a function pointer to the routine which should handle BFD
error messages. It is called when a BFD routine encounters an
error for which it wants to print a message. Going through a
function pointer permits a program linked against BFD to intercept
the messages and deal with them itself. */
-static bfd_error_handler_type _bfd_error_internal = error_handler_internal;
+static bfd_error_handler_type _bfd_error_internal = error_handler_fprintf;
/*
FUNCTION
@@ -1427,6 +1497,25 @@ bfd_set_error_handler (bfd_error_handler_type pnew)
}
/*
+INTERNAL_FUNCTION
+ _bfd_set_error_handler_caching
+
+SYNOPSIS
+ bfd_error_handler_type _bfd_set_error_handler_caching (bfd *);
+
+DESCRIPTION
+ Set the BFD error handler function to one that stores messages
+ to the per_xvec_warn array. Returns the previous function.
+*/
+
+bfd_error_handler_type
+_bfd_set_error_handler_caching (bfd *abfd)
+{
+ error_handler_bfd = abfd;
+ return bfd_set_error_handler (error_handler_sprintf);
+}
+
+/*
FUNCTION
bfd_set_error_program_name
@@ -1447,6 +1536,25 @@ bfd_set_error_program_name (const char *name)
}
/*
+INTERNAL_FUNCTION
+ _bfd_get_error_program_name
+
+SYNOPSIS
+ const char *_bfd_get_error_program_name (void);
+
+DESCRIPTION
+ Get the program name used when printing a BFD error.
+*/
+
+const char *
+_bfd_get_error_program_name (void)
+{
+ if (_bfd_error_program_name != NULL)
+ return _bfd_error_program_name;
+ return "BFD";
+}
+
+/*
SUBSECTION
BFD assert handler
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 1392240..7a4de82 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -326,8 +326,8 @@ elf_swap_shdr_in (bfd *abfd,
|| dst->sh_size > filesize - dst->sh_offset)
&& !abfd->read_only)
{
- const char **warn = _bfd_per_xvec_warn (abfd->xvec);
- *warn = _("warning: %pB has a section extending past end of file");
+ _bfd_error_handler (_("warning: %pB has a section "
+ "extending past end of file"), abfd);
abfd->read_only = 1;
}
}
@@ -773,8 +773,8 @@ elf_object_p (bfd *abfd)
i_ehdrp->e_shstrndx = SHN_UNDEF;
if (!abfd->read_only)
{
- const char **warn = _bfd_per_xvec_warn (abfd->xvec);
- *warn = _("warning: %pB has a corrupt string table index");
+ _bfd_error_handler
+ (_("warning: %pB has a corrupt string table index"), abfd);
abfd->read_only = 1;
}
}
@@ -821,9 +821,8 @@ elf_object_p (bfd *abfd)
i_phdr->p_align &= -i_phdr->p_align;
if (!abfd->read_only)
{
- const char **warn = _bfd_per_xvec_warn (abfd->xvec);
- *warn = _("warning: %pB has a program header "
- "with invalid alignment");
+ _bfd_error_handler (_("warning: %pB has a program header "
+ "with invalid alignment"), abfd);
abfd->read_only = 1;
}
}
diff --git a/bfd/format.c b/bfd/format.c
index 7e2813c..97fba30 100644
--- a/bfd/format.c
+++ b/bfd/format.c
@@ -203,10 +203,36 @@ bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve)
}
static void
-clear_warnmsg (const bfd_target *targ)
+print_warnmsg (struct per_xvec_message **list)
+{
+ fflush (stdout);
+ fprintf (stderr, "%s: ", _bfd_get_error_program_name ());
+
+ for (struct per_xvec_message *warn = *list; warn; warn = warn->next)
+ {
+ fputs (warn->message, stderr);
+ fputc ('\n', stderr);
+ }
+ fflush (stderr);
+}
+
+static void
+clear_warnmsg (struct per_xvec_message **list)
+{
+ struct per_xvec_message *warn = *list;
+ while (warn)
+ {
+ struct per_xvec_message *next = warn->next;
+ free (warn);
+ warn = next;
+ }
+ *list = NULL;
+}
+
+static void
+null_error_handler (const char *fmt ATTRIBUTE_UNUSED,
+ va_list ap ATTRIBUTE_UNUSED)
{
- const char **warn = _bfd_per_xvec_warn (targ);
- *warn = NULL;
}
/*
@@ -244,6 +270,8 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
unsigned int initial_section_id = _bfd_section_id;
struct bfd_preserve preserve, preserve_match;
bfd_cleanup cleanup = NULL;
+ bfd_error_handler_type orig_error_handler;
+ static int in_check_format;
if (matching != NULL)
*matching = NULL;
@@ -272,6 +300,14 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
abfd->format = format;
save_targ = abfd->xvec;
+ /* Don't report errors on recursive calls checking the first element
+ of an archive. */
+ if (in_check_format)
+ orig_error_handler = bfd_set_error_handler (null_error_handler);
+ else
+ orig_error_handler = _bfd_set_error_handler_caching (abfd);
+ ++in_check_format;
+
preserve_match.marker = NULL;
if (!bfd_preserve_save (abfd, &preserve, NULL))
goto err_ret;
@@ -282,7 +318,6 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) /* rewind! */
goto err_ret;
- clear_warnmsg (abfd->xvec);
cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
if (cleanup)
@@ -349,7 +384,6 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
goto err_ret;
- clear_warnmsg (abfd->xvec);
cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
if (cleanup)
{
@@ -514,13 +548,15 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
if (preserve_match.marker != NULL)
bfd_preserve_finish (abfd, &preserve_match);
bfd_preserve_finish (abfd, &preserve);
+ bfd_set_error_handler (orig_error_handler);
- if (!abfd->my_archive)
- {
- const char **warn = _bfd_per_xvec_warn (abfd->xvec);
- if (*warn)
- _bfd_error_handler (*warn, abfd);
- }
+ struct per_xvec_message **list = _bfd_per_xvec_warn (abfd->xvec, 0);
+ if (*list)
+ print_warnmsg (list);
+ list = _bfd_per_xvec_warn (NULL, 0);
+ for (size_t i = 0; i < _bfd_target_vector_entries + 1; i++)
+ clear_warnmsg (list++);
+ --in_check_format;
/* File position has moved, BTW. */
return true;
@@ -536,10 +572,7 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
abfd->xvec = save_targ;
abfd->format = bfd_unknown;
free (matching_vector);
- if (preserve_match.marker != NULL)
- bfd_preserve_finish (abfd, &preserve_match);
- bfd_preserve_restore (abfd, &preserve);
- return false;
+ goto out;
}
/* Restore original target type and format. */
@@ -563,9 +596,31 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
free (matching_vector);
if (cleanup)
cleanup (abfd);
+ out:
if (preserve_match.marker != NULL)
bfd_preserve_finish (abfd, &preserve_match);
bfd_preserve_restore (abfd, &preserve);
+ bfd_set_error_handler (orig_error_handler);
+ struct per_xvec_message **list = _bfd_per_xvec_warn (NULL, 0);
+ struct per_xvec_message **one = NULL;
+ for (size_t i = 0; i < _bfd_target_vector_entries + 1; i++)
+ {
+ if (list[i])
+ {
+ if (!one)
+ one = list + i;
+ else
+ {
+ one = NULL;
+ break;
+ }
+ }
+ }
+ if (one)
+ print_warnmsg (one);
+ for (size_t i = 0; i < _bfd_target_vector_entries + 1; i++)
+ clear_warnmsg (list++);
+ --in_check_format;
return false;
}
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 2dec810..cba6d42 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1,6 +1,6 @@
/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
- generated from "libbfd-in.h", "libbfd.c", "bfdio.c", "bfdwin.c",
- "cache.c", "reloc.c", "section.c", "targets.c", "archures.c"
+ generated from "libbfd-in.h", "libbfd.c", "bfd.c", "bfdio.c",
+ "bfdwin.c", "cache.c", "reloc.c", "section.c", "targets.c", "archures.c"
and "linker.c".
Run "make headers" in your build bfd/ to regenerate. */
@@ -989,6 +989,11 @@ bool bfd_write_bigendian_4byte_int (bfd *, unsigned int);
unsigned int bfd_log2 (bfd_vma x);
+/* Extracted from bfd.c. */
+bfd_error_handler_type _bfd_set_error_handler_caching (bfd *);
+
+const char *_bfd_get_error_program_name (void);
+
/* Extracted from bfdio.c. */
struct bfd_iovec
{
@@ -3554,7 +3559,7 @@ bool _bfd_unrecognized_reloc
bool _bfd_section_size_insane (bfd *abfd, asection *sec);
/* Extracted from targets.c. */
-const char **_bfd_per_xvec_warn (const bfd_target *);
+struct per_xvec_message **_bfd_per_xvec_warn (const bfd_target *, size_t);
/* Extracted from archures.c. */
extern const bfd_arch_info_type bfd_default_arch_struct;
diff --git a/bfd/peicode.h b/bfd/peicode.h
index f7ba24a..6462b8e 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -1527,8 +1527,8 @@ pe_bfd_object_p (bfd * abfd)
if ((a->SectionAlignment & -a->SectionAlignment) != a->SectionAlignment
|| a->SectionAlignment >= 0x80000000)
{
- const char **warn = _bfd_per_xvec_warn (abfd->xvec);
- *warn = _("%pB: adjusting invalid SectionAlignment");
+ _bfd_error_handler (_("%pB: adjusting invalid SectionAlignment"),
+ abfd);
a->SectionAlignment &= -a->SectionAlignment;
if (a->SectionAlignment >= 0x80000000)
a->SectionAlignment = 0x40000000;
@@ -1537,18 +1537,15 @@ pe_bfd_object_p (bfd * abfd)
if ((a->FileAlignment & -a->FileAlignment) != a->FileAlignment
|| a->FileAlignment > a->SectionAlignment)
{
- const char **warn = _bfd_per_xvec_warn (abfd->xvec);
- *warn = _("%pB: adjusting invalid FileAlignment");
+ _bfd_error_handler (_("%pB: adjusting invalid FileAlignment"),
+ abfd);
a->FileAlignment &= -a->FileAlignment;
if (a->FileAlignment > a->SectionAlignment)
a->FileAlignment = a->SectionAlignment;
}
if (a->NumberOfRvaAndSizes > IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
- {
- const char **warn = _bfd_per_xvec_warn (abfd->xvec);
- *warn = _("%pB: invalid NumberOfRvaAndSizes");
- }
+ _bfd_error_handler (_("%pB: invalid NumberOfRvaAndSizes"), abfd);
}
result = coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
diff --git a/bfd/targets.c b/bfd/targets.c
index 0bb85b6..cf928a5 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -1460,7 +1460,8 @@ const bfd_target *const *const bfd_associated_vector = _bfd_associated_vector;
const size_t _bfd_target_vector_entries = ARRAY_SIZE (_bfd_target_vector);
/* A place to stash a warning from _bfd_check_format. */
-static const char *per_xvec_warn[ARRAY_SIZE (_bfd_target_vector) + 1];
+static struct per_xvec_message *per_xvec_warn[ARRAY_SIZE (_bfd_target_vector)
+ + 1];
/* This array maps configuration triplets onto BFD vectors. */
@@ -1481,26 +1482,58 @@ static const struct targmatch bfd_target_match[] = {
};
/*
+CODE_FRAGMENT
+.{* Cached _bfd_check_format messages are put in this. *}
+.struct per_xvec_message
+.{
+. struct per_xvec_message *next;
+. char message[];
+.};
+.
INTERNAL_FUNCTION
_bfd_per_xvec_warn
SYNOPSIS
- const char **_bfd_per_xvec_warn (const bfd_target *);
+ struct per_xvec_message **_bfd_per_xvec_warn (const bfd_target *, size_t);
DESCRIPTION
Return a location for the given target xvec to use for
- warnings specific to that target.
+ warnings specific to that target. If TARG is NULL, returns
+ the array of per_xvec_message pointers, otherwise if ALLOC is
+ zero, returns a pointer to a pointer to the list of messages
+ for TARG, otherwise (both TARG and ALLOC non-zero), allocates
+ a new per_xvec_message with space for a string of ALLOC
+ bytes and returns a pointer to a pointer to it. May return a
+ pointer to a NULL pointer on allocation failure.
*/
-const char **
-_bfd_per_xvec_warn (const bfd_target *targ)
+struct per_xvec_message **
+_bfd_per_xvec_warn (const bfd_target *targ, size_t alloc)
{
size_t idx;
+ if (!targ)
+ return per_xvec_warn;
for (idx = 0; idx < ARRAY_SIZE (_bfd_target_vector); idx++)
if (_bfd_target_vector[idx] == targ)
break;
- return per_xvec_warn + idx;
+ struct per_xvec_message **m = per_xvec_warn + idx;
+ if (!alloc)
+ return m;
+ int count = 0;
+ while (*m)
+ {
+ m = &(*m)->next;
+ count++;
+ }
+ /* Anti-fuzzer measure. Don't cache more than 5 messages. */
+ if (count < 5)
+ {
+ *m = bfd_malloc (sizeof (**m) + alloc);
+ if (*m != NULL)
+ (*m)->next = NULL;
+ }
+ return m;
}
/* Find a target vector, given a name or configuration triplet. */