OSDN Git Service

* c-lang.c (finish_file): Bracket declaration of static_ctors,
[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 Free Software Foundation, Inc.
5    Contributed by Jason Merrill (jason@cygnus.com).
6
7 This file is part of GNU CC.
8
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
22
23 #include <stdio.h>
24 #include <ctype.h>
25 #include "config.h"
26 #include "hash.h"
27 #include "demangle.h"
28
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36
37 #ifdef HAVE_STRING_H
38 #include <string.h>
39 #else
40 #ifdef HAVE_STRINGS_H
41 #include <strings.h>
42 #endif
43 #endif
44
45 #define MAX_ITERATIONS 17
46
47 /* Obstack allocation and deallocation routines.  */
48 #define obstack_chunk_alloc xmalloc
49 #define obstack_chunk_free free
50
51 extern char * xmalloc PARAMS((unsigned));
52 extern void free ();
53 extern char * getenv ();
54
55 /* Defined in collect2.c.  */
56 extern int vflag, debug;
57 extern char *ldout;
58 extern char *c_file_name;
59 extern struct obstack temporary_obstack;
60 extern struct obstack permanent_obstack;
61 extern char * temporary_firstobj;
62
63 /* Defined in the automatically-generated underscore.c.  */
64 extern int prepends_underscore;
65
66 static int tlink_verbose;
67 \f
68 /* Hash table code.  */
69
70 typedef struct symbol_hash_entry
71 {
72   struct hash_entry root;
73   struct file_hash_entry *file;
74   int chosen;
75   int tweaking;
76   int tweaked;
77 } symbol;
78
79 typedef struct file_hash_entry
80 {
81   struct hash_entry root;
82   const char *args;
83   const char *dir;
84   const char *main;
85   int tweaking;
86 } file;
87
88 typedef struct demangled_hash_entry
89 {
90   struct hash_entry root;
91   const char *mangled;
92 } demangled;
93
94 static struct hash_table symbol_table;
95
96 static struct hash_entry *
97 symbol_hash_newfunc (entry, table, string)
98      struct hash_entry *entry;
99      struct hash_table *table;
100      const char *string;
101 {
102   struct symbol_hash_entry *ret = (struct symbol_hash_entry *) entry;
103   if (ret == NULL)
104     {
105       ret = ((struct symbol_hash_entry *)
106              hash_allocate (table, sizeof (struct symbol_hash_entry)));
107       if (ret == NULL)
108         return NULL;
109     }
110   ret = ((struct symbol_hash_entry *)
111          hash_newfunc ((struct hash_entry *) ret, table, string));
112   ret->file = NULL;
113   ret->chosen = 0;
114   ret->tweaking = 0;
115   ret->tweaked = 0;
116   return (struct hash_entry *) ret;
117 }
118
119 static struct symbol_hash_entry *
120 symbol_hash_lookup (string, create)
121      const char *string;
122      boolean create;
123 {
124   return ((struct symbol_hash_entry *)
125           hash_lookup (&symbol_table, string, create, true));
126 }
127
128 static struct hash_table file_table;
129
130 static struct hash_entry *
131 file_hash_newfunc (entry, table, string)
132      struct hash_entry *entry;
133      struct hash_table *table;
134      const char *string;
135 {
136    struct file_hash_entry *ret = (struct file_hash_entry *) entry;
137   if (ret == NULL)
138     {
139       ret = ((struct file_hash_entry *)
140              hash_allocate (table, sizeof (struct file_hash_entry)));
141       if (ret == NULL)
142         return NULL;
143     }
144   ret = ((struct file_hash_entry *)
145          hash_newfunc ((struct hash_entry *) ret, table, string));
146   ret->args = NULL;
147   ret->dir = NULL;
148   ret->main = NULL;
149   ret->tweaking = 0;
150   return (struct hash_entry *) ret;
151 }
152
153 static struct file_hash_entry *
154 file_hash_lookup (string)
155      const char *string;
156 {
157   return ((struct file_hash_entry *)
158           hash_lookup (&file_table, string, true, true));
159 }
160
161 static struct hash_table demangled_table;
162
163 static struct hash_entry *
164 demangled_hash_newfunc (entry, table, string)
165      struct hash_entry *entry;
166      struct hash_table *table;
167      const char *string;
168 {
169   struct demangled_hash_entry *ret = (struct demangled_hash_entry *) entry;
170   if (ret == NULL)
171     {
172       ret = ((struct demangled_hash_entry *)
173              hash_allocate (table, sizeof (struct demangled_hash_entry)));
174       if (ret == NULL)
175         return NULL;
176     }
177   ret = ((struct demangled_hash_entry *)
178          hash_newfunc ((struct hash_entry *) ret, table, string));
179   ret->mangled = NULL;
180   return (struct hash_entry *) ret;
181 }
182
183 static struct demangled_hash_entry *
184 demangled_hash_lookup (string, create)
185      const char *string;
186      boolean create;
187 {
188   return ((struct demangled_hash_entry *)
189           hash_lookup (&demangled_table, string, create, true));
190 }
191 \f
192 /* Stack code.  */
193
194 struct symbol_stack_entry
195 {
196   symbol *value;
197   struct symbol_stack_entry *next;
198 };
199 struct obstack symbol_stack_obstack;
200 struct symbol_stack_entry *symbol_stack;
201
202 struct file_stack_entry
203 {
204   file *value;
205   struct file_stack_entry *next;
206 };
207 struct obstack file_stack_obstack;
208 struct file_stack_entry *file_stack;
209
210 static void
211 symbol_push (p)
212      symbol *p;
213 {
214   struct symbol_stack_entry *ep = (struct symbol_stack_entry *) obstack_alloc
215     (&symbol_stack_obstack, sizeof (struct symbol_stack_entry));
216   ep->value = p;
217   ep->next = symbol_stack;
218   symbol_stack = ep;
219 }
220
221 static symbol *
222 symbol_pop ()
223 {
224   struct symbol_stack_entry *ep = symbol_stack;
225   symbol *p;
226   if (ep == NULL)
227     return NULL;
228   p = ep->value;
229   symbol_stack = ep->next;
230   obstack_free (&symbol_stack_obstack, ep);
231   return p;
232 }
233
234 static void
235 file_push (p)
236      file *p;
237 {
238   struct file_stack_entry *ep;
239
240   if (p->tweaking)
241     return;
242
243   ep = (struct file_stack_entry *) obstack_alloc
244     (&file_stack_obstack, sizeof (struct file_stack_entry));
245   ep->value = p;
246   ep->next = file_stack;
247   file_stack = ep;
248   p->tweaking = 1;
249 }
250
251 static file *
252 file_pop ()
253 {
254   struct file_stack_entry *ep = file_stack;
255   file *p;
256   if (ep == NULL)
257     return NULL;
258   p = ep->value;
259   file_stack = ep->next;
260   obstack_free (&file_stack_obstack, ep);
261   p->tweaking = 0;
262   return p;
263 }
264 \f
265 /* Other machinery.  */
266
267 static void
268 tlink_init ()
269 {
270   char *p;
271
272   hash_table_init (&symbol_table, symbol_hash_newfunc);
273   hash_table_init (&file_table, file_hash_newfunc);
274   hash_table_init (&demangled_table, demangled_hash_newfunc);
275   obstack_begin (&symbol_stack_obstack, 0);
276   obstack_begin (&file_stack_obstack, 0);
277
278   p = getenv ("TLINK_VERBOSE");
279   if (p)
280     tlink_verbose = atoi (p);
281   else
282     {
283       tlink_verbose = 1;
284       if (vflag)
285         tlink_verbose = 2;
286       if (debug)
287         tlink_verbose = 3;
288     }
289 }
290
291 static int
292 tlink_execute (prog, argv, redir)
293      char *prog;
294      char **argv;
295      char *redir;
296 {
297   collect_execute (prog, argv, redir);
298   return collect_wait (prog);
299
300
301 static char *
302 frob_extension (s, ext)
303      char *s, *ext;
304 {
305   char *p = (char *) rindex (s, '/');
306   if (! p)
307     p = s;
308   p = (char *) rindex (p, '.');
309   if (! p)
310     p = s + strlen (s);
311
312   obstack_grow (&temporary_obstack, s, p - s);
313   return obstack_copy0 (&temporary_obstack, ext, strlen (ext));
314 }
315
316 static char *
317 obstack_fgets (stream, ob)
318      FILE *stream;
319      struct obstack *ob;
320 {
321   int c;
322   while ((c = getc (stream)) != EOF && c != '\n')
323     obstack_1grow (ob, c);
324   if (obstack_object_size (ob) == 0)
325     return NULL;
326   obstack_1grow (ob, '\0');
327   return obstack_finish (ob);
328 }
329
330 static char *
331 tfgets (stream)
332      FILE *stream;
333 {
334   return obstack_fgets (stream, &temporary_obstack);
335 }
336
337 static char *
338 pfgets (stream)
339      FILE *stream;
340 {
341   return obstack_fgets (stream, &permanent_obstack);
342 }
343 \f
344 /* Real tlink code.  */
345
346 static void
347 freadsym (stream, f, chosen)
348      FILE *stream;
349      file *f;
350      int chosen;
351 {
352   symbol *sym;
353
354   {
355     char *name = tfgets (stream);
356     sym = symbol_hash_lookup (name, true);
357   }
358
359   if (sym->file == NULL)
360     {
361       symbol_push (sym);
362       sym->file = f;
363       sym->chosen = chosen;
364     }
365   else if (chosen)
366     {
367       if (sym->chosen && sym->file != f)
368         {
369           if (sym->chosen == 1)
370             file_push (sym->file);
371           else
372             {
373               file_push (f);
374               f = sym->file;
375               chosen = sym->chosen;
376             }
377         }
378       sym->file = f;
379       sym->chosen = chosen;
380     }
381 }
382
383 static void
384 read_repo_file (f)
385      file *f;
386 {
387   char c;
388   FILE *stream = fopen (f->root.string, "r");
389
390   if (tlink_verbose >= 2)
391     fprintf (stderr, "collect: reading %s\n", f->root.string);
392
393   while (fscanf (stream, "%c ", &c) == 1)
394     {
395       switch (c)
396         {
397         case 'A':
398           f->args = pfgets (stream);
399           break;
400         case 'D':
401           f->dir = pfgets (stream);
402           break;
403         case 'M':
404           f->main = pfgets (stream);
405           break;
406         case 'P':
407           freadsym (stream, f, 2);
408           break;
409         case 'C':
410           freadsym (stream, f, 1);
411           break;
412         case 'O':
413           freadsym (stream, f, 0);
414           break;
415         }
416       obstack_free (&temporary_obstack, temporary_firstobj);
417     }
418   fclose (stream);
419   if (f->args == NULL)
420     f->args = getenv ("COLLECT_GCC_OPTIONS");
421   if (f->dir == NULL)
422     f->dir = ".";
423 }
424
425 static void
426 maybe_tweak (line, f)
427      char *line;
428      file *f;
429 {
430   symbol *sym = symbol_hash_lookup (line + 2, false);
431
432   if ((sym->file == f && sym->tweaking)
433       || (sym->file != f && line[0] == 'C'))
434     {
435       sym->tweaking = 0;
436       sym->tweaked = 1;
437
438       if (line[0] == 'O')
439         line[0] = 'C';
440       else
441         line[0] = 'O';
442     }
443 }
444
445 static int
446 recompile_files ()
447 {
448   file *f;
449
450   while ((f = file_pop ()) != NULL)
451     {
452       char *line, *command;
453       FILE *stream = fopen (f->root.string, "r");
454       char *outname = frob_extension (f->root.string, ".rnw");
455       FILE *output = fopen (outname, "w");
456
457       while ((line = tfgets (stream)) != NULL)
458         {
459           switch (line[0])
460             {
461             case 'C':
462             case 'O':
463               maybe_tweak (line, f);
464             }
465           fprintf (output, "%s\n", line);
466         }
467       fclose (stream);
468       fclose (output);
469       rename (outname, f->root.string);
470
471       obstack_grow (&temporary_obstack, "cd ", 3);
472       obstack_grow (&temporary_obstack, f->dir, strlen (f->dir));
473       obstack_grow (&temporary_obstack, "; ", 2);
474       obstack_grow (&temporary_obstack, c_file_name, strlen (c_file_name));
475       obstack_1grow (&temporary_obstack, ' ');
476       obstack_grow (&temporary_obstack, f->args, strlen (f->args));
477       obstack_1grow (&temporary_obstack, ' ');
478       command = obstack_copy0 (&temporary_obstack, f->main, strlen (f->main));
479
480       if (tlink_verbose)
481         fprintf (stderr, "collect: recompiling %s\n", f->main);
482       if (tlink_verbose >= 3)
483         fprintf (stderr, "%s\n", command);
484
485       if (system (command) != 0)
486         return 0;
487
488       read_repo_file (f);
489
490       obstack_free (&temporary_obstack, temporary_firstobj);
491     }
492   return 1;
493 }
494
495 static int
496 read_repo_files (object_lst)
497      char **object_lst;
498 {
499   char **object = object_lst;
500
501   for (; *object; object++)
502     {
503       char *p = frob_extension (*object, ".rpo");
504       file *f;
505
506       if (! file_exists (p))
507         continue;
508
509       f = file_hash_lookup (p);
510
511       read_repo_file (f);
512     }
513
514   if (file_stack != NULL && ! recompile_files ())
515     return 0;
516
517   return (symbol_stack != NULL);
518 }
519
520 static void
521 demangle_new_symbols ()
522 {
523   symbol *sym;
524
525   while ((sym = symbol_pop ()) != NULL)
526     {
527       demangled *dem;
528       char *p = cplus_demangle (sym->root.string, DMGL_PARAMS | DMGL_ANSI);
529
530       if (! p)
531         continue;
532
533       dem = demangled_hash_lookup (p, true);
534       dem->mangled = sym->root.string;
535     }
536 }
537
538 static int
539 scan_linker_output (fname)
540      char *fname;
541 {
542   FILE *stream = fopen (fname, "r");
543   char *line;
544
545   while ((line = tfgets (stream)) != NULL)
546     {
547       char *p = line, *q;
548       symbol *sym;
549       int end;
550       
551       while (*p && isspace (*p))
552         ++p;
553
554       if (! *p)
555         continue;
556
557       for (q = p; *q && ! isspace (*q); ++q)
558         ;
559
560       /* Try the first word on the line.  */
561       if (*p == '.')
562         ++p;
563       if (*p == '_' && prepends_underscore)
564         ++p;
565
566       end = ! *q;
567       *q = 0;
568       sym = symbol_hash_lookup (p, false);
569
570       if (! sym && ! end)
571         /* Try a mangled name in `quotes'.  */
572         {
573           demangled *dem = 0;
574           p = (char *) index (q+1, '`');
575           q = 0;
576
577 #define MUL "multiple definition of "
578 #define UND "undefined reference to "
579
580           if (p && (p - line > sizeof (MUL)))
581             {
582               char *beg = p - sizeof (MUL) + 1;
583               *p = 0;
584               if (!strcmp (beg, MUL) || !strcmp (beg, UND))
585                 p++, q = (char *) index (p, '\'');
586             }
587           if (q)
588             *q = 0, dem = demangled_hash_lookup (p, false);
589           if (dem)
590             sym = symbol_hash_lookup (dem->mangled, false);
591         }
592
593       if (sym && sym->tweaked)
594         {
595           fclose (stream);
596           return 0;
597         }
598       if (sym && !sym->tweaking)
599         {
600           if (tlink_verbose >= 2)
601             fprintf (stderr, "collect: tweaking %s in %s\n",
602                      sym->root.string, sym->file->root.string);
603           sym->tweaking = 1;
604           file_push (sym->file);
605         }
606         
607       obstack_free (&temporary_obstack, temporary_firstobj);
608     }
609
610   fclose (stream);
611   return (file_stack != NULL);
612 }
613
614 void
615 do_tlink (ld_argv, object_lst)
616      char **ld_argv, **object_lst;
617 {
618   int exit = tlink_execute ("ld", ld_argv, ldout);
619
620   tlink_init ();
621
622   if (exit)
623     {
624       int i = 0;
625
626       /* Until collect does a better job of figuring out which are object
627          files, assume that everything on the command line could be.  */
628       if (read_repo_files (ld_argv))
629         while (exit && i++ < MAX_ITERATIONS)
630           {
631             if (tlink_verbose >= 3)
632               dump_file (ldout);
633             demangle_new_symbols ();
634             if (! scan_linker_output (ldout))
635               break;
636             if (! recompile_files ())
637               break;
638             if (tlink_verbose)
639               fprintf (stderr, "collect: relinking\n");
640             exit = tlink_execute ("ld", ld_argv, ldout);
641           }
642     }
643
644   dump_file (ldout);
645   unlink (ldout);
646   if (exit)
647     {
648       error ("ld returned %d exit status", exit);
649       collect_exit (exit);
650     }
651 }