Mercurial > hg > CbC > CbC_gcc
comparison gcc/tlink.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Scan linker error messages for missing template instantiations and provide | 1 /* Scan linker error messages for missing template instantiations and provide |
2 them. | 2 them. |
3 | 3 |
4 Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2007, 2008, | 4 Copyright (C) 1995-2017 Free Software Foundation, Inc. |
5 2009, 2010 Free Software Foundation, Inc. | |
6 Contributed by Jason Merrill (jason@cygnus.com). | 5 Contributed by Jason Merrill (jason@cygnus.com). |
7 | 6 |
8 This file is part of GCC. | 7 This file is part of GCC. |
9 | 8 |
10 GCC is free software; you can redistribute it and/or modify it under | 9 GCC is free software; you can redistribute it and/or modify it under |
25 #include "system.h" | 24 #include "system.h" |
26 #include "coretypes.h" | 25 #include "coretypes.h" |
27 #include "tm.h" | 26 #include "tm.h" |
28 #include "intl.h" | 27 #include "intl.h" |
29 #include "obstack.h" | 28 #include "obstack.h" |
30 #include "hashtab.h" | |
31 #include "demangle.h" | 29 #include "demangle.h" |
32 #include "collect2.h" | 30 #include "collect2.h" |
31 #include "collect-utils.h" | |
32 #include "filenames.h" | |
33 #include "diagnostic-core.h" | |
33 | 34 |
34 /* TARGET_64BIT may be defined to use driver specific functionality. */ | 35 /* TARGET_64BIT may be defined to use driver specific functionality. */ |
35 #undef TARGET_64BIT | 36 #undef TARGET_64BIT |
36 #define TARGET_64BIT TARGET_64BIT_DEFAULT | 37 #define TARGET_64BIT TARGET_64BIT_DEFAULT |
37 | 38 |
63 const char *dir; | 64 const char *dir; |
64 const char *main; | 65 const char *main; |
65 int tweaking; | 66 int tweaking; |
66 } file; | 67 } file; |
67 | 68 |
69 typedef const char *str; | |
70 | |
68 typedef struct demangled_hash_entry | 71 typedef struct demangled_hash_entry |
69 { | 72 { |
70 const char *key; | 73 const char *key; |
71 const char *mangled; | 74 vec<str> mangled; |
72 } demangled; | 75 } demangled; |
73 | 76 |
74 /* Hash and comparison functions for these hash tables. */ | 77 /* Hash and comparison functions for these hash tables. */ |
75 | 78 |
76 static int hash_string_eq (const void *, const void *); | 79 static int hash_string_eq (const void *, const void *); |
98 static struct demangled_hash_entry *demangled_hash_lookup (const char *, int); | 101 static struct demangled_hash_entry *demangled_hash_lookup (const char *, int); |
99 static void symbol_push (symbol *); | 102 static void symbol_push (symbol *); |
100 static symbol * symbol_pop (void); | 103 static symbol * symbol_pop (void); |
101 static void file_push (file *); | 104 static void file_push (file *); |
102 static file * file_pop (void); | 105 static file * file_pop (void); |
103 static void tlink_init (void); | |
104 static int tlink_execute (const char *, char **, const char *, const char *); | |
105 static char * frob_extension (const char *, const char *); | 106 static char * frob_extension (const char *, const char *); |
106 static char * obstack_fgets (FILE *, struct obstack *); | 107 static char * obstack_fgets (FILE *, struct obstack *); |
107 static char * tfgets (FILE *); | 108 static char * tfgets (FILE *); |
108 static char * pfgets (FILE *); | 109 static char * pfgets (FILE *); |
109 static void freadsym (FILE *, file *, int); | 110 static void freadsym (FILE *, file *, int); |
269 if (p) | 270 if (p) |
270 tlink_verbose = atoi (p); | 271 tlink_verbose = atoi (p); |
271 else | 272 else |
272 { | 273 { |
273 tlink_verbose = 1; | 274 tlink_verbose = 1; |
274 if (vflag) | 275 if (verbose) |
275 tlink_verbose = 2; | 276 tlink_verbose = 2; |
276 if (debug) | 277 if (debug) |
277 tlink_verbose = 3; | 278 tlink_verbose = 3; |
278 } | 279 } |
279 | 280 |
280 initial_cwd = getpwd (); | 281 initial_cwd = getpwd (); |
281 } | 282 } |
282 | 283 |
283 static int | 284 static int |
284 tlink_execute (const char *prog, char **argv, const char *outname, | 285 tlink_execute (const char *prog, char **argv, const char *outname, |
285 const char *errname) | 286 const char *errname, bool use_atfile) |
286 { | 287 { |
287 struct pex_obj *pex; | 288 struct pex_obj *pex; |
288 | 289 |
289 pex = collect_execute (prog, argv, outname, errname, PEX_LAST | PEX_SEARCH); | 290 pex = collect_execute (prog, argv, outname, errname, |
291 PEX_LAST | PEX_SEARCH, use_atfile); | |
290 return collect_wait (prog, pex); | 292 return collect_wait (prog, pex); |
291 } | 293 } |
292 | 294 |
293 static char * | 295 static char * |
294 frob_extension (const char *s, const char *ext) | 296 frob_extension (const char *s, const char *ext) |
295 { | 297 { |
296 const char *p = strrchr (s, '/'); | 298 const char *p; |
297 if (! p) | 299 |
298 p = s; | 300 p = strrchr (lbasename (s), '.'); |
299 p = strrchr (p, '.'); | |
300 if (! p) | 301 if (! p) |
301 p = s + strlen (s); | 302 p = s + strlen (s); |
302 | 303 |
303 obstack_grow (&temporary_obstack, s, p - s); | 304 obstack_grow (&temporary_obstack, s, p - s); |
304 return (char *) obstack_copy0 (&temporary_obstack, ext, strlen (ext)); | 305 return (char *) obstack_copy0 (&temporary_obstack, ext, strlen (ext)); |
432 { | 433 { |
433 sym->tweaking = 0; | 434 sym->tweaking = 0; |
434 sym->tweaked = 1; | 435 sym->tweaked = 1; |
435 | 436 |
436 if (line[0] == 'O') | 437 if (line[0] == 'O') |
437 line[0] = 'C'; | 438 { |
439 line[0] = 'C'; | |
440 sym->chosen = 1; | |
441 } | |
438 else | 442 else |
439 line[0] = 'O'; | 443 { |
444 line[0] = 'O'; | |
445 sym->chosen = 0; | |
446 } | |
440 } | 447 } |
441 } | 448 } |
442 | 449 |
443 /* Update the repo files for each of the object files we have adjusted and | 450 /* Update the repo files for each of the object files we have adjusted and |
444 recompile. */ | 451 recompile. */ |
475 fclose (output); | 482 fclose (output); |
476 /* On Windows "rename" returns -1 and sets ERRNO to EACCESS if | 483 /* On Windows "rename" returns -1 and sets ERRNO to EACCESS if |
477 the new file name already exists. Therefore, we explicitly | 484 the new file name already exists. Therefore, we explicitly |
478 remove the old file first. */ | 485 remove the old file first. */ |
479 if (remove (f->key) == -1) | 486 if (remove (f->key) == -1) |
480 fatal_perror ("removing .rpo file"); | 487 fatal_error (input_location, "removing .rpo file: %m"); |
481 if (rename (outname, f->key) == -1) | 488 if (rename (outname, f->key) == -1) |
482 fatal_perror ("renaming .rpo file"); | 489 fatal_error (input_location, "renaming .rpo file: %m"); |
483 | 490 |
484 if (!f->args) | 491 if (!f->args) |
485 { | 492 { |
486 error ("repository file '%s' does not contain command-line " | 493 error ("repository file '%s' does not contain command-line " |
487 "arguments", f->key); | 494 "arguments", f->key); |
534 | 541 |
535 if (tlink_verbose) | 542 if (tlink_verbose) |
536 fprintf (stderr, _("collect: recompiling %s\n"), f->main); | 543 fprintf (stderr, _("collect: recompiling %s\n"), f->main); |
537 | 544 |
538 if (chdir (f->dir) != 0 | 545 if (chdir (f->dir) != 0 |
539 || tlink_execute (c_file_name, argv, NULL, NULL) != 0 | 546 || tlink_execute (c_file_name, argv, NULL, NULL, false) != 0 |
540 || chdir (initial_cwd) != 0) | 547 || chdir (initial_cwd) != 0) |
541 return 0; | 548 return 0; |
542 | 549 |
543 read_repo_file (f); | 550 read_repo_file (f); |
544 | 551 |
595 | 602 |
596 if (! p) | 603 if (! p) |
597 continue; | 604 continue; |
598 | 605 |
599 dem = demangled_hash_lookup (p, true); | 606 dem = demangled_hash_lookup (p, true); |
600 dem->mangled = sym->key; | 607 dem->mangled.safe_push (sym->key); |
601 } | 608 } |
609 } | |
610 | |
611 /* We want to tweak symbol SYM. Return true if all is well, false on | |
612 error. */ | |
613 | |
614 static bool | |
615 start_tweaking (symbol *sym) | |
616 { | |
617 if (sym && sym->tweaked) | |
618 { | |
619 error ("'%s' was assigned to '%s', but was not defined " | |
620 "during recompilation, or vice versa", | |
621 sym->key, sym->file->key); | |
622 return 0; | |
623 } | |
624 if (sym && !sym->tweaking) | |
625 { | |
626 if (tlink_verbose >= 2) | |
627 fprintf (stderr, _("collect: tweaking %s in %s\n"), | |
628 sym->key, sym->file->key); | |
629 sym->tweaking = 1; | |
630 file_push (sym->file); | |
631 } | |
632 return true; | |
602 } | 633 } |
603 | 634 |
604 /* Step through the output of the linker, in the file named FNAME, and | 635 /* Step through the output of the linker, in the file named FNAME, and |
605 adjust the settings for each symbol encountered. */ | 636 adjust the settings for each symbol encountered. */ |
606 | 637 |
613 | 644 |
614 while ((line = tfgets (stream)) != NULL) | 645 while ((line = tfgets (stream)) != NULL) |
615 { | 646 { |
616 char *p = line, *q; | 647 char *p = line, *q; |
617 symbol *sym; | 648 symbol *sym; |
649 demangled *dem = 0; | |
618 int end; | 650 int end; |
619 int ok = 0; | 651 int ok = 0; |
652 unsigned ix; | |
653 str s; | |
620 | 654 |
621 /* On darwin9, we might have to skip " in " lines as well. */ | 655 /* On darwin9, we might have to skip " in " lines as well. */ |
622 if (skip_next_in_line | 656 if (skip_next_in_line |
623 && strstr (p, " in ")) | 657 && strstr (p, " in ")) |
624 continue; | 658 continue; |
659 | 693 |
660 if (! sym && ! end) | 694 if (! sym && ! end) |
661 /* Try a mangled name in quotes. */ | 695 /* Try a mangled name in quotes. */ |
662 { | 696 { |
663 char *oldq = q + 1; | 697 char *oldq = q + 1; |
664 demangled *dem = 0; | |
665 q = 0; | 698 q = 0; |
666 | 699 |
667 /* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)* */ | 700 /* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)* */ |
668 if (strcmp (oldq, "referenced from:") == 0) | 701 if (strcmp (oldq, "referenced from:") == 0) |
669 { | 702 { |
715 || strstr (oldq, "nsatisfied") | 748 || strstr (oldq, "nsatisfied") |
716 || strstr (oldq, "ultiple"))) | 749 || strstr (oldq, "ultiple"))) |
717 { | 750 { |
718 *q = 0; | 751 *q = 0; |
719 dem = demangled_hash_lookup (p, false); | 752 dem = demangled_hash_lookup (p, false); |
720 if (dem) | 753 if (!dem) |
721 sym = symbol_hash_lookup (dem->mangled, false); | |
722 else | |
723 { | 754 { |
724 if (!strncmp (p, USER_LABEL_PREFIX, | 755 if (!strncmp (p, USER_LABEL_PREFIX, |
725 strlen (USER_LABEL_PREFIX))) | 756 strlen (USER_LABEL_PREFIX))) |
726 p += strlen (USER_LABEL_PREFIX); | 757 p += strlen (USER_LABEL_PREFIX); |
727 sym = symbol_hash_lookup (p, false); | 758 sym = symbol_hash_lookup (p, false); |
728 } | 759 } |
729 } | 760 } |
730 } | 761 } |
731 | 762 |
732 if (sym && sym->tweaked) | 763 if (dem) |
733 { | 764 { |
734 error ("'%s' was assigned to '%s', but was not defined " | 765 /* We found a demangled name. If this is the name of a |
735 "during recompilation, or vice versa", | 766 constructor or destructor, there can be several mangled names |
736 sym->key, sym->file->key); | 767 that match it, so choose or unchoose all of them. If some are |
768 chosen and some not, leave the later ones that don't match | |
769 alone for now; either this will cause the link to succeed, or | |
770 on the next attempt we will switch all of them the other way | |
771 and that will cause it to succeed. */ | |
772 int chosen = 0; | |
773 int len = dem->mangled.length (); | |
774 ok = true; | |
775 FOR_EACH_VEC_ELT (dem->mangled, ix, s) | |
776 { | |
777 sym = symbol_hash_lookup (s, false); | |
778 if (ix == 0) | |
779 chosen = sym->chosen; | |
780 else if (sym->chosen != chosen) | |
781 /* Mismatch. */ | |
782 continue; | |
783 /* Avoid an error about re-tweaking when we guess wrong in | |
784 the case of mismatch. */ | |
785 if (len > 1) | |
786 sym->tweaked = false; | |
787 ok = start_tweaking (sym); | |
788 } | |
789 } | |
790 else | |
791 ok = start_tweaking (sym); | |
792 | |
793 obstack_free (&temporary_obstack, temporary_firstobj); | |
794 | |
795 if (!ok) | |
796 { | |
737 fclose (stream); | 797 fclose (stream); |
738 return 0; | 798 return 0; |
739 } | 799 } |
740 if (sym && !sym->tweaking) | |
741 { | |
742 if (tlink_verbose >= 2) | |
743 fprintf (stderr, _("collect: tweaking %s in %s\n"), | |
744 sym->key, sym->file->key); | |
745 sym->tweaking = 1; | |
746 file_push (sym->file); | |
747 } | |
748 | |
749 obstack_free (&temporary_obstack, temporary_firstobj); | |
750 } | 800 } |
751 | 801 |
752 fclose (stream); | 802 fclose (stream); |
753 return (file_stack != NULL); | 803 return (file_stack != NULL); |
754 } | 804 } |
763 to provide missing definitions. Currently ignored. */ | 813 to provide missing definitions. Currently ignored. */ |
764 | 814 |
765 void | 815 void |
766 do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED) | 816 do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED) |
767 { | 817 { |
768 int exit = tlink_execute ("ld", ld_argv, ldout, lderrout); | 818 int ret = tlink_execute ("ld", ld_argv, ldout, lderrout, |
819 HAVE_GNU_LD && at_file_supplied); | |
769 | 820 |
770 tlink_init (); | 821 tlink_init (); |
771 | 822 |
772 if (exit) | 823 if (ret) |
773 { | 824 { |
774 int i = 0; | 825 int i = 0; |
775 | 826 |
776 /* Until collect does a better job of figuring out which are object | 827 /* Until collect does a better job of figuring out which are object |
777 files, assume that everything on the command line could be. */ | 828 files, assume that everything on the command line could be. */ |
778 if (read_repo_files (ld_argv)) | 829 if (read_repo_files (ld_argv)) |
779 while (exit && i++ < MAX_ITERATIONS) | 830 while (ret && i++ < MAX_ITERATIONS) |
780 { | 831 { |
781 if (tlink_verbose >= 3) | 832 if (tlink_verbose >= 3) |
782 { | 833 { |
783 dump_file (ldout, stdout); | 834 dump_ld_file (ldout, stdout); |
784 dump_file (lderrout, stderr); | 835 dump_ld_file (lderrout, stderr); |
785 } | 836 } |
786 demangle_new_symbols (); | 837 demangle_new_symbols (); |
787 if (! scan_linker_output (ldout) | 838 if (! scan_linker_output (ldout) |
788 && ! scan_linker_output (lderrout)) | 839 && ! scan_linker_output (lderrout)) |
789 break; | 840 break; |
790 if (! recompile_files ()) | 841 if (! recompile_files ()) |
791 break; | 842 break; |
792 if (tlink_verbose) | 843 if (tlink_verbose) |
793 fprintf (stderr, _("collect: relinking\n")); | 844 fprintf (stderr, _("collect: relinking\n")); |
794 exit = tlink_execute ("ld", ld_argv, ldout, lderrout); | 845 ret = tlink_execute ("ld", ld_argv, ldout, lderrout, |
846 HAVE_GNU_LD && at_file_supplied); | |
795 } | 847 } |
796 } | 848 } |
797 | 849 |
798 dump_file (ldout, stdout); | 850 dump_ld_file (ldout, stdout); |
799 unlink (ldout); | 851 unlink (ldout); |
800 dump_file (lderrout, stderr); | 852 dump_ld_file (lderrout, stderr); |
801 unlink (lderrout); | 853 unlink (lderrout); |
802 if (exit) | 854 if (ret) |
803 { | 855 { |
804 error ("ld returned %d exit status", exit); | 856 error ("ld returned %d exit status", ret); |
805 collect_exit (exit); | 857 exit (ret); |
806 } | 858 } |
807 } | 859 else |
860 { | |
861 /* We have just successfully produced an output file, so assume that we | |
862 may unlink it if need be for now on. */ | |
863 may_unlink_output_file = true; | |
864 } | |
865 } |