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); |