OSDN Git Service

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