OSDN Git Service

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