OSDN Git Service

Add dbg count support for ccp
[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 #include "libiberty.h"
34
35 #define MAX_ITERATIONS 17
36
37 /* Defined in the automatically-generated underscore.c.  */
38 extern int prepends_underscore;
39
40 static int tlink_verbose;
41
42 static char *initial_cwd;
43 \f
44 /* Hash table boilerplate for working with htab_t.  We have hash tables
45    for symbol names, file names, and demangled symbols.  */
46
47 typedef struct symbol_hash_entry
48 {
49   const char *key;
50   struct file_hash_entry *file;
51   int chosen;
52   int tweaking;
53   int tweaked;
54 } symbol;
55
56 typedef struct file_hash_entry
57 {
58   const char *key;
59   const char *args;
60   const char *dir;
61   const char *main;
62   int tweaking;
63 } file;
64
65 typedef struct demangled_hash_entry
66 {
67   const char *key;
68   const char *mangled;
69 } demangled;
70
71 /* Hash and comparison functions for these hash tables.  */
72
73 static int hash_string_eq (const void *, const void *);
74 static hashval_t hash_string_hash (const void *);
75
76 static int
77 hash_string_eq (const void *s1_p, const void *s2_p)
78 {
79   const char *const *s1 = (const char *const *) s1_p;
80   const char *s2 = (const char *) s2_p;
81   return strcmp (*s1, s2) == 0;
82 }
83
84 static hashval_t
85 hash_string_hash (const void *s_p)
86 {
87   const char *const *s = (const char *const *) s_p;
88   return (*htab_hash_string) (*s);
89 }
90
91 static htab_t symbol_table;
92
93 static struct symbol_hash_entry * symbol_hash_lookup (const char *, int);
94 static struct file_hash_entry * file_hash_lookup (const char *);
95 static struct demangled_hash_entry *demangled_hash_lookup (const char *, int);
96 static void symbol_push (symbol *);
97 static symbol * symbol_pop (void);
98 static void file_push (file *);
99 static file * file_pop (void);
100 static void tlink_init (void);
101 static int tlink_execute (const char *, char **, const char *, const char *);
102 static char * frob_extension (const char *, const char *);
103 static char * obstack_fgets (FILE *, struct obstack *);
104 static char * tfgets (FILE *);
105 static char * pfgets (FILE *);
106 static void freadsym (FILE *, file *, int);
107 static void read_repo_file (file *);
108 static void maybe_tweak (char *, file *);
109 static int recompile_files (void);
110 static int read_repo_files (char **);
111 static void demangle_new_symbols (void);
112 static int scan_linker_output (const char *);
113
114 /* Look up an entry in the symbol hash table.  */
115
116 static struct symbol_hash_entry *
117 symbol_hash_lookup (const char *string, int create)
118 {
119   void **e;
120   e = htab_find_slot_with_hash (symbol_table, string,
121                                 (*htab_hash_string) (string),
122                                 create ? INSERT : NO_INSERT);
123   if (e == NULL)
124     return NULL;
125   if (*e == NULL)
126     {
127       struct symbol_hash_entry *v;
128       *e = v = XCNEW (struct symbol_hash_entry);
129       v->key = xstrdup (string);
130     }
131   return (struct symbol_hash_entry *) *e;
132 }
133
134 static htab_t file_table;
135
136 /* Look up an entry in the file hash table.  */
137
138 static struct file_hash_entry *
139 file_hash_lookup (const char *string)
140 {
141   void **e;
142   e = htab_find_slot_with_hash (file_table, string,
143                                 (*htab_hash_string) (string),
144                                 INSERT);
145   if (*e == NULL)
146     {
147       struct file_hash_entry *v;
148       *e = v = XCNEW (struct file_hash_entry);
149       v->key = xstrdup (string);
150     }
151   return (struct file_hash_entry *) *e;
152 }
153
154 static htab_t demangled_table;
155
156 /* Look up an entry in the demangled name hash table.  */
157
158 static struct demangled_hash_entry *
159 demangled_hash_lookup (const char *string, int create)
160 {
161   void **e;
162   e = htab_find_slot_with_hash (demangled_table, string,
163                                 (*htab_hash_string) (string),
164                                 create ? INSERT : NO_INSERT);
165   if (e == NULL)
166     return NULL;
167   if (*e == NULL)
168     {
169       struct demangled_hash_entry *v;
170       *e = v = XCNEW (struct demangled_hash_entry);
171       v->key = xstrdup (string);
172     }
173   return (struct demangled_hash_entry *) *e;
174 }
175 \f
176 /* Stack code.  */
177
178 struct symbol_stack_entry
179 {
180   symbol *value;
181   struct symbol_stack_entry *next;
182 };
183 struct obstack symbol_stack_obstack;
184 struct symbol_stack_entry *symbol_stack;
185
186 struct file_stack_entry
187 {
188   file *value;
189   struct file_stack_entry *next;
190 };
191 struct obstack file_stack_obstack;
192 struct file_stack_entry *file_stack;
193
194 static void
195 symbol_push (symbol *p)
196 {
197   struct symbol_stack_entry *ep
198     = XOBNEW (&symbol_stack_obstack, struct symbol_stack_entry);
199   ep->value = p;
200   ep->next = symbol_stack;
201   symbol_stack = ep;
202 }
203
204 static symbol *
205 symbol_pop (void)
206 {
207   struct symbol_stack_entry *ep = symbol_stack;
208   symbol *p;
209   if (ep == NULL)
210     return NULL;
211   p = ep->value;
212   symbol_stack = ep->next;
213   obstack_free (&symbol_stack_obstack, ep);
214   return p;
215 }
216
217 static void
218 file_push (file *p)
219 {
220   struct file_stack_entry *ep;
221
222   if (p->tweaking)
223     return;
224
225   ep = XOBNEW (&file_stack_obstack, 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   initial_cwd = getpwd ();
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 (char *) 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           /* Then try 'single quotes'.  */
687           else if (p = strchr (oldq, '\''), p)
688             p++, q = strchr (p, '\'');
689           else {
690             /* Then try entire line.  */
691             q = strchr (oldq, 0);
692             if (q != oldq)
693               p = (char *)oldq;
694           }
695
696           if (p)
697             {
698               /* Don't let the strstr's below see the demangled name; we
699                  might get spurious matches.  */
700               p[-1] = '\0';
701
702               /* powerpc64-linux references .foo when calling function foo.  */
703               if (*p == '.')
704                 p++;
705             }
706
707           /* We need to check for certain error keywords here, or we would
708              mistakenly use GNU ld's "In function `foo':" message.  */
709           if (q && (ok
710                     || strstr (oldq, "ndefined")
711                     || strstr (oldq, "nresolved")
712                     || strstr (oldq, "nsatisfied")
713                     || strstr (oldq, "ultiple")))
714             {
715               *q = 0;
716               dem = demangled_hash_lookup (p, false);
717               if (dem)
718                 sym = symbol_hash_lookup (dem->mangled, false);
719               else
720                 {
721                   if (!strncmp (p, USER_LABEL_PREFIX,
722                                 strlen (USER_LABEL_PREFIX)))
723                     p += strlen (USER_LABEL_PREFIX);
724                   sym = symbol_hash_lookup (p, false);
725                 }
726             }
727         }
728
729       if (sym && sym->tweaked)
730         {
731           error ("'%s' was assigned to '%s', but was not defined "
732                  "during recompilation, or vice versa", 
733                  sym->key, sym->file->key);
734           fclose (stream);
735           return 0;
736         }
737       if (sym && !sym->tweaking)
738         {
739           if (tlink_verbose >= 2)
740             fprintf (stderr, _("collect: tweaking %s in %s\n"),
741                      sym->key, sym->file->key);
742           sym->tweaking = 1;
743           file_push (sym->file);
744         }
745
746       obstack_free (&temporary_obstack, temporary_firstobj);
747     }
748
749   fclose (stream);
750   return (file_stack != NULL);
751 }
752
753 /* Entry point for tlink.  Called from main in collect2.c.
754
755    Iteratively try to provide definitions for all the unresolved symbols
756    mentioned in the linker error messages.
757
758    LD_ARGV is an array of arguments for the linker.
759    OBJECT_LST is an array of object files that we may be able to recompile
760      to provide missing definitions.  Currently ignored.  */
761
762 void
763 do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED)
764 {
765   int exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
766
767   tlink_init ();
768
769   if (exit)
770     {
771       int i = 0;
772
773       /* Until collect does a better job of figuring out which are object
774          files, assume that everything on the command line could be.  */
775       if (read_repo_files (ld_argv))
776         while (exit && i++ < MAX_ITERATIONS)
777           {
778             if (tlink_verbose >= 3)
779               {
780                 dump_file (ldout, stdout);
781                 dump_file (lderrout, stderr);
782               }
783             demangle_new_symbols ();
784             if (! scan_linker_output (ldout)
785                 && ! scan_linker_output (lderrout))
786               break;
787             if (! recompile_files ())
788               break;
789             if (tlink_verbose)
790               fprintf (stderr, _("collect: relinking\n"));
791             exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
792           }
793     }
794
795   dump_file (ldout, stdout);
796   unlink (ldout);
797   dump_file (lderrout, stderr);
798   unlink (lderrout);
799   if (exit)
800     {
801       error ("ld returned %d exit status", exit);
802       collect_exit (exit);
803     }
804 }