/* ldmisc.c
- Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support.
This file is part of GLD, the Gnu Linker.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GLD; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+along with GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
-#define USE_STDARG 1
#else
#include <varargs.h>
-#define USE_STDARG 0
#endif
#include "ld.h"
#include "ldmain.h"
#include "ldfile.h"
-
-#if USE_STDARG
-static void finfo PARAMS ((FILE *, const char *, ...));
-#else
-/* VARARGS*/
-static void finfo ();
-#endif
+static void vfinfo PARAMS ((FILE *, const char *, va_list));
/*
%% literal %
%X no object output, fail return
%V hex bfd_vma
%v hex bfd_vma, no leading zeros
+ %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces
%C clever filename:linenumber with function
%D like %C, but no function name
%G like %D, but only function name
&& bfd_get_symbol_leading_char (output_bfd) == string[0])
++string;
- /* This is a hack for better error reporting on XCOFF. */
- if (string[0] == '.')
+ /* This is a hack for better error reporting on XCOFF, or the MS PE
+ format. Xcoff has a single '.', while the NT PE for PPC has
+ '..'. So we remove all of them. */
+ while (string[0] == '.')
++string;
res = cplus_demangle (string, DMGL_ANSI | DMGL_PARAMS);
while (*fmt != '\0')
{
- while (*fmt != '%' && *fmt != '\0')
+ while (*fmt != '%' && *fmt != '\0')
{
putc (*fmt, fp);
fmt++;
}
- if (*fmt == '%')
+ if (*fmt == '%')
{
- fmt ++;
- switch (*fmt++)
+ fmt++;
+ switch (*fmt++)
{
default:
- fprintf (fp,"%%%c", fmt[-1]);
+ fprintf (fp, "%%%c", fmt[-1]);
break;
case '%':
}
break;
+ case 'W':
+ /* hex bfd_vma with 0x with no leading zeroes taking up
+ 8 spaces. */
+ {
+ char buf[100];
+ bfd_vma value;
+ char *p;
+ int len;
+
+ value = va_arg (arg, bfd_vma);
+ sprintf_vma (buf, value);
+ for (p = buf; *p == '0'; ++p)
+ ;
+ if (*p == '\0')
+ --p;
+ len = strlen (p);
+ while (len < 8)
+ {
+ putc (' ', fp);
+ ++len;
+ }
+ fprintf (fp, "0x%s", p);
+ }
+ break;
+
case 'T':
/* Symbol name. */
{
const char *name = va_arg (arg, const char *);
- if (name == (const char *) NULL)
- fprintf (fp, "no symbol");
+ if (name == (const char *) NULL || *name == 0)
+ fprintf (fp, _("no symbol"));
+ else if (! demangling)
+ fprintf (fp, "%s", name);
else
{
char *demangled;
case 'B':
/* filename from a bfd */
- {
+ {
bfd *abfd = va_arg (arg, bfd *);
if (abfd->my_archive)
fprintf (fp, "%s(%s)", abfd->my_archive->filename,
break;
case 'F':
- /* error is fatal */
+ /* Error is fatal. */
fatal = true;
break;
case 'P':
- /* print program name */
+ /* Print program name. */
fprintf (fp, "%s", program_name);
break;
case 'E':
/* current bfd error or errno */
- fprintf (fp, bfd_errmsg (bfd_get_error ()));
+ fprintf (fp, "%s", bfd_errmsg (bfd_get_error ()));
break;
case 'I':
break;
case 'S':
- /* print script file and linenumber */
+ /* 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);
+ fprintf (fp, _("built in linker script:%u"), lineno);
break;
case 'R':
- /* Print all that's interesting about a relent */
+ /* Print all that's interesting about a relent. */
{
arelent *relent = va_arg (arg, arelent *);
-
- finfo (fp, "%s+0x%v (type %s)",
- (*(relent->sym_ptr_ptr))->name,
- relent->addend,
- relent->howto->name);
+
+ lfinfo (fp, "%s+0x%v (type %s)",
+ (*(relent->sym_ptr_ptr))->name,
+ relent->addend,
+ relent->howto->name);
}
break;
-
+
case 'C':
case 'D':
case 'G':
symsize = bfd_get_symtab_upper_bound (abfd);
if (symsize < 0)
- einfo ("%B%F: could not read symbols\n", abfd);
+ 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);
+ einfo (_("%B%F: could not read symbols\n"), abfd);
if (entry != (lang_input_statement_type *) NULL)
{
entry->asymbols = asymbols;
{
if (functionname != NULL && fmt[-1] == 'G')
{
- finfo (fp, "%B:", abfd);
+ lfinfo (fp, "%B:", abfd);
if (filename != NULL
&& strcmp (filename, bfd_get_filename (abfd)) != 0)
fprintf (fp, "%s:", filename);
- finfo (fp, "%T", functionname);
+ lfinfo (fp, "%T", functionname);
}
else if (functionname != NULL && fmt[-1] == 'C')
{
/* We use abfd->filename in this initial line,
in case filename is a .h file or something
similarly unhelpful. */
- finfo (fp, "%B: In function `%T':\n",
- abfd, functionname);
+ lfinfo (fp, _("%B: In function `%T':\n"),
+ abfd, functionname);
last_bfd = abfd;
if (last_file != NULL)
free (last_file);
- last_file = buystring (filename);
+ last_file = xstrdup (filename);
if (last_function != NULL)
free (last_function);
- last_function = buystring (functionname);
+ last_function = xstrdup (functionname);
}
discard_last = false;
if (linenumber != 0)
fprintf (fp, "%s:%u", filename, linenumber);
else
- finfo (fp, "%s(%s+0x%v)", filename, section->name,
- offset);
+ lfinfo (fp, "%s(%s+0x%v)", filename, section->name,
+ offset);
}
else if (filename == NULL
|| strcmp (filename, abfd->filename) == 0)
{
- finfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
+ lfinfo (fp, "%B(%s+0x%v)", abfd, section->name,
+ offset);
if (linenumber != 0)
- finfo (fp, ":%u", linenumber);
+ lfinfo (fp, ":%u", linenumber);
}
- else if (linenumber != 0)
- finfo (fp, "%B:%s:%u", abfd, filename, linenumber);
+ else if (linenumber != 0)
+ lfinfo (fp, "%B:%s:%u", abfd, filename, linenumber);
else
- finfo (fp, "%B(%s+0x%v):%s", abfd, section->name, offset,
- filename);
+ lfinfo (fp, "%B(%s+0x%v):%s", abfd, section->name,
+ offset, filename);
}
else
- finfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
+ lfinfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
if (discard_last)
{
}
}
break;
-
+
case 's':
/* arbitrary string, like printf */
fprintf (fp, "%s", va_arg (arg, char *));
}
}
- if (fatal == true)
- xexit(1);
+ if (config.fatal_warnings)
+ config.make_executable = false;
+
+ if (fatal == true)
+ xexit (1);
}
-/* Format info message and print on stdout. */
+/* Format info message and print on stdout. */
/* (You would think this should be called just "info", but then you
would hosed by LynxOS, which defines that name in its libc.) */
void
-#if USE_STDARG
-info_msg (const char *fmt, ...)
-#else
-info_msg (va_alist)
- va_dcl
-#endif
+info_msg VPARAMS ((const char *fmt, ...))
{
- va_list arg;
-
-#if ! USE_STDARG
- const char *fmt;
-
- va_start (arg);
- fmt = va_arg (arg, const char *);
-#else
- va_start (arg, fmt);
-#endif
+ VA_OPEN (arg, fmt);
+ VA_FIXEDARG (arg, const char *, fmt);
vfinfo (stdout, fmt, arg);
- va_end (arg);
+ VA_CLOSE (arg);
}
-/* ('e' for error.) Format info message and print on stderr. */
+/* ('e' for error.) Format info message and print on stderr. */
void
-#if USE_STDARG
-einfo (const char *fmt, ...)
-#else
-einfo (va_alist)
- va_dcl
-#endif
+einfo VPARAMS ((const char *fmt, ...))
{
- va_list arg;
-
-#if ! USE_STDARG
- const char *fmt;
-
- va_start (arg);
- fmt = va_arg (arg, const char *);
-#else
- va_start (arg, fmt);
-#endif
+ VA_OPEN (arg, fmt);
+ VA_FIXEDARG (arg, const char *, fmt);
vfinfo (stderr, fmt, arg);
- va_end (arg);
+ VA_CLOSE (arg);
}
-void
+void
info_assert (file, line)
const char *file;
unsigned int line;
{
- einfo ("%F%P: internal error %s %d\n", file, line);
-}
-
-char *
-buystring (x)
- CONST char *CONST x;
-{
- size_t l = strlen(x)+1;
- char *r = xmalloc(l);
- memcpy(r, x,l);
- return r;
+ einfo (_("%F%P: internal error %s %d\n"), file, line);
}
-/* ('m' for map) Format info message and print on map. */
+/* ('m' for map) Format info message and print on map. */
void
-#if USE_STDARG
-minfo (const char *fmt, ...)
-#else
-minfo (va_alist)
- va_dcl
-#endif
+minfo VPARAMS ((const char *fmt, ...))
{
- va_list arg;
-
-#if ! USE_STDARG
- const char *fmt;
- va_start (arg);
- fmt = va_arg (arg, const char *);
-#else
- va_start (arg, fmt);
-#endif
+ VA_OPEN (arg, fmt);
+ VA_FIXEDARG (arg, const char *, fmt);
vfinfo (config.map_file, fmt, arg);
- va_end (arg);
+ VA_CLOSE (arg);
}
-static void
-#if USE_STDARG
-finfo (FILE *file, const char *fmt, ...)
-#else
-finfo (va_alist)
- va_dcl
-#endif
+void
+lfinfo VPARAMS ((FILE *file, const char *fmt, ...))
{
- va_list arg;
-
-#if ! USE_STDARG
- FILE *file;
- const char *fmt;
-
- va_start (arg);
- file = va_arg (arg, FILE *);
- fmt = va_arg (arg, const char *);
-#else
- va_start (arg, fmt);
-#endif
+ VA_OPEN (arg, fmt);
+ VA_FIXEDARG (arg, FILE *, file);
+ VA_FIXEDARG (arg, const char *, fmt);
vfinfo (file, fmt, arg);
- va_end (arg);
+ VA_CLOSE (arg);
}
\f
/* Functions to print the link map. */
-void
+void
print_space ()
{
fprintf (config.map_file, " ");
}
-void
+void
print_nl ()
{
fprintf (config.map_file, "\n");
}
-void
-print_address (value)
- bfd_vma value;
+/* A more or less friendly abort message. In ld.h abort is defined to
+ call this function. */
+
+void
+ld_abort (file, line, fn)
+ const char *file;
+ int line;
+ const char *fn;
{
- fprintf_vma (config.map_file, value);
+ if (fn != NULL)
+ einfo (_("%P: internal error: aborting at %s line %d in %s\n"),
+ file, line, fn);
+ else
+ einfo (_("%P: internal error: aborting at %s line %d\n"),
+ file, line);
+ einfo (_("%P%F: please report this bug\n"));
+ xexit (1);
}