+ {
+ char *demangled;
+
+ demangled = demangle (name);
+ fprintf (fp, "%s", demangled);
+ free (demangled);
+ }
+ }
+ break;
+
+ case 'B':
+ /* filename from a bfd */
+ {
+ bfd *abfd = va_arg (arg, bfd *);
+ if (abfd->my_archive)
+ fprintf (fp, "%s(%s)", abfd->my_archive->filename,
+ abfd->filename);
+ else
+ fprintf (fp, "%s", abfd->filename);
+ }
+ break;
+
+ case 'F':
+ /* error is fatal */
+ fatal = true;
+ break;
+
+ case 'P':
+ /* print program name */
+ fprintf (fp, "%s", program_name);
+ break;
+
+ case 'E':
+ /* current bfd error or errno */
+ fprintf (fp, bfd_errmsg (bfd_get_error ()));
+ break;
+
+ case 'I':
+ /* filename from a lang_input_statement_type */
+ {
+ lang_input_statement_type *i;
+
+ i = va_arg (arg, lang_input_statement_type *);
+ if (bfd_my_archive (i->the_bfd) != NULL)
+ fprintf (fp, "(%s)",
+ bfd_get_filename (bfd_my_archive (i->the_bfd)));
+ fprintf (fp, "%s", i->local_sym_name);
+ if (bfd_my_archive (i->the_bfd) == NULL
+ && strcmp (i->local_sym_name, i->filename) != 0)
+ fprintf (fp, " (%s)", i->filename);
+ }
+ break;
+
+ case 'S':
+ /* print script file and linenumber */
+ if (parsing_defsym)
+ fprintf (fp, "--defsym %s", lex_string);
+ else if (ldfile_input_filename != NULL)
+ fprintf (fp, "%s:%u", ldfile_input_filename, lineno);
+ else
+ fprintf (fp, _("built in linker script:%u"), lineno);
+ break;
+
+ case 'R':
+ /* Print all that's interesting about a relent */
+ {
+ arelent *relent = va_arg (arg, arelent *);
+
+ lfinfo (fp, "%s+0x%v (type %s)",
+ (*(relent->sym_ptr_ptr))->name,
+ relent->addend,
+ relent->howto->name);
+ }
+ break;
+
+ case 'C':
+ case 'D':
+ case 'G':
+ /* Clever filename:linenumber with function name if possible,
+ or section name as a last resort. The arguments are a BFD,
+ a section, and an offset. */
+ {
+ static bfd *last_bfd;
+ static char *last_file = NULL;
+ static char *last_function = NULL;
+ bfd *abfd;
+ asection *section;
+ bfd_vma offset;
+ lang_input_statement_type *entry;
+ asymbol **asymbols;
+ const char *filename;
+ const char *functionname;
+ unsigned int linenumber;
+ boolean discard_last;
+
+ abfd = va_arg (arg, bfd *);
+ section = va_arg (arg, asection *);
+ offset = va_arg (arg, bfd_vma);
+
+ entry = (lang_input_statement_type *) abfd->usrdata;
+ if (entry != (lang_input_statement_type *) NULL
+ && entry->asymbols != (asymbol **) NULL)
+ asymbols = entry->asymbols;
+ else
+ {
+ long symsize;
+ long symbol_count;
+
+ symsize = bfd_get_symtab_upper_bound (abfd);
+ if (symsize < 0)
+ einfo (_("%B%F: could not read symbols\n"), abfd);
+ asymbols = (asymbol **) xmalloc (symsize);
+ symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
+ if (symbol_count < 0)
+ einfo (_("%B%F: could not read symbols\n"), abfd);
+ if (entry != (lang_input_statement_type *) NULL)
+ {
+ entry->asymbols = asymbols;
+ entry->symbol_count = symbol_count;
+ }
+ }
+
+ discard_last = true;
+ if (bfd_find_nearest_line (abfd, section, asymbols, offset,
+ &filename, &functionname,
+ &linenumber))
+ {
+ if (functionname != NULL && fmt[-1] == 'G')
+ {
+ lfinfo (fp, "%B:", abfd);
+ if (filename != NULL
+ && strcmp (filename, bfd_get_filename (abfd)) != 0)
+ fprintf (fp, "%s:", filename);
+ lfinfo (fp, "%T", functionname);
+ }
+ else if (functionname != NULL && fmt[-1] == 'C')
+ {
+ if (filename == (char *) NULL)
+ filename = abfd->filename;
+
+ if (last_bfd == NULL
+ || last_file == NULL
+ || last_function == NULL
+ || last_bfd != abfd
+ || strcmp (last_file, filename) != 0
+ || strcmp (last_function, functionname) != 0)
+ {
+ /* We use abfd->filename in this initial line,
+ in case filename is a .h file or something
+ similarly unhelpful. */
+ lfinfo (fp, _("%B: In function `%T':\n"),
+ abfd, functionname);
+
+ last_bfd = abfd;
+ if (last_file != NULL)
+ free (last_file);
+ last_file = buystring (filename);
+ if (last_function != NULL)
+ free (last_function);
+ last_function = buystring (functionname);
+ }
+ discard_last = false;
+ if (linenumber != 0)
+ fprintf (fp, "%s:%u", filename, linenumber);
+ else
+ lfinfo (fp, "%s(%s+0x%v)", filename, section->name,
+ offset);
+ }
+ else if (filename == NULL
+ || strcmp (filename, abfd->filename) == 0)
+ {
+ lfinfo (fp, "%B(%s+0x%v)", abfd, section->name,
+ offset);
+ if (linenumber != 0)
+ lfinfo (fp, ":%u", linenumber);
+ }
+ else if (linenumber != 0)
+ lfinfo (fp, "%B:%s:%u", abfd, filename, linenumber);
+ else
+ lfinfo (fp, "%B(%s+0x%v):%s", abfd, section->name,
+ offset, filename);
+ }
+ else
+ lfinfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
+
+ if (discard_last)
+ {
+ last_bfd = NULL;
+ if (last_file != NULL)
+ {
+ free (last_file);
+ last_file = NULL;
+ }
+ if (last_function != NULL)
+ {
+ free (last_function);
+ last_function = NULL;
+ }
+ }
+ }
+ break;
+
+ case 's':
+ /* arbitrary string, like printf */
+ fprintf (fp, "%s", va_arg (arg, char *));
+ break;
+
+ case 'd':
+ /* integer, like printf */
+ fprintf (fp, "%d", va_arg (arg, int));
+ break;
+
+ case 'u':
+ /* unsigned integer, like printf */
+ fprintf (fp, "%u", va_arg (arg, unsigned int));
+ break;