OSDN Git Service

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