OSDN Git Service

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