Rev 1 | Rev 4 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1 | Rev 2 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | // QNX 8.0 linker driver by Pierre-Marie Baty <pm@pmbaty.com> |
1 | // QNX 8.0 'gcc' linker driver drop-in replacement by Pierre-Marie Baty <pm@pmbaty.com> |
2 | 2 | ||
3 | // RATIONALE |
3 | // RATIONALE |
4 | // until a proper QNXToolchain class is implemented in the Clang driver, Clang relies on GNU GCC to drive the system linker 'ld'. |
4 | // until a proper QNXToolchain class is implemented in the Clang driver, Clang relies on GNU GCC to drive the system linker 'ld'. |
5 | // So we *HAVE* to provide a 'gcc' executable for Clang to be able to link QNX files. |
5 | // So we *HAVE* to provide a 'gcc' executable for Clang to be able to link QNX files. |
6 | // GNU GCC is itself a driver which can also invoke a compiler or a linker (gcc invokes collect2 which in turn invokes ld). |
6 | // GNU GCC is itself a driver which can also invoke a compiler or a linker (gcc invokes collect2 which in turn invokes ld). |
7 | // This means our GCC will need to either chain-call 'clang' when it is called for *compiling* and chain-call 'ld' when it is called for *linking*. |
7 | // This means our GCC will need to either chain-call 'clang' when it is called for *compiling* and chain-call 'ld' when it is called for *linking*. |
8 | // When proper support is added to it, GNU GCC contains a linker specification for the system which it uses to construct the linker command line. |
8 | // When proper support is added to it, GNU GCC contains a linker specification for the system which it uses to construct the linker command line. |
9 | // The linker specifications for QNX 8.0 can be extracted from '<target triple>-gcc -dumpspecs' and have been reimplemented in this file. |
9 | // The linker specifications for QNX 8.0 can be extracted from '<target triple>-gcc -dumpspecs' and have been reimplemented in this file. |
10 | // The GNU specs language is documented here: https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html |
10 | // The GNU specs language is documented here: https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html |
- | 11 | ||
- | 12 | // environment variables: |
|
- | 13 | // DEBUG_LINKER_DRIVER - when defined to any value (incl. empty string), print the constructed command line to stderr before calling the linker. |
|
11 | 14 | ||
12 | #include <stdio.h> |
15 | #include <stdio.h> |
13 | #include <stdlib.h> |
16 | #include <stdlib.h> |
14 | #include <stdarg.h> |
17 | #include <stdarg.h> |
15 | #include <stdbool.h> |
18 | #include <stdbool.h> |
Line 203... | Line 206... | ||
203 | // "%{!nostdlib:" |
206 | // "%{!nostdlib:" |
204 | // "%{!nodefaultlibs:" "%:pass-through-libs(%(link_gcc_c_sequence))" "}" |
207 | // "%{!nodefaultlibs:" "%:pass-through-libs(%(link_gcc_c_sequence))" "}" |
205 | // "} " |
208 | // "} " |
206 | // "}" |
209 | // "}" |
207 | // "}" |
210 | // "}" |
208 |
|
211 | if (!ARGV_CONTAINS_SINGLEARG ("-fno-use-linker-plugin") && !ARGV_CONTAINS_SINGLEARG ("-fno-lto")) |
209 | { |
212 | { |
210 |
|
213 | /*ADD_LINKER_ARG ("-plugin"); |
211 | ADD_LINKER_ARG (resolve_envvars ("${QNX_HOST}/usr/lib/gcc/" TARGET_TRIPLE "/" BASEVER "/liblto_plugin.so")); |
214 | ADD_LINKER_ARG (resolve_envvars ("${QNX_HOST}/usr/lib/gcc/" TARGET_TRIPLE "/" BASEVER "/liblto_plugin.so")); |
212 | ADD_LINKER_ARG (resolve_envvars ("-plugin-opt=${QNX_HOST}/usr/lib/gcc/" TARGET_TRIPLE "/" BASEVER "/lto-wrapper")); |
215 | ADD_LINKER_ARG (resolve_envvars ("-plugin-opt=${QNX_HOST}/usr/lib/gcc/" TARGET_TRIPLE "/" BASEVER "/lto-wrapper")); |
213 | ADD_LINKER_ARG (makefmtstr ("-plugin-opt=-fresolution=%s.res", " |
216 | ADD_LINKER_ARG (makefmtstr ("-plugin-opt=-fresolution=%s.res", "TODO-UNKNOWN")); // LTO is not interoperable between clang and ld. See below. |
214 | if (ARGV_CONTAINS_ARGWITHEQUALVAL ("-flinker-output")) |
217 | if (ARGV_CONTAINS_ARGWITHEQUALVAL ("-flinker-output")) |
215 | ADD_LINKER_ARG ("-plugin-opt=-linker-output-known"); |
218 | ADD_LINKER_ARG ("-plugin-opt=-linker-output-known"); |
216 | if (!ARGV_CONTAINS_SINGLEARG ("-nostdlib") && !ARGV_CONTAINS_SINGLEARG ("-nodefaultlibs")) |
219 | if (!ARGV_CONTAINS_SINGLEARG ("-nostdlib") && !ARGV_CONTAINS_SINGLEARG ("-nodefaultlibs")) |
217 | for (arg_index = 0; arg_index < larg_count; arg_index++) |
220 | for (arg_index = 0; arg_index < larg_count; arg_index++) |
218 | ADD_LINKER_ARG (makefmtstr ("-plugin-opt=-pass-through=%s", largs[arg_index])); |
221 | ADD_LINKER_ARG (makefmtstr ("-plugin-opt=-pass-through=%s", largs[arg_index]));*/ |
- | 222 | ||
- | 223 | // looks like LTO is a no-go. See: https://stackoverflow.com/questions/51259340/interoperability-between-clang-gcc-and-lto |
|
219 |
|
224 | } |
220 | 225 | ||
221 | // "%{flto|flto=*:" "%<fcompare-debug*" "} " |
226 | // "%{flto|flto=*:" "%<fcompare-debug*" "} " |
222 | if (ARGV_CONTAINS_SINGLEARG ("-flto") || ARGV_CONTAINS_ARGWITHEQUALVAL ("-flto")) |
227 | if (ARGV_CONTAINS_SINGLEARG ("-flto") || ARGV_CONTAINS_ARGWITHEQUALVAL ("-flto")) |
223 | for (arg_index = 1; arg_index < argc; arg_index++) |
228 | for (arg_index = 1; arg_index < argc; arg_index++) |
224 | if (strncmp (argv[arg_index], "-fcompare-debug", 15) == 0) |
229 | if (strncmp (argv[arg_index], "-fcompare-debug", 15) == 0) |
Line 649... | Line 654... | ||
649 | 654 | ||
650 | // "%o " |
655 | // "%o " |
651 | for (arg_index = 0; arg_index < oarg_count; arg_index++) |
656 | for (arg_index = 0; arg_index < oarg_count; arg_index++) |
652 | ADD_LINKER_ARG (oargs[arg_index]); |
657 | ADD_LINKER_ARG (oargs[arg_index]); |
653 | 658 | ||
654 | // |
659 | // QUOTE FROM https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html -- BEGIN |
655 | // "gt(" |
- | |
- | 660 | // "The following example inserts the link_gomp spec if the last -ftree-parallelize-loops= option given on the command line is greater than 1: |
|
656 | // |
661 | // %{ %:gt(%{ftree-parallelize-loops=*:%*} 1):%:include(libgomp.spec)%(link_gomp)}" |
- | 662 | // QUOTE FROM https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html -- END |
|
657 | // |
663 | // "%{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):%:include(libgomp.spec)%(link_gomp)} " |
658 | // "} " |
- | |
659 |
|
664 | // nothing to do (link_gomp is an empty string in this GCC) |
660 | 665 | ||
661 | // "%{fgnu-tm:" "%:include(libitm.spec)%(link_itm)" "} " |
666 | // "%{fgnu-tm:" "%:include(libitm.spec)%(link_itm)" "} " |
662 | if (ARGV_CONTAINS_SINGLEARG ("-fgnu-tm")) |
667 | if (ARGV_CONTAINS_SINGLEARG ("-fgnu-tm")) |
663 | { |
668 | { |
664 | ADD_LINKER_ARG ("-litm"); |
669 | ADD_LINKER_ARG ("-litm"); |
Line 686... | Line 691... | ||
686 | // "-lasan " |
691 | // "-lasan " |
687 | // "%{static-libasan:" "-Bdynamic" "} " |
692 | // "%{static-libasan:" "-Bdynamic" "} " |
688 | // "%{static-libasan|static:" "%:include(libsanitizer.spec)%(link_libasan)" "} " |
693 | // "%{static-libasan|static:" "%:include(libsanitizer.spec)%(link_libasan)" "} " |
689 | // "%{static:" "%ecannot specify -static with -fsanitize=address" "}" |
694 | // "%{static:" "%ecannot specify -static with -fsanitize=address" "}" |
690 | // "} " |
695 | // "} " |
- | 696 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=address")) |
|
- | 697 | { |
|
- | 698 | if (ARGV_CONTAINS_SINGLEARG ("-static-libasan")) ADD_LINKER_ARG ("-Bstatic"); |
|
- | 699 | ADD_LINKER_ARG ("-lasan"); |
|
- | 700 | if (ARGV_CONTAINS_SINGLEARG ("-static-libasan")) ADD_LINKER_ARG ("-Bdynamic"); |
|
- | 701 | if (ARGV_CONTAINS_SINGLEARG ("-static-libasan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 702 | ADD_LINKER_ARG ("-lm"); // only known dependency to libasan on QNX |
|
- | 703 | if (ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 704 | { |
|
- | 705 | fprintf (stderr, "%s: error: cannot specify -static with -fsanitize=address\n", argv[0]); |
|
- | 706 | exit (1); |
|
- | 707 | } |
|
- | 708 | } |
|
- | 709 | ||
691 | // "%{%:sanitize(hwaddress):" |
710 | // "%{%:sanitize(hwaddress):" |
692 | // "%{static-libhwasan:" "-Bstatic" "} " |
711 | // "%{static-libhwasan:" "-Bstatic" "} " |
693 | // "-lhwasan " |
712 | // "-lhwasan " |
694 | // "%{static-libhwasan:" "-Bdynamic" "} " |
713 | // "%{static-libhwasan:" "-Bdynamic" "} " |
695 | // "%{static-libhwasan|static:" "%:include(libsanitizer.spec)%(link_libhwasan)" "} " |
714 | // "%{static-libhwasan|static:" "%:include(libsanitizer.spec)%(link_libhwasan)" "} " |
696 | // "%{static:" "%ecannot specify -static with -fsanitize=hwaddress" "}" |
715 | // "%{static:" "%ecannot specify -static with -fsanitize=hwaddress" "}" |
697 | // "} " |
716 | // "} " |
- | 717 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=hwaddress")) |
|
- | 718 | { |
|
- | 719 | if (ARGV_CONTAINS_SINGLEARG ("-static-libhwasan")) ADD_LINKER_ARG ("-Bstatic"); |
|
- | 720 | ADD_LINKER_ARG ("-lhwasan"); |
|
- | 721 | if (ARGV_CONTAINS_SINGLEARG ("-static-libhwasan")) ADD_LINKER_ARG ("-Bdynamic"); |
|
- | 722 | if (ARGV_CONTAINS_SINGLEARG ("-static-libhwasan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 723 | ADD_LINKER_ARG ("-lm"); // only known dependency to libhwasan on QNX |
|
- | 724 | if (ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 725 | { |
|
- | 726 | fprintf (stderr, "%s: error: cannot specify -static with -fsanitize=hwaddress\n", argv[0]); |
|
- | 727 | exit (1); |
|
- | 728 | } |
|
- | 729 | } |
|
- | 730 | ||
698 | // "%{%:sanitize(thread):" |
731 | // "%{%:sanitize(thread):" |
699 | // "%{static-libtsan:" "-Bstatic" "} " |
732 | // "%{static-libtsan:" "-Bstatic" "} " |
700 | // "-ltsan " |
733 | // "-ltsan " |
701 | // "%{static-libtsan:" "-Bdynamic" "} " |
734 | // "%{static-libtsan:" "-Bdynamic" "} " |
702 | // "%{static-libtsan|static:" "%:include(libsanitizer.spec)%(link_libtsan)" "} " |
735 | // "%{static-libtsan|static:" "%:include(libsanitizer.spec)%(link_libtsan)" "} " |
703 | // "%{static:" "%ecannot specify -static with -fsanitize=thread" "}" |
736 | // "%{static:" "%ecannot specify -static with -fsanitize=thread" "}" |
704 | // "} " |
737 | // "} " |
- | 738 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=thread")) |
|
- | 739 | { |
|
- | 740 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan")) ADD_LINKER_ARG ("-Bstatic"); |
|
- | 741 | ADD_LINKER_ARG ("-ltsan"); |
|
- | 742 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan")) ADD_LINKER_ARG ("-Bdynamic"); |
|
- | 743 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 744 | ADD_LINKER_ARG ("-lm"); // only known dependency to libtsan on QNX |
|
- | 745 | if (ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 746 | { |
|
- | 747 | fprintf (stderr, "%s: error: cannot specify -static with -fsanitize=thread\n", argv[0]); |
|
- | 748 | exit (1); |
|
- | 749 | } |
|
- | 750 | } |
|
- | 751 | ||
705 | // "%{%:sanitize(undefined):" |
752 | // "%{%:sanitize(undefined):" |
706 | // "%{static-libubsan:" "-Bstatic" "} " |
753 | // "%{static-libubsan:" "-Bstatic" "} " |
707 | // "-lubsan " |
754 | // "-lubsan " |
708 | // "%{static-libubsan:" "-Bdynamic" "} " |
755 | // "%{static-libubsan:" "-Bdynamic" "} " |
709 | // "%{static-libubsan|static:" "%:include(libsanitizer.spec)%(link_libubsan)" "}" |
756 | // "%{static-libubsan|static:" "%:include(libsanitizer.spec)%(link_libubsan)" "}" |
710 | // "} " |
757 | // "} " |
- | 758 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=undefined")) |
|
- | 759 | { |
|
- | 760 | if (ARGV_CONTAINS_SINGLEARG ("-static-libubsan")) ADD_LINKER_ARG ("-Bstatic"); |
|
- | 761 | ADD_LINKER_ARG ("-lubsan"); |
|
- | 762 | if (ARGV_CONTAINS_SINGLEARG ("-static-libubsan")) ADD_LINKER_ARG ("-Bdynamic"); |
|
- | 763 | if (ARGV_CONTAINS_SINGLEARG ("-static-libubsan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 764 | ADD_LINKER_ARG ("-lm"); // only known dependency to libubsan on QNX |
|
- | 765 | } |
|
- | 766 | ||
711 | // "%{%:sanitize(leak):" |
767 | // "%{%:sanitize(leak):" |
712 | // "%{static-liblsan:" "-Bstatic" "} " |
768 | // "%{static-liblsan:" "-Bstatic" "} " |
713 | // "-llsan " |
769 | // "-llsan " |
714 | // "%{static-liblsan:" "-Bdynamic" "} " |
770 | // "%{static-liblsan:" "-Bdynamic" "} " |
715 | // "%{static-liblsan|static:" "%:include(libsanitizer.spec)%(link_liblsan)" "}" |
771 | // "%{static-liblsan|static:" "%:include(libsanitizer.spec)%(link_liblsan)" "}" |
716 | // "}" |
772 | // "}" |
- | 773 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=leak")) |
|
- | 774 | { |
|
- | 775 | if (ARGV_CONTAINS_SINGLEARG ("-static-liblsan")) ADD_LINKER_ARG ("-Bstatic"); |
|
717 |
|
776 | ADD_LINKER_ARG ("-llsan"); |
- | 777 | if (ARGV_CONTAINS_SINGLEARG ("-static-liblsan")) ADD_LINKER_ARG ("-Bdynamic"); |
|
- | 778 | if (ARGV_CONTAINS_SINGLEARG ("-static-liblsan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 779 | ADD_LINKER_ARG ("-lm"); // only known dependency to liblsan on QNX |
|
- | 780 | } |
|
718 | #else // !IS_TARGET_INTEL |
781 | #else // !IS_TARGET_INTEL |
719 | // "%{%:sanitize(address): " |
782 | // "%{%:sanitize(address): " |
720 | // "%{static-libasan|static:" "%:include(libsanitizer.spec)%(link_libasan)" "} " |
783 | // "%{static-libasan|static:" "%:include(libsanitizer.spec)%(link_libasan)" "} " |
721 | // "%{static:" "%ecannot specify -static with -fsanitize=address" "}" |
784 | // "%{static:" "%ecannot specify -static with -fsanitize=address" "}" |
722 | // "} " |
785 | // "} " |
- | 786 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=address")) |
|
- | 787 | { |
|
- | 788 | if (ARGV_CONTAINS_SINGLEARG ("-static-libasan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 789 | ADD_LINKER_ARG ("-lm"); // only known dependency to libasan on QNX |
|
- | 790 | if (ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 791 | { |
|
- | 792 | fprintf (stderr, "%s: error: cannot specify -static with -fsanitize=address\n", argv[0]); |
|
- | 793 | exit (1); |
|
- | 794 | } |
|
- | 795 | } |
|
- | 796 | ||
723 | // "%{%:sanitize(hwaddress): " |
797 | // "%{%:sanitize(hwaddress): " |
724 | // "%{static-libhwasan|static:" "%:include(libsanitizer.spec)%(link_libhwasan)" "} " |
798 | // "%{static-libhwasan|static:" "%:include(libsanitizer.spec)%(link_libhwasan)" "} " |
725 | // "%{static:" "%ecannot specify -static with -fsanitize=hwaddress" "}" |
799 | // "%{static:" "%ecannot specify -static with -fsanitize=hwaddress" "}" |
726 | // "} " |
800 | // "} " |
- | 801 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=hwaddress")) |
|
- | 802 | { |
|
- | 803 | if (ARGV_CONTAINS_SINGLEARG ("-static-libhwasan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 804 | ADD_LINKER_ARG ("-lm"); // only known dependency to libhwasan on QNX |
|
- | 805 | if (ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 806 | { |
|
- | 807 | fprintf (stderr, "%s: error: cannot specify -static with -fsanitize=hwaddress\n", argv[0]); |
|
- | 808 | exit (1); |
|
- | 809 | } |
|
- | 810 | } |
|
- | 811 | ||
727 | // "%{%:sanitize(thread): " |
812 | // "%{%:sanitize(thread): " |
728 | // "%{static-libtsan|static:" "%:include(libsanitizer.spec)%(link_libtsan)" "} " |
813 | // "%{static-libtsan|static:" "%:include(libsanitizer.spec)%(link_libtsan)" "} " |
729 | // "%{static:" "%ecannot specify -static with -fsanitize=thread" "}" |
814 | // "%{static:" "%ecannot specify -static with -fsanitize=thread" "}" |
730 | // "} " |
815 | // "} " |
- | 816 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=thread")) |
|
- | 817 | { |
|
- | 818 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 819 | ADD_LINKER_ARG ("-lm"); // only known dependency to libtsan on QNX |
|
- | 820 | if (ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 821 | { |
|
- | 822 | fprintf (stderr, "%s: error: cannot specify -static with -fsanitize=thread\n", argv[0]); |
|
- | 823 | exit (1); |
|
- | 824 | } |
|
- | 825 | } |
|
- | 826 | ||
731 | // "%{%:sanitize(undefined):" |
827 | // "%{%:sanitize(undefined):" |
732 | // "%{static-libubsan:" "-Bstatic" "} " |
828 | // "%{static-libubsan:" "-Bstatic" "} " |
733 | // "-lubsan " |
829 | // "-lubsan " |
734 | // "%{static-libubsan:" "-Bdynamic" "} " |
830 | // "%{static-libubsan:" "-Bdynamic" "} " |
735 | // "%{static-libubsan|static:" "%:include(libsanitizer.spec)%(link_libubsan)" "}" |
831 | // "%{static-libubsan|static:" "%:include(libsanitizer.spec)%(link_libubsan)" "}" |
736 | // "} " |
832 | // "} " |
- | 833 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=undefined")) |
|
- | 834 | { |
|
- | 835 | if (ARGV_CONTAINS_SINGLEARG ("-static-libubsan")) ADD_LINKER_ARG ("-Bstatic"); |
|
- | 836 | ADD_LINKER_ARG ("-lubsan"); |
|
- | 837 | if (ARGV_CONTAINS_SINGLEARG ("-static-libubsan")) ADD_LINKER_ARG ("-Bdynamic"); |
|
- | 838 | if (ARGV_CONTAINS_SINGLEARG ("-static-libubsan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 839 | ADD_LINKER_ARG ("-lm"); // only known dependency to libubsan on QNX |
|
- | 840 | } |
|
- | 841 | ||
737 | // "%{%:sanitize(leak): " |
842 | // "%{%:sanitize(leak): " |
738 | // "%{static-liblsan|static:" "%:include(libsanitizer.spec)%(link_liblsan)" "}" |
843 | // "%{static-liblsan|static:" "%:include(libsanitizer.spec)%(link_liblsan)" "}" |
739 | // "}" |
844 | // "}" |
- | 845 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=leak")) |
|
- | 846 | { |
|
- | 847 | if (ARGV_CONTAINS_SINGLEARG ("-static-liblsan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
|
- | 848 | ADD_LINKER_ARG ("-lm"); // only known dependency to liblsan on QNX |
|
740 |
|
849 | } |
741 | #endif // IS_TARGET_INTEL |
850 | #endif // IS_TARGET_INTEL |
742 | 851 | ||
743 | // "%{fstack-protector|fstack-protector-all|fstack-protector-strong|fstack-protector-explicit:}" |
852 | // "%{fstack-protector|fstack-protector-all|fstack-protector-strong|fstack-protector-explicit:}" |
744 | // nothing to do |
853 | // nothing to do |
745 | 854 | ||
Line 938... | Line 1047... | ||
938 | 1047 | ||
939 | was_cpluspluslib_included = false; |
1048 | was_cpluspluslib_included = false; |
940 | for (arg_index = 0; arg_index < larg_count; arg_index++) |
1049 | for (arg_index = 0; arg_index < larg_count; arg_index++) |
941 | { |
1050 | { |
942 | ADD_LINKER_ARG (largs[arg_index]); |
1051 | ADD_LINKER_ARG (largs[arg_index]); |
943 | if (strstr (largs[arg_index], "c++") != NULL) |
1052 | if (((arg = strstr (largs[arg_index], "c++")) != NULL) && (arg[3] == 0)) |
944 | was_cpluspluslib_included = true; |
1053 | was_cpluspluslib_included = true; // catches -lstdc++ and -lc++ |
945 | } |
1054 | } |
946 | if (!was_cpluspluslib_included) |
1055 | if (!was_cpluspluslib_included) |
947 | { |
1056 | { |
948 | if (strstr (argv[0], "g++") != NULL) |
1057 | if (strstr (argv[0], "g++") != NULL) |
949 | ADD_LINKER_ARG ("-lc++"); // if |
1058 | ADD_LINKER_ARG ("-lc++"); // if clang invoked us as g++ to link stuff it probably means we need a C++ library |
950 | else |
1059 | else |
951 | { |
1060 | { |
952 | requires_libcplusplus = false; // figure it out the hard way: if we see a C++ mangled symbol name in one of the object files, it means we need a C++ library |
1061 | requires_libcplusplus = false; // figure it out the hard way: if we see a C++ mangled symbol name in one of the object files, it means we need a C++ library |
953 | for (arg_index = 0; !requires_libcplusplus && (arg_index < oarg_count); arg_index++) |
1062 | for (arg_index = 0; !requires_libcplusplus && (arg_index < oarg_count); arg_index++) |
954 | { |
1063 | { |
Line 993... | Line 1102... | ||
993 | } |
1102 | } |
994 | else if ((strncmp (argv[arg_index], "-T", 2) == 0) && ((argv[arg_index])[2] != 0)) |
1103 | else if ((strncmp (argv[arg_index], "-T", 2) == 0) && ((argv[arg_index])[2] != 0)) |
995 | ADD_LINKER_ARG (argv[arg_index]); |
1104 | ADD_LINKER_ARG (argv[arg_index]); |
996 | 1105 | ||
997 | // since clang doesn't seem to generate .note.GNU-stack sections in output ELF files we explicitly specify the linker that we don't want an executable stack |
1106 | // since clang doesn't seem to generate .note.GNU-stack sections in output ELF files we explicitly specify the linker that we don't want an executable stack |
- | 1107 | // TODO: fix this in clang itself |
|
998 | ADD_LINKER_ARG ("-z"); |
1108 | ADD_LINKER_ARG ("-z"); |
999 | ADD_LINKER_ARG ("noexecstack"); |
1109 | ADD_LINKER_ARG ("noexecstack"); |
1000 | 1110 | ||
1001 | if (ARGV_CONTAINS_SINGLEARG ("-v")) |
1111 | if (ARGV_CONTAINS_SINGLEARG ("-v") || (getenv ("DEBUG_LINKER_DRIVER") != NULL)) |
1002 | { |
1112 | { |
1003 | fputs ("LINKER DRIVER: CONSTRUCTED COMMAND LINE BEGIN\n", stderr); |
1113 | fputs ("LINKER DRIVER: CONSTRUCTED COMMAND LINE BEGIN\n", stderr); |
1004 | for (arg_index = 0; arg_index < linker_argc; arg_index++) |
1114 | for (arg_index = 0; arg_index < linker_argc; arg_index++) |
1005 | fprintf (stderr, "%s%s%s\n", (arg_index > 0 ? "\t" : ""), linker_argv[arg_index], ((size_t) arg_index + 1 < linker_argc ? " \\" : "")); |
1115 | fprintf (stderr, "%s%s%s\n", (arg_index > 0 ? "\t" : ""), linker_argv[arg_index], ((size_t) arg_index + 1 < linker_argc ? " \\" : "")); |
1006 | fputs ("LINKER DRIVER: CONSTRUCTED COMMAND LINE END\n", stderr); |
1116 | fputs ("LINKER DRIVER: CONSTRUCTED COMMAND LINE END\n", stderr); |