gcc80: Handle TZ specific "%+" format in strftime.
[dragonfly.git] / contrib / gcc-8.0 / gcc / tlink.c
1 /* Scan linker error messages for missing template instantiations and provide
2    them.
3
4    Copyright (C) 1995-2018 Free Software Foundation, Inc.
5    Contributed by Jason Merrill (jason@cygnus.com).
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "intl.h"
28 #include "obstack.h"
29 #include "demangle.h"
30 #include "collect2.h"
31 #include "collect-utils.h"
32 #include "filenames.h"
33 #include "diagnostic-core.h"
34
35 /* TARGET_64BIT may be defined to use driver specific functionality. */
36 #undef TARGET_64BIT
37 #define TARGET_64BIT TARGET_64BIT_DEFAULT
38
39 #define MAX_ITERATIONS 17
40
41 /* Defined in the automatically-generated underscore.c.  */
42 extern int prepends_underscore;
43
44 static int tlink_verbose;
45
46 static char *initial_cwd;
47 \f
48 /* Hash table boilerplate for working with htab_t.  We have hash tables
49    for symbol names, file names, and demangled symbols.  */
50
51 typedef struct symbol_hash_entry
52 {
53   const char *key;
54   struct file_hash_entry *file;
55   int chosen;
56   int tweaking;
57   int tweaked;
58 } symbol;
59
60 typedef struct file_hash_entry
61 {
62   const char *key;
63   const char *args;
64   const char *dir;
65   const char *main;
66   int tweaking;
67 } file;
68
69 typedef const char *str;
70
71 typedef struct demangled_hash_entry
72 {
73   const char *key;
74   vec<str> mangled;
75 } demangled;
76
77 /* Hash and comparison functions for these hash tables.  */
78
79 static int hash_string_eq (const void *, const void *);
80 static hashval_t hash_string_hash (const void *);
81
82 static int
83 hash_string_eq (const void *s1_p, const void *s2_p)
84 {
85   const char *const *s1 = (const char *const *) s1_p;
86   const char *s2 = (const char *) s2_p;
87   return strcmp (*s1, s2) == 0;
88 }
89
90 static hashval_t
91 hash_string_hash (const void *s_p)
92 {
93   const char *const *s = (const char *const *) s_p;
94   return (*htab_hash_string) (*s);
95 }
96
97 static htab_t symbol_table;
98
99 static struct symbol_hash_entry * symbol_hash_lookup (const char *, int);
100 static struct file_hash_entry * file_hash_lookup (const char *);
101 static struct demangled_hash_entry *demangled_hash_lookup (const char *, int);
102 static void symbol_push (symbol *);
103 static symbol * symbol_pop (void);
104 static void file_push (file *);
105 static file * file_pop (void);
106 static char * frob_extension (const char *, const char *);
107 static char * obstack_fgets (FILE *, struct obstack *);
108 static char * tfgets (FILE *);
109 static char * pfgets (FILE *);
110 static void freadsym (FILE *, file *, int);
111 static void read_repo_file (file *);
112 static void maybe_tweak (char *, file *);
113 static int recompile_files (void);
114 static int read_repo_files (char **);
115 static void demangle_new_symbols (void);
116 static int scan_linker_output (const char *);
117
118 /* Look up an entry in the symbol hash table.  */
119
120 static struct symbol_hash_entry *
121 symbol_hash_lookup (const char *string, int create)
122 {
123   void **e;
124   e = htab_find_slot_with_hash (symbol_table, string,
125                                 (*htab_hash_string) (string),
126                                 create ? INSERT : NO_INSERT);
127   if (e == NULL)
128     return NULL;
129   if (*e == NULL)
130     {
131       struct symbol_hash_entry *v;
132       *e = v = XCNEW (struct symbol_hash_entry);
133       v->key = xstrdup (string);
134     }
135   return (struct symbol_hash_entry *) *e;
136 }
137
138 static htab_t file_table;
139
140 /* Look up an entry in the file hash table.  */
141
142 static struct file_hash_entry *
143 file_hash_lookup (const char *string)
144 {
145   void **e;
146   e = htab_find_slot_with_hash (file_table, string,
147                                 (*htab_hash_string) (string),
148                                 INSERT);
149   if (*e == NULL)
150     {
151       struct file_hash_entry *v;
152       *e = v = XCNEW (struct file_hash_entry);
153       v->key = xstrdup (string);
154     }
155   return (struct file_hash_entry *) *e;
156 }
157
158 static htab_t demangled_table;
159
160 /* Look up an entry in the demangled name hash table.  */
161
162 static struct demangled_hash_entry *
163 demangled_hash_lookup (const char *string, int create)
164 {
165   void **e;
166   e = htab_find_slot_with_hash (demangled_table, string,
167                                 (*htab_hash_string) (string),
168                                 create ? INSERT : NO_INSERT);
169   if (e == NULL)
170     return NULL;
171   if (*e == NULL)
172     {
173       struct demangled_hash_entry *v;
174       *e = v = XCNEW (struct demangled_hash_entry);
175       v->key = xstrdup (string);
176     }
177   return (struct demangled_hash_entry *) *e;
178 }
179 \f
180 /* Stack code.  */
181
182 struct symbol_stack_entry
183 {
184   symbol *value;
185   struct symbol_stack_entry *next;
186 };
187 struct obstack symbol_stack_obstack;
188 struct symbol_stack_entry *symbol_stack;
189
190 struct file_stack_entry
191 {
192   file *value;
193   struct file_stack_entry *next;
194 };
195 struct obstack file_stack_obstack;
196 struct file_stack_entry *file_stack;
197
198 static void
199 symbol_push (symbol *p)
200 {
201   struct symbol_stack_entry *ep
202     = XOBNEW (&symbol_stack_obstack, struct symbol_stack_entry);
203   ep->value = p;
204   ep->next = symbol_stack;
205   symbol_stack = ep;
206 }
207
208 static symbol *
209 symbol_pop (void)
210 {
211   struct symbol_stack_entry *ep = symbol_stack;
212   symbol *p;
213   if (ep == NULL)
214     return NULL;
215   p = ep->value;
216   symbol_stack = ep->next;
217   obstack_free (&symbol_stack_obstack, ep);
218   return p;
219 }
220
221 static void
222 file_push (file *p)
223 {
224   struct file_stack_entry *ep;
225
226   if (p->tweaking)
227     return;
228
229   ep = XOBNEW (&file_stack_obstack, struct file_stack_entry);
230   ep->value = p;
231   ep->next = file_stack;
232   file_stack = ep;
233   p->tweaking = 1;
234 }
235
236 static file *
237 file_pop (void)
238 {
239   struct file_stack_entry *ep = file_stack;
240   file *p;
241   if (ep == NULL)
242     return NULL;
243   p = ep->value;
244   file_stack = ep->next;
245   obstack_free (&file_stack_obstack, ep);
246   p->tweaking = 0;
247   return p;
248 }
249 \f
250 /* Other machinery.  */
251
252 /* Initialize the tlink machinery.  Called from do_tlink.  */
253
254 static void
255 tlink_init (void)
256 {
257   const char *p;
258
259   symbol_table = htab_create (500, hash_string_hash, hash_string_eq,
260                               NULL);
261   file_table = htab_create (500, hash_string_hash, hash_string_eq,
262                             NULL);
263   demangled_table = htab_create (500, hash_string_hash, hash_string_eq,
264                                  NULL);
265
266   obstack_begin (&symbol_stack_obstack, 0);
267   obstack_begin (&file_stack_obstack, 0);
268
269   p = getenv ("TLINK_VERBOSE");
270   if (p)
271     tlink_verbose = atoi (p);
272   else
273     {
274       tlink_verbose = 1;
275       if (verbose)
276         tlink_verbose = 2;
277       if (debug)
278         tlink_verbose = 3;
279     }
280
281   initial_cwd = getpwd ();
282 }
283
284 static int
285 tlink_execute (const char *prog, char **argv, const char *outname,
286                const char *errname, bool use_atfile)
287 {
288   struct pex_obj *pex;
289
290   pex = collect_execute (prog, argv, outname, errname,
291                          PEX_LAST | PEX_SEARCH, use_atfile);
292   return collect_wait (prog, pex);
293 }
294
295 static char *
296 frob_extension (const char *s, const char *ext)
297 {
298   const char *p;
299
300   p = strrchr (lbasename (s), '.');
301   if (! p)
302     p = s + strlen (s);
303
304   obstack_grow (&temporary_obstack, s, p - s);
305   return (char *) obstack_copy0 (&temporary_obstack, ext, strlen (ext));
306 }
307
308 static char *
309 obstack_fgets (FILE *stream, struct obstack *ob)
310 {
311   int c;
312   while ((c = getc (stream)) != EOF && c != '\n')
313     obstack_1grow (ob, c);
314   if (obstack_object_size (ob) == 0)
315     return NULL;
316   obstack_1grow (ob, '\0');
317   return XOBFINISH (ob, char *);
318 }
319
320 static char *
321 tfgets (FILE *stream)
322 {
323   return obstack_fgets (stream, &temporary_obstack);
324 }
325
326 static char *
327 pfgets (FILE *stream)
328 {
329   return xstrdup (tfgets (stream));
330 }
331 \f
332 /* Real tlink code.  */
333
334 /* Subroutine of read_repo_file.  We are reading the repo file for file F,
335    which is coming in on STREAM, and the symbol that comes next in STREAM
336    is offered, chosen or provided if CHOSEN is 0, 1 or 2, respectively.
337
338    XXX "provided" is unimplemented, both here and in the compiler.  */
339
340 static void
341 freadsym (FILE *stream, file *f, int chosen)
342 {
343   symbol *sym;
344
345   {
346     const char *name = tfgets (stream);
347     sym = symbol_hash_lookup (name, true);
348   }
349
350   if (sym->file == NULL)
351     {
352       /* We didn't have this symbol already, so we choose this file.  */
353
354       symbol_push (sym);
355       sym->file = f;
356       sym->chosen = chosen;
357     }
358   else if (chosen)
359     {
360       /* We want this file; cast aside any pretender.  */
361
362       if (sym->chosen && sym->file != f)
363         {
364           if (sym->chosen == 1)
365             file_push (sym->file);
366           else
367             {
368               file_push (f);
369               f = sym->file;
370               chosen = sym->chosen;
371             }
372         }
373       sym->file = f;
374       sym->chosen = chosen;
375     }
376 }
377
378 /* Read in the repo file denoted by F, and record all its information.  */
379
380 static void
381 read_repo_file (file *f)
382 {
383   char c;
384   FILE *stream = fopen (f->key, "r");
385
386   if (tlink_verbose >= 2)
387     fprintf (stderr, _("collect: reading %s\n"), f->key);
388
389   while (fscanf (stream, "%c ", &c) == 1)
390     {
391       switch (c)
392         {
393         case 'A':
394           f->args = pfgets (stream);
395           break;
396         case 'D':
397           f->dir = pfgets (stream);
398           break;
399         case 'M':
400           f->main = pfgets (stream);
401           break;
402         case 'P':
403           freadsym (stream, f, 2);
404           break;
405         case 'C':
406           freadsym (stream, f, 1);
407           break;
408         case 'O':
409           freadsym (stream, f, 0);
410           break;
411         }
412       obstack_free (&temporary_obstack, temporary_firstobj);
413     }
414   fclose (stream);
415   if (f->args == NULL)
416     f->args = getenv ("COLLECT_GCC_OPTIONS");
417   if (f->dir == NULL)
418     f->dir = ".";
419 }
420
421 /* We might want to modify LINE, which is a symbol line from file F.  We do
422    this if either we saw an error message referring to the symbol in
423    question, or we have already allocated the symbol to another file and
424    this one wants to emit it as well.  */
425
426 static void
427 maybe_tweak (char *line, file *f)
428 {
429   symbol *sym = symbol_hash_lookup (line + 2, false);
430
431   if ((sym->file == f && sym->tweaking)
432       || (sym->file != f && line[0] == 'C'))
433     {
434       sym->tweaking = 0;
435       sym->tweaked = 1;
436
437       if (line[0] == 'O')
438         {
439           line[0] = 'C';
440           sym->chosen = 1;
441         }
442       else
443         {
444           line[0] = 'O';
445           sym->chosen = 0;
446         }
447     }
448 }
449
450 /* Update the repo files for each of the object files we have adjusted and
451    recompile.  */
452
453 static int
454 recompile_files (void)
455 {
456   file *f;
457
458   putenv (xstrdup ("COMPILER_PATH="));
459   putenv (xstrdup ("LIBRARY_PATH="));
460
461   while ((f = file_pop ()) != NULL)
462     {
463       char *line;
464       const char *p, *q;
465       char **argv;
466       struct obstack arg_stack;
467       FILE *stream = fopen (f->key, "r");
468       const char *const outname = frob_extension (f->key, ".rnw");
469       FILE *output = fopen (outname, "w");
470
471       while ((line = tfgets (stream)) != NULL)
472         {
473           switch (line[0])
474             {
475             case 'C':
476             case 'O':
477               maybe_tweak (line, f);
478             }
479           fprintf (output, "%s\n", line);
480         }
481       fclose (stream);
482       fclose (output);
483       /* On Windows "rename" returns -1 and sets ERRNO to EACCESS if
484          the new file name already exists.  Therefore, we explicitly
485          remove the old file first.  */
486       if (remove (f->key) == -1)
487         fatal_error (input_location, "removing .rpo file: %m");
488       if (rename (outname, f->key) == -1)
489         fatal_error (input_location, "renaming .rpo file: %m");
490
491       if (!f->args)
492         {
493           error ("repository file '%s' does not contain command-line "
494                  "arguments", f->key);
495           return 0;
496         }
497
498       /* Build a null-terminated argv array suitable for
499          tlink_execute().  Manipulate arguments on the arg_stack while
500          building argv on the temporary_obstack.  */
501
502       obstack_init (&arg_stack);
503       obstack_ptr_grow (&temporary_obstack, c_file_name);
504
505       for (p = f->args; *p != '\0'; p = q + 1)
506         {
507           /* Arguments are delimited by single-quotes.  Find the
508              opening quote.  */
509           p = strchr (p, '\'');
510           if (!p)
511             goto done;
512
513           /* Find the closing quote.  */
514           q = strchr (p + 1, '\'');
515           if (!q)
516             goto done;
517
518           obstack_grow (&arg_stack, p + 1, q - (p + 1));
519
520           /* Replace '\'' with '.  This is how set_collect_gcc_options
521              encodes a single-quote.  */
522           while (q[1] == '\\' && q[2] == '\'' && q[3] == '\'')
523             {
524               const char *r;
525
526               r = strchr (q + 4, '\'');
527               if (!r)
528                 goto done;
529
530               obstack_grow (&arg_stack, q + 3, r - (q + 3));
531               q = r;
532             }
533
534           obstack_1grow (&arg_stack, '\0');
535           obstack_ptr_grow (&temporary_obstack, obstack_finish (&arg_stack));
536         }
537     done:
538       obstack_ptr_grow (&temporary_obstack, f->main);
539       obstack_ptr_grow (&temporary_obstack, NULL);
540       argv = XOBFINISH (&temporary_obstack, char **);
541
542       if (tlink_verbose)
543         fprintf (stderr, _("collect: recompiling %s\n"), f->main);
544
545       if (chdir (f->dir) != 0
546           || tlink_execute (c_file_name, argv, NULL, NULL, false) != 0
547           || chdir (initial_cwd) != 0)
548         return 0;
549
550       read_repo_file (f);
551
552       obstack_free (&arg_stack, NULL);
553       obstack_free (&temporary_obstack, temporary_firstobj);
554     }
555   return 1;
556 }
557
558 /* The first phase of processing: determine which object files have
559    .rpo files associated with them, and read in the information.  */
560
561 static int
562 read_repo_files (char **object_lst)
563 {
564   char **object = object_lst;
565
566   for (; *object; object++)
567     {
568       const char *p;
569       file *f;
570
571       /* Don't bother trying for ld flags.  */
572       if (*object[0] == '-')
573         continue;
574
575       p = frob_extension (*object, ".rpo");
576
577       if (! file_exists (p))
578         continue;
579
580       f = file_hash_lookup (p);
581
582       read_repo_file (f);
583     }
584
585   if (file_stack != NULL && ! recompile_files ())
586     return 0;
587
588   return (symbol_stack != NULL);
589 }
590
591 /* Add the demangled forms of any new symbols to the hash table.  */
592
593 static void
594 demangle_new_symbols (void)
595 {
596   symbol *sym;
597
598   while ((sym = symbol_pop ()) != NULL)
599     {
600       demangled *dem;
601       const char *p = cplus_demangle (sym->key, DMGL_PARAMS | DMGL_ANSI);
602
603       if (! p)
604         continue;
605
606       dem = demangled_hash_lookup (p, true);
607       dem->mangled.safe_push (sym->key);
608     }
609 }
610
611 /* We want to tweak symbol SYM.  Return true if all is well, false on
612    error.  */
613
614 static bool
615 start_tweaking (symbol *sym)
616 {
617   if (sym && sym->tweaked)
618     {
619       error ("'%s' was assigned to '%s', but was not defined "
620              "during recompilation, or vice versa",
621              sym->key, sym->file->key);
622       return 0;
623     }
624   if (sym && !sym->tweaking)
625     {
626       if (tlink_verbose >= 2)
627         fprintf (stderr, _("collect: tweaking %s in %s\n"),
628                  sym->key, sym->file->key);
629       sym->tweaking = 1;
630       file_push (sym->file);
631     }
632   return true;
633 }
634
635 /* Step through the output of the linker, in the file named FNAME, and
636    adjust the settings for each symbol encountered.  */
637
638 static int
639 scan_linker_output (const char *fname)
640 {
641   FILE *stream = fopen (fname, "r");
642   char *line;
643   int skip_next_in_line = 0;
644
645   while ((line = tfgets (stream)) != NULL)
646     {
647       char *p = line, *q;
648       symbol *sym;
649       demangled *dem = 0;
650       int end;
651       int ok = 0;
652       unsigned ix;
653       str s;
654
655       /* On darwin9, we might have to skip " in " lines as well.  */
656       if (skip_next_in_line
657           && strstr (p, " in "))
658           continue;
659       skip_next_in_line = 0;
660
661       while (*p && ISSPACE ((unsigned char) *p))
662         ++p;
663
664       if (! *p)
665         continue;
666
667       for (q = p; *q && ! ISSPACE ((unsigned char) *q); ++q)
668         ;
669
670       /* Try the first word on the line.  */
671       if (*p == '.')
672         ++p;
673       if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
674         p += strlen (USER_LABEL_PREFIX);
675
676       end = ! *q;
677       *q = 0;
678       sym = symbol_hash_lookup (p, false);
679
680       /* Some SVR4 linkers produce messages like
681          ld: 0711-317 ERROR: Undefined symbol: .g__t3foo1Zi
682          */
683       if (! sym && ! end && strstr (q + 1, "Undefined symbol: "))
684         {
685           char *p = strrchr (q + 1, ' ');
686           p++;
687           if (*p == '.')
688             p++;
689           if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
690             p += strlen (USER_LABEL_PREFIX);
691           sym = symbol_hash_lookup (p, false);
692         }
693
694       if (! sym && ! end)
695         /* Try a mangled name in quotes.  */
696         {
697           char *oldq = q + 1;
698           q = 0;
699
700           /* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)*  */
701           if (strcmp (oldq, "referenced from:") == 0)
702             {
703               /* We have to remember that we found a symbol to tweak.  */
704               ok = 1;
705
706               /* We actually want to start from the first word on the
707                  line.  */
708               oldq = p;
709
710               /* Since the format is multiline, we have to skip
711                  following lines with " in ".  */
712               skip_next_in_line = 1;
713             }
714
715           /* First try `GNU style'.  */
716           p = strchr (oldq, '`');
717           if (p)
718             p++, q = strchr (p, '\'');
719           /* Then try "double quotes".  */
720           else if (p = strchr (oldq, '"'), p)
721             p++, q = strchr (p, '"');
722           /* Then try 'single quotes'.  */
723           else if (p = strchr (oldq, '\''), p)
724             p++, q = strchr (p, '\'');
725           else {
726             /* Then try entire line.  */
727             q = strchr (oldq, 0);
728             if (q != oldq)
729               p = (char *)oldq;
730           }
731
732           if (p)
733             {
734               /* Don't let the strstr's below see the demangled name; we
735                  might get spurious matches.  */
736               p[-1] = '\0';
737
738               /* powerpc64-linux references .foo when calling function foo.  */
739               if (*p == '.')
740                 p++;
741             }
742
743           /* We need to check for certain error keywords here, or we would
744              mistakenly use GNU ld's "In function `foo':" message.  */
745           if (q && (ok
746                     || strstr (oldq, "ndefined")
747                     || strstr (oldq, "nresolved")
748                     || strstr (oldq, "nsatisfied")
749                     || strstr (oldq, "ultiple")))
750             {
751               *q = 0;
752               dem = demangled_hash_lookup (p, false);
753               if (!dem)
754                 {
755                   if (!strncmp (p, USER_LABEL_PREFIX,
756                                 strlen (USER_LABEL_PREFIX)))
757                     p += strlen (USER_LABEL_PREFIX);
758                   sym = symbol_hash_lookup (p, false);
759                 }
760             }
761         }
762
763       if (dem)
764         {
765           /* We found a demangled name.  If this is the name of a
766              constructor or destructor, there can be several mangled names
767              that match it, so choose or unchoose all of them.  If some are
768              chosen and some not, leave the later ones that don't match
769              alone for now; either this will cause the link to succeed, or
770              on the next attempt we will switch all of them the other way
771              and that will cause it to succeed.  */
772           int chosen = 0;
773           int len = dem->mangled.length ();
774           ok = true;
775           FOR_EACH_VEC_ELT (dem->mangled, ix, s)
776             {
777               sym = symbol_hash_lookup (s, false);
778               if (ix == 0)
779                 chosen = sym->chosen;
780               else if (sym->chosen != chosen)
781                 /* Mismatch.  */
782                 continue;
783               /* Avoid an error about re-tweaking when we guess wrong in
784                  the case of mismatch.  */
785               if (len > 1)
786                 sym->tweaked = false;
787               ok = start_tweaking (sym);
788             }
789         }
790       else
791         ok = start_tweaking (sym);
792
793       obstack_free (&temporary_obstack, temporary_firstobj);
794
795       if (!ok)
796         {
797           fclose (stream);
798           return 0;
799         }
800     }
801
802   fclose (stream);
803   return (file_stack != NULL);
804 }
805
806 /* Entry point for tlink.  Called from main in collect2.c.
807
808    Iteratively try to provide definitions for all the unresolved symbols
809    mentioned in the linker error messages.
810
811    LD_ARGV is an array of arguments for the linker.
812    OBJECT_LST is an array of object files that we may be able to recompile
813      to provide missing definitions.  Currently ignored.  */
814
815 void
816 do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED)
817 {
818   int ret = tlink_execute ("ld", ld_argv, ldout, lderrout,
819                            HAVE_GNU_LD && at_file_supplied);
820
821   tlink_init ();
822
823   if (ret)
824     {
825       int i = 0;
826
827       /* Until collect does a better job of figuring out which are object
828          files, assume that everything on the command line could be.  */
829       if (read_repo_files (ld_argv))
830         while (ret && i++ < MAX_ITERATIONS)
831           {
832             if (tlink_verbose >= 3)
833               {
834                 dump_ld_file (ldout, stdout);
835                 dump_ld_file (lderrout, stderr);
836               }
837             demangle_new_symbols ();
838             if (! scan_linker_output (ldout)
839                 && ! scan_linker_output (lderrout))
840               break;
841             if (! recompile_files ())
842               break;
843             if (tlink_verbose)
844               fprintf (stderr, _("collect: relinking\n"));
845             ret = tlink_execute ("ld", ld_argv, ldout, lderrout,
846                                  HAVE_GNU_LD && at_file_supplied);
847           }
848     }
849
850   dump_ld_file (ldout, stdout);
851   unlink (ldout);
852   dump_ld_file (lderrout, stderr);
853   unlink (lderrout);
854   if (ret)
855     {
856       error ("ld returned %d exit status", ret);
857       exit (ret);
858     }
859   else
860     {
861       /* We have just successfully produced an output file, so assume that we
862          may unlink it if need be for now on.  */ 
863       may_unlink_output_file = true;
864     }
865 }