Daily bump.
[gcc.git] / 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 }