175fd0b74Schristos /* ldmisc.c
2*e992f068Schristos Copyright (C) 1991-2022 Free Software Foundation, Inc.
375fd0b74Schristos Written by Steve Chamberlain of Cygnus Support.
475fd0b74Schristos
575fd0b74Schristos This file is part of the GNU Binutils.
675fd0b74Schristos
775fd0b74Schristos This program is free software; you can redistribute it and/or modify
875fd0b74Schristos it under the terms of the GNU General Public License as published by
975fd0b74Schristos the Free Software Foundation; either version 3 of the License, or
1075fd0b74Schristos (at your option) any later version.
1175fd0b74Schristos
1275fd0b74Schristos This program is distributed in the hope that it will be useful,
1375fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1475fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1575fd0b74Schristos GNU General Public License for more details.
1675fd0b74Schristos
1775fd0b74Schristos You should have received a copy of the GNU General Public License
1875fd0b74Schristos along with this program; if not, write to the Free Software
1975fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2075fd0b74Schristos MA 02110-1301, USA. */
2175fd0b74Schristos
2275fd0b74Schristos #include "sysdep.h"
2375fd0b74Schristos #include "bfd.h"
2475fd0b74Schristos #include "bfdlink.h"
2575fd0b74Schristos #include "libiberty.h"
26012573ebSchristos #include "ctf-api.h"
27ede78133Schristos #include "safe-ctype.h"
2875fd0b74Schristos #include "filenames.h"
2975fd0b74Schristos #include "demangle.h"
3075fd0b74Schristos #include <stdarg.h>
3175fd0b74Schristos #include "ld.h"
3275fd0b74Schristos #include "ldmisc.h"
3375fd0b74Schristos #include "ldexp.h"
3475fd0b74Schristos #include "ldlang.h"
3575fd0b74Schristos #include <ldgram.h>
3675fd0b74Schristos #include "ldlex.h"
3775fd0b74Schristos #include "ldmain.h"
3875fd0b74Schristos #include "ldfile.h"
3975fd0b74Schristos
4075fd0b74Schristos /*
4175fd0b74Schristos %% literal %
4275fd0b74Schristos %C clever filename:linenumber with function
4375fd0b74Schristos %D like %C, but no function name
4475fd0b74Schristos %E current bfd error or errno
4575fd0b74Schristos %F error is fatal
4675fd0b74Schristos %G like %D, but only function name
4775fd0b74Schristos %H like %C but in addition emit section+offset
4875fd0b74Schristos %P print program name
4975fd0b74Schristos %V hex bfd_vma
5075fd0b74Schristos %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces
5175fd0b74Schristos %X no object output, fail return
5275fd0b74Schristos %d integer, like printf
5375fd0b74Schristos %ld long, like printf
5475fd0b74Schristos %lu unsigned long, like printf
5575fd0b74Schristos %p native (host) void* pointer, like printf
56ede78133Schristos %pA section name from a section
57ede78133Schristos %pB filename from a bfd
58ede78133Schristos %pI filename from a lang_input_statement_type
59ede78133Schristos %pR info about a relent
60ede78133Schristos %pS print script file and linenumber from etree_type.
61ede78133Schristos %pT symbol name
62*e992f068Schristos %pU print script file without linenumber from etree_type.
6375fd0b74Schristos %s arbitrary string, like printf
6475fd0b74Schristos %u integer, like printf
6575fd0b74Schristos %v hex bfd_vma, no leading zeros
6675fd0b74Schristos */
6775fd0b74Schristos
6875fd0b74Schristos void
vfinfo(FILE * fp,const char * fmt,va_list ap,bool is_warning)69*e992f068Schristos vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
7075fd0b74Schristos {
71*e992f068Schristos bool fatal = false;
72ede78133Schristos const char *scan;
73ede78133Schristos int arg_type;
74ede78133Schristos unsigned int arg_count = 0;
75ede78133Schristos unsigned int arg_no;
76ede78133Schristos union vfinfo_args
77ede78133Schristos {
78ede78133Schristos int i;
79ede78133Schristos long l;
80ede78133Schristos void *p;
81ede78133Schristos bfd_vma v;
82ede78133Schristos struct {
83ede78133Schristos bfd *abfd;
84ede78133Schristos asection *sec;
85ede78133Schristos bfd_vma off;
86ede78133Schristos } reladdr;
87ede78133Schristos enum
88ede78133Schristos {
89ede78133Schristos Bad,
90ede78133Schristos Int,
91ede78133Schristos Long,
92ede78133Schristos Ptr,
93ede78133Schristos Vma,
94ede78133Schristos RelAddr
95ede78133Schristos } type;
96ede78133Schristos } args[9];
9775fd0b74Schristos
98ede78133Schristos for (arg_no = 0; arg_no < sizeof (args) / sizeof (args[0]); arg_no++)
99ede78133Schristos args[arg_no].type = Bad;
100ede78133Schristos
101ede78133Schristos arg_count = 0;
102ede78133Schristos scan = fmt;
103ede78133Schristos while (*scan != '\0')
104ede78133Schristos {
105ede78133Schristos while (*scan != '%' && *scan != '\0')
106ede78133Schristos scan++;
107ede78133Schristos
108ede78133Schristos if (*scan == '%')
109ede78133Schristos {
110ede78133Schristos scan++;
111ede78133Schristos
112ede78133Schristos arg_no = arg_count;
113ede78133Schristos if (*scan != '0' && ISDIGIT (*scan) && scan[1] == '$')
114ede78133Schristos {
115ede78133Schristos arg_no = *scan - '1';
116ede78133Schristos scan += 2;
117ede78133Schristos }
118ede78133Schristos
119ede78133Schristos arg_type = Bad;
120ede78133Schristos switch (*scan++)
121ede78133Schristos {
122ede78133Schristos case '\0':
123ede78133Schristos --scan;
124ede78133Schristos break;
125ede78133Schristos
126ede78133Schristos case 'V':
127ede78133Schristos case 'v':
128ede78133Schristos case 'W':
129ede78133Schristos arg_type = Vma;
130ede78133Schristos break;
131ede78133Schristos
132ede78133Schristos case 's':
133ede78133Schristos arg_type = Ptr;
134ede78133Schristos break;
135ede78133Schristos
136ede78133Schristos case 'p':
137ede78133Schristos if (*scan == 'A' || *scan == 'B' || *scan == 'I'
138ede78133Schristos || *scan == 'R' || *scan == 'S' || *scan == 'T')
139ede78133Schristos scan++;
140ede78133Schristos arg_type = Ptr;
141ede78133Schristos break;
142ede78133Schristos
143ede78133Schristos case 'C':
144ede78133Schristos case 'D':
145ede78133Schristos case 'G':
146ede78133Schristos case 'H':
147ede78133Schristos arg_type = RelAddr;
148ede78133Schristos break;
149ede78133Schristos
150ede78133Schristos case 'd':
151ede78133Schristos case 'u':
152ede78133Schristos arg_type = Int;
153ede78133Schristos break;
154ede78133Schristos
155ede78133Schristos case 'l':
156ede78133Schristos if (*scan == 'd' || *scan == 'u')
157ede78133Schristos {
158ede78133Schristos ++scan;
159ede78133Schristos arg_type = Long;
160ede78133Schristos }
161ede78133Schristos break;
162ede78133Schristos
163ede78133Schristos default:
164ede78133Schristos break;
165ede78133Schristos }
166ede78133Schristos if (arg_type != Bad)
167ede78133Schristos {
168ede78133Schristos if (arg_no >= sizeof (args) / sizeof (args[0]))
169ede78133Schristos abort ();
170ede78133Schristos args[arg_no].type = arg_type;
171ede78133Schristos ++arg_count;
172ede78133Schristos }
173ede78133Schristos }
174ede78133Schristos }
175ede78133Schristos
176ede78133Schristos for (arg_no = 0; arg_no < arg_count; arg_no++)
177ede78133Schristos {
178ede78133Schristos switch (args[arg_no].type)
179ede78133Schristos {
180ede78133Schristos case Int:
181ede78133Schristos args[arg_no].i = va_arg (ap, int);
182ede78133Schristos break;
183ede78133Schristos case Long:
184ede78133Schristos args[arg_no].l = va_arg (ap, long);
185ede78133Schristos break;
186ede78133Schristos case Ptr:
187ede78133Schristos args[arg_no].p = va_arg (ap, void *);
188ede78133Schristos break;
189ede78133Schristos case Vma:
190ede78133Schristos args[arg_no].v = va_arg (ap, bfd_vma);
191ede78133Schristos break;
192ede78133Schristos case RelAddr:
193ede78133Schristos args[arg_no].reladdr.abfd = va_arg (ap, bfd *);
194ede78133Schristos args[arg_no].reladdr.sec = va_arg (ap, asection *);
195ede78133Schristos args[arg_no].reladdr.off = va_arg (ap, bfd_vma);
196ede78133Schristos break;
197ede78133Schristos default:
198ede78133Schristos abort ();
199ede78133Schristos }
200ede78133Schristos }
201ede78133Schristos
202ede78133Schristos arg_count = 0;
20375fd0b74Schristos while (*fmt != '\0')
20475fd0b74Schristos {
20575fd0b74Schristos const char *str = fmt;
20675fd0b74Schristos while (*fmt != '%' && *fmt != '\0')
20775fd0b74Schristos fmt++;
20875fd0b74Schristos if (fmt != str)
20975fd0b74Schristos if (fwrite (str, 1, fmt - str, fp))
21075fd0b74Schristos {
21175fd0b74Schristos /* Ignore. */
21275fd0b74Schristos }
21375fd0b74Schristos
21475fd0b74Schristos if (*fmt == '%')
21575fd0b74Schristos {
21675fd0b74Schristos fmt++;
217ede78133Schristos
218ede78133Schristos arg_no = arg_count;
219ede78133Schristos if (*fmt != '0' && ISDIGIT (*fmt) && fmt[1] == '$')
220ede78133Schristos {
221ede78133Schristos arg_no = *fmt - '1';
222ede78133Schristos fmt += 2;
223ede78133Schristos }
224ede78133Schristos
22575fd0b74Schristos switch (*fmt++)
22675fd0b74Schristos {
227ede78133Schristos case '\0':
228ede78133Schristos --fmt;
229ede78133Schristos /* Fall through. */
230ede78133Schristos
23175fd0b74Schristos case '%':
23275fd0b74Schristos /* literal % */
23375fd0b74Schristos putc ('%', fp);
23475fd0b74Schristos break;
23575fd0b74Schristos
23675fd0b74Schristos case 'X':
23775fd0b74Schristos /* no object output, fail return */
238*e992f068Schristos config.make_executable = false;
23975fd0b74Schristos break;
24075fd0b74Schristos
24175fd0b74Schristos case 'V':
24275fd0b74Schristos /* hex bfd_vma */
24375fd0b74Schristos {
244ede78133Schristos bfd_vma value = args[arg_no].v;
245ede78133Schristos ++arg_count;
24675fd0b74Schristos fprintf_vma (fp, value);
24775fd0b74Schristos }
24875fd0b74Schristos break;
24975fd0b74Schristos
25075fd0b74Schristos case 'v':
25175fd0b74Schristos /* hex bfd_vma, no leading zeros */
25275fd0b74Schristos {
25375fd0b74Schristos char buf[100];
25475fd0b74Schristos char *p = buf;
255ede78133Schristos bfd_vma value = args[arg_no].v;
256ede78133Schristos ++arg_count;
25775fd0b74Schristos sprintf_vma (p, value);
25875fd0b74Schristos while (*p == '0')
25975fd0b74Schristos p++;
26075fd0b74Schristos if (!*p)
26175fd0b74Schristos p--;
26275fd0b74Schristos fputs (p, fp);
26375fd0b74Schristos }
26475fd0b74Schristos break;
26575fd0b74Schristos
26675fd0b74Schristos case 'W':
26775fd0b74Schristos /* hex bfd_vma with 0x with no leading zeroes taking up
26875fd0b74Schristos 8 spaces. */
26975fd0b74Schristos {
27075fd0b74Schristos char buf[100];
27175fd0b74Schristos bfd_vma value;
27275fd0b74Schristos char *p;
27375fd0b74Schristos int len;
27475fd0b74Schristos
275ede78133Schristos value = args[arg_no].v;
276ede78133Schristos ++arg_count;
27775fd0b74Schristos sprintf_vma (buf, value);
27875fd0b74Schristos for (p = buf; *p == '0'; ++p)
27975fd0b74Schristos ;
28075fd0b74Schristos if (*p == '\0')
28175fd0b74Schristos --p;
28275fd0b74Schristos len = strlen (p);
28375fd0b74Schristos while (len < 8)
28475fd0b74Schristos {
28575fd0b74Schristos putc (' ', fp);
28675fd0b74Schristos ++len;
28775fd0b74Schristos }
28875fd0b74Schristos fprintf (fp, "0x%s", p);
28975fd0b74Schristos }
29075fd0b74Schristos break;
29175fd0b74Schristos
29275fd0b74Schristos case 'F':
29375fd0b74Schristos /* Error is fatal. */
294*e992f068Schristos fatal = true;
29575fd0b74Schristos break;
29675fd0b74Schristos
29775fd0b74Schristos case 'P':
29875fd0b74Schristos /* Print program name. */
29975fd0b74Schristos fprintf (fp, "%s", program_name);
30075fd0b74Schristos break;
30175fd0b74Schristos
30275fd0b74Schristos case 'E':
30375fd0b74Schristos /* current bfd error or errno */
30475fd0b74Schristos fprintf (fp, "%s", bfd_errmsg (bfd_get_error ()));
30575fd0b74Schristos break;
30675fd0b74Schristos
30775fd0b74Schristos case 'C':
30875fd0b74Schristos case 'D':
30975fd0b74Schristos case 'G':
31075fd0b74Schristos case 'H':
31175fd0b74Schristos /* Clever filename:linenumber with function name if possible.
31275fd0b74Schristos The arguments are a BFD, a section, and an offset. */
31375fd0b74Schristos {
31475fd0b74Schristos static bfd *last_bfd;
315ede78133Schristos static char *last_file;
316ede78133Schristos static char *last_function;
31775fd0b74Schristos bfd *abfd;
31875fd0b74Schristos asection *section;
31975fd0b74Schristos bfd_vma offset;
32075fd0b74Schristos asymbol **asymbols = NULL;
32175fd0b74Schristos const char *filename;
32275fd0b74Schristos const char *functionname;
32375fd0b74Schristos unsigned int linenumber;
324*e992f068Schristos bool discard_last;
325*e992f068Schristos bool done;
326012573ebSchristos bfd_error_type last_bfd_error = bfd_get_error ();
32775fd0b74Schristos
328ede78133Schristos abfd = args[arg_no].reladdr.abfd;
329ede78133Schristos section = args[arg_no].reladdr.sec;
330ede78133Schristos offset = args[arg_no].reladdr.off;
331ede78133Schristos ++arg_count;
33275fd0b74Schristos
33375fd0b74Schristos if (abfd != NULL)
33475fd0b74Schristos {
33575fd0b74Schristos if (!bfd_generic_link_read_symbols (abfd))
336ede78133Schristos einfo (_("%F%P: %pB: could not read symbols: %E\n"), abfd);
33775fd0b74Schristos
33875fd0b74Schristos asymbols = bfd_get_outsymbols (abfd);
33975fd0b74Schristos }
34075fd0b74Schristos
34175fd0b74Schristos /* The GNU Coding Standard requires that error messages
34275fd0b74Schristos be of the form:
34375fd0b74Schristos
34475fd0b74Schristos source-file-name:lineno: message
34575fd0b74Schristos
34675fd0b74Schristos We do not always have a line number available so if
34775fd0b74Schristos we cannot find them we print out the section name and
34875fd0b74Schristos offset instead. */
349*e992f068Schristos discard_last = true;
35075fd0b74Schristos if (abfd != NULL
35175fd0b74Schristos && bfd_find_nearest_line (abfd, section, asymbols, offset,
35275fd0b74Schristos &filename, &functionname,
35375fd0b74Schristos &linenumber))
35475fd0b74Schristos {
35575fd0b74Schristos if (functionname != NULL
35675fd0b74Schristos && (fmt[-1] == 'C' || fmt[-1] == 'H'))
35775fd0b74Schristos {
35875fd0b74Schristos /* Detect the case where we are printing out a
35975fd0b74Schristos message for the same function as the last
36075fd0b74Schristos call to vinfo ("%C"). In this situation do
36175fd0b74Schristos not print out the ABFD filename or the
36275fd0b74Schristos function name again. Note - we do still
36375fd0b74Schristos print out the source filename, as this will
36475fd0b74Schristos allow programs that parse the linker's output
36575fd0b74Schristos (eg emacs) to correctly locate multiple
36675fd0b74Schristos errors in the same source file. */
36775fd0b74Schristos if (last_bfd == NULL
36875fd0b74Schristos || last_function == NULL
36975fd0b74Schristos || last_bfd != abfd
370ede78133Schristos || (last_file == NULL) != (filename == NULL)
37175fd0b74Schristos || (filename != NULL
37275fd0b74Schristos && filename_cmp (last_file, filename) != 0)
37375fd0b74Schristos || strcmp (last_function, functionname) != 0)
37475fd0b74Schristos {
375ede78133Schristos lfinfo (fp, _("%pB: in function `%pT':\n"),
37675fd0b74Schristos abfd, functionname);
37775fd0b74Schristos
37875fd0b74Schristos last_bfd = abfd;
37975fd0b74Schristos free (last_file);
38075fd0b74Schristos last_file = NULL;
38175fd0b74Schristos if (filename)
38275fd0b74Schristos last_file = xstrdup (filename);
38375fd0b74Schristos free (last_function);
38475fd0b74Schristos last_function = xstrdup (functionname);
38575fd0b74Schristos }
386*e992f068Schristos discard_last = false;
38775fd0b74Schristos }
38875fd0b74Schristos else
389ede78133Schristos lfinfo (fp, "%pB:", abfd);
39075fd0b74Schristos
39175fd0b74Schristos if (filename != NULL)
39275fd0b74Schristos fprintf (fp, "%s:", filename);
39375fd0b74Schristos
39475fd0b74Schristos done = fmt[-1] != 'H';
39575fd0b74Schristos if (functionname != NULL && fmt[-1] == 'G')
396ede78133Schristos lfinfo (fp, "%pT", functionname);
39775fd0b74Schristos else if (filename != NULL && linenumber != 0)
39875fd0b74Schristos fprintf (fp, "%u%s", linenumber, done ? "" : ":");
39975fd0b74Schristos else
400*e992f068Schristos done = false;
40175fd0b74Schristos }
40275fd0b74Schristos else
40375fd0b74Schristos {
404ede78133Schristos lfinfo (fp, "%pB:", abfd);
405*e992f068Schristos done = false;
40675fd0b74Schristos }
40775fd0b74Schristos if (!done)
408ede78133Schristos lfinfo (fp, "(%pA+0x%v)", section, offset);
409012573ebSchristos bfd_set_error (last_bfd_error);
41075fd0b74Schristos
41175fd0b74Schristos if (discard_last)
41275fd0b74Schristos {
41375fd0b74Schristos last_bfd = NULL;
41475fd0b74Schristos free (last_file);
41575fd0b74Schristos last_file = NULL;
41675fd0b74Schristos free (last_function);
41775fd0b74Schristos last_function = NULL;
41875fd0b74Schristos }
41975fd0b74Schristos }
42075fd0b74Schristos break;
42175fd0b74Schristos
42275fd0b74Schristos case 'p':
423ede78133Schristos if (*fmt == 'A')
424ede78133Schristos {
425ede78133Schristos /* section name from a section */
426ede78133Schristos asection *sec;
427ede78133Schristos bfd *abfd;
428ede78133Schristos
429ede78133Schristos fmt++;
430ede78133Schristos sec = (asection *) args[arg_no].p;
431ede78133Schristos ++arg_count;
432ede78133Schristos fprintf (fp, "%s", sec->name);
433012573ebSchristos abfd = sec->owner;
434012573ebSchristos if (abfd != NULL)
435012573ebSchristos {
436012573ebSchristos const char *group = bfd_group_name (abfd, sec);
437ede78133Schristos if (group != NULL)
438ede78133Schristos fprintf (fp, "[%s]", group);
439ede78133Schristos }
440012573ebSchristos }
441ede78133Schristos else if (*fmt == 'B')
442ede78133Schristos {
443ede78133Schristos /* filename from a bfd */
444ede78133Schristos bfd *abfd = (bfd *) args[arg_no].p;
445ede78133Schristos
446ede78133Schristos fmt++;
447ede78133Schristos ++arg_count;
448ede78133Schristos if (abfd == NULL)
449ede78133Schristos fprintf (fp, "%s generated", program_name);
450ede78133Schristos else if (abfd->my_archive != NULL
451ede78133Schristos && !bfd_is_thin_archive (abfd->my_archive))
452*e992f068Schristos fprintf (fp, "%s(%s)",
453*e992f068Schristos bfd_get_filename (abfd->my_archive),
454*e992f068Schristos bfd_get_filename (abfd));
455ede78133Schristos else
456*e992f068Schristos fprintf (fp, "%s", bfd_get_filename (abfd));
457ede78133Schristos }
458ede78133Schristos else if (*fmt == 'I')
459ede78133Schristos {
460ede78133Schristos /* filename from a lang_input_statement_type */
461ede78133Schristos lang_input_statement_type *i;
462ede78133Schristos
463ede78133Schristos fmt++;
464ede78133Schristos i = (lang_input_statement_type *) args[arg_no].p;
465ede78133Schristos ++arg_count;
466012573ebSchristos if (i->the_bfd != NULL
467012573ebSchristos && i->the_bfd->my_archive != NULL
468ede78133Schristos && !bfd_is_thin_archive (i->the_bfd->my_archive))
469*e992f068Schristos fprintf (fp, "(%s)%s",
470*e992f068Schristos bfd_get_filename (i->the_bfd->my_archive),
471012573ebSchristos i->local_sym_name);
472012573ebSchristos else
473012573ebSchristos fprintf (fp, "%s", i->filename);
474ede78133Schristos }
475ede78133Schristos else if (*fmt == 'R')
476ede78133Schristos {
477ede78133Schristos /* Print all that's interesting about a relent. */
478ede78133Schristos arelent *relent = (arelent *) args[arg_no].p;
479ede78133Schristos
480ede78133Schristos fmt++;
481ede78133Schristos ++arg_count;
482ede78133Schristos lfinfo (fp, "%s+0x%v (type %s)",
483ede78133Schristos (*(relent->sym_ptr_ptr))->name,
484ede78133Schristos relent->addend,
485ede78133Schristos relent->howto->name);
486ede78133Schristos }
487*e992f068Schristos else if (*fmt == 'S' || *fmt == 'U')
488ede78133Schristos {
489*e992f068Schristos /* Print script file and perhaps the associated linenumber. */
490ede78133Schristos etree_type node;
491ede78133Schristos etree_type *tp = (etree_type *) args[arg_no].p;
492ede78133Schristos
493ede78133Schristos fmt++;
494ede78133Schristos ++arg_count;
495ede78133Schristos if (tp == NULL)
496ede78133Schristos {
497ede78133Schristos tp = &node;
498ede78133Schristos tp->type.filename = ldlex_filename ();
499ede78133Schristos tp->type.lineno = lineno;
500ede78133Schristos }
501*e992f068Schristos if (tp->type.filename != NULL && fmt[-1] == 'S')
502ede78133Schristos fprintf (fp, "%s:%u", tp->type.filename, tp->type.lineno);
503*e992f068Schristos else if (tp->type.filename != NULL && fmt[-1] == 'U')
504*e992f068Schristos fprintf (fp, "%s", tp->type.filename);
505ede78133Schristos }
506ede78133Schristos else if (*fmt == 'T')
507ede78133Schristos {
508ede78133Schristos /* Symbol name. */
509ede78133Schristos const char *name = (const char *) args[arg_no].p;
510ede78133Schristos
511ede78133Schristos fmt++;
512ede78133Schristos ++arg_count;
513ede78133Schristos if (name == NULL || *name == 0)
514ede78133Schristos {
515ede78133Schristos fprintf (fp, _("no symbol"));
516ede78133Schristos break;
517ede78133Schristos }
518ede78133Schristos else if (demangling)
519ede78133Schristos {
520ede78133Schristos char *demangled;
521ede78133Schristos
522ede78133Schristos demangled = bfd_demangle (link_info.output_bfd, name,
523ede78133Schristos DMGL_ANSI | DMGL_PARAMS);
524ede78133Schristos if (demangled != NULL)
525ede78133Schristos {
526ede78133Schristos fprintf (fp, "%s", demangled);
527ede78133Schristos free (demangled);
528ede78133Schristos break;
529ede78133Schristos }
530ede78133Schristos }
531ede78133Schristos fprintf (fp, "%s", name);
532ede78133Schristos }
533ede78133Schristos else
534ede78133Schristos {
53575fd0b74Schristos /* native (host) void* pointer, like printf */
536ede78133Schristos fprintf (fp, "%p", args[arg_no].p);
537ede78133Schristos ++arg_count;
538ede78133Schristos }
53975fd0b74Schristos break;
54075fd0b74Schristos
54175fd0b74Schristos case 's':
54275fd0b74Schristos /* arbitrary string, like printf */
543ede78133Schristos fprintf (fp, "%s", (char *) args[arg_no].p);
544ede78133Schristos ++arg_count;
54575fd0b74Schristos break;
54675fd0b74Schristos
54775fd0b74Schristos case 'd':
54875fd0b74Schristos /* integer, like printf */
549ede78133Schristos fprintf (fp, "%d", args[arg_no].i);
550ede78133Schristos ++arg_count;
55175fd0b74Schristos break;
55275fd0b74Schristos
55375fd0b74Schristos case 'u':
55475fd0b74Schristos /* unsigned integer, like printf */
555ede78133Schristos fprintf (fp, "%u", args[arg_no].i);
556ede78133Schristos ++arg_count;
55775fd0b74Schristos break;
55875fd0b74Schristos
55975fd0b74Schristos case 'l':
56075fd0b74Schristos if (*fmt == 'd')
56175fd0b74Schristos {
562ede78133Schristos fprintf (fp, "%ld", args[arg_no].l);
563ede78133Schristos ++arg_count;
56475fd0b74Schristos ++fmt;
56575fd0b74Schristos break;
56675fd0b74Schristos }
56775fd0b74Schristos else if (*fmt == 'u')
56875fd0b74Schristos {
569ede78133Schristos fprintf (fp, "%lu", args[arg_no].l);
570ede78133Schristos ++arg_count;
57175fd0b74Schristos ++fmt;
57275fd0b74Schristos break;
57375fd0b74Schristos }
57475fd0b74Schristos /* Fallthru */
57575fd0b74Schristos
57675fd0b74Schristos default:
57775fd0b74Schristos fprintf (fp, "%%%c", fmt[-1]);
57875fd0b74Schristos break;
57975fd0b74Schristos }
58075fd0b74Schristos }
58175fd0b74Schristos }
58275fd0b74Schristos
58375fd0b74Schristos if (is_warning && config.fatal_warnings)
584*e992f068Schristos config.make_executable = false;
58575fd0b74Schristos
58675fd0b74Schristos if (fatal)
58775fd0b74Schristos xexit (1);
58875fd0b74Schristos }
58975fd0b74Schristos
59075fd0b74Schristos /* Format info message and print on stdout. */
59175fd0b74Schristos
59275fd0b74Schristos /* (You would think this should be called just "info", but then you
59375fd0b74Schristos would be hosed by LynxOS, which defines that name in its libc.) */
59475fd0b74Schristos
59575fd0b74Schristos void
info_msg(const char * fmt,...)59675fd0b74Schristos info_msg (const char *fmt, ...)
59775fd0b74Schristos {
59875fd0b74Schristos va_list arg;
59975fd0b74Schristos
60075fd0b74Schristos va_start (arg, fmt);
601*e992f068Schristos vfinfo (stdout, fmt, arg, false);
60275fd0b74Schristos va_end (arg);
60375fd0b74Schristos }
60475fd0b74Schristos
60575fd0b74Schristos /* ('e' for error.) Format info message and print on stderr. */
60675fd0b74Schristos
60775fd0b74Schristos void
einfo(const char * fmt,...)60875fd0b74Schristos einfo (const char *fmt, ...)
60975fd0b74Schristos {
61075fd0b74Schristos va_list arg;
61175fd0b74Schristos
61275fd0b74Schristos fflush (stdout);
61375fd0b74Schristos va_start (arg, fmt);
614*e992f068Schristos vfinfo (stderr, fmt, arg, true);
61575fd0b74Schristos va_end (arg);
61675fd0b74Schristos fflush (stderr);
61775fd0b74Schristos }
61875fd0b74Schristos
61975fd0b74Schristos void
info_assert(const char * file,unsigned int line)62075fd0b74Schristos info_assert (const char *file, unsigned int line)
62175fd0b74Schristos {
62275fd0b74Schristos einfo (_("%F%P: internal error %s %d\n"), file, line);
62375fd0b74Schristos }
62475fd0b74Schristos
62575fd0b74Schristos /* ('m' for map) Format info message and print on map. */
62675fd0b74Schristos
62775fd0b74Schristos void
minfo(const char * fmt,...)62875fd0b74Schristos minfo (const char *fmt, ...)
62975fd0b74Schristos {
63075fd0b74Schristos if (config.map_file != NULL)
63175fd0b74Schristos {
63275fd0b74Schristos va_list arg;
63375fd0b74Schristos
63475fd0b74Schristos va_start (arg, fmt);
63575fd0b74Schristos if (fmt[0] == '%' && fmt[1] == '!' && fmt[2] == 0)
63675fd0b74Schristos {
63775fd0b74Schristos /* Stash info about --as-needed shared libraries. Print
63875fd0b74Schristos later so they don't appear intermingled with archive
63975fd0b74Schristos library info. */
64075fd0b74Schristos struct asneeded_minfo *m = xmalloc (sizeof *m);
64175fd0b74Schristos
64275fd0b74Schristos m->next = NULL;
64375fd0b74Schristos m->soname = va_arg (arg, const char *);
64475fd0b74Schristos m->ref = va_arg (arg, bfd *);
64575fd0b74Schristos m->name = va_arg (arg, const char *);
64675fd0b74Schristos *asneeded_list_tail = m;
64775fd0b74Schristos asneeded_list_tail = &m->next;
64875fd0b74Schristos }
64975fd0b74Schristos else
650*e992f068Schristos vfinfo (config.map_file, fmt, arg, false);
65175fd0b74Schristos va_end (arg);
65275fd0b74Schristos }
65375fd0b74Schristos }
65475fd0b74Schristos
65575fd0b74Schristos void
lfinfo(FILE * file,const char * fmt,...)65675fd0b74Schristos lfinfo (FILE *file, const char *fmt, ...)
65775fd0b74Schristos {
65875fd0b74Schristos va_list arg;
65975fd0b74Schristos
66075fd0b74Schristos va_start (arg, fmt);
661*e992f068Schristos vfinfo (file, fmt, arg, false);
66275fd0b74Schristos va_end (arg);
66375fd0b74Schristos }
66475fd0b74Schristos
66575fd0b74Schristos /* Functions to print the link map. */
66675fd0b74Schristos
66775fd0b74Schristos void
print_space(void)66875fd0b74Schristos print_space (void)
66975fd0b74Schristos {
67075fd0b74Schristos fprintf (config.map_file, " ");
67175fd0b74Schristos }
67275fd0b74Schristos
67375fd0b74Schristos void
print_nl(void)67475fd0b74Schristos print_nl (void)
67575fd0b74Schristos {
67675fd0b74Schristos fprintf (config.map_file, "\n");
67775fd0b74Schristos }
67875fd0b74Schristos
67975fd0b74Schristos /* A more or less friendly abort message. In ld.h abort is defined to
68075fd0b74Schristos call this function. */
68175fd0b74Schristos
68275fd0b74Schristos void
ld_abort(const char * file,int line,const char * fn)68375fd0b74Schristos ld_abort (const char *file, int line, const char *fn)
68475fd0b74Schristos {
68575fd0b74Schristos if (fn != NULL)
68675fd0b74Schristos einfo (_("%P: internal error: aborting at %s:%d in %s\n"),
68775fd0b74Schristos file, line, fn);
68875fd0b74Schristos else
68975fd0b74Schristos einfo (_("%P: internal error: aborting at %s:%d\n"),
69075fd0b74Schristos file, line);
691ede78133Schristos einfo (_("%F%P: please report this bug\n"));
69275fd0b74Schristos xexit (1);
69375fd0b74Schristos }
694