xref: /dragonfly/contrib/gcc-8.0/gcc/tlink.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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 
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
hash_string_eq(const void * s1_p,const void * s2_p)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
hash_string_hash(const void * s_p)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 *
symbol_hash_lookup(const char * string,int create)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 *
file_hash_lookup(const char * string)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 *
demangled_hash_lookup(const char * string,int create)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 
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
symbol_push(symbol * p)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 *
symbol_pop(void)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
file_push(file * p)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 *
file_pop(void)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 
250 /* Other machinery.  */
251 
252 /* Initialize the tlink machinery.  Called from do_tlink.  */
253 
254 static void
tlink_init(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
tlink_execute(const char * prog,char ** argv,const char * outname,const char * errname,bool use_atfile)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 *
frob_extension(const char * s,const char * ext)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 *
obstack_fgets(FILE * stream,struct obstack * ob)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 *
tfgets(FILE * stream)321 tfgets (FILE *stream)
322 {
323   return obstack_fgets (stream, &temporary_obstack);
324 }
325 
326 static char *
pfgets(FILE * stream)327 pfgets (FILE *stream)
328 {
329   return xstrdup (tfgets (stream));
330 }
331 
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
freadsym(FILE * stream,file * f,int chosen)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
read_repo_file(file * f)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
maybe_tweak(char * line,file * f)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
recompile_files(void)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
read_repo_files(char ** object_lst)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
demangle_new_symbols(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
start_tweaking(symbol * sym)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
scan_linker_output(const char * fname)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
do_tlink(char ** ld_argv,char ** object_lst ATTRIBUTE_UNUSED)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 }
866