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