Subversion Repositories QNX 8.QNX8 linker driver

Rev

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
   /*if (!ARGV_CONTAINS_SINGLEARG ("-fno-use-linker-plugin") && !ARGV_CONTAINS_SINGLEARG ("-fno-lto"))
211
   if (!ARGV_CONTAINS_SINGLEARG ("-fno-use-linker-plugin") && !ARGV_CONTAINS_SINGLEARG ("-fno-lto"))
209
   {
212
   {
210
      ADD_LINKER_ARG ("-plugin");
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", "FIXME-UNKNOWN")); // FIXME: how to get the linker resolution file? Are the GCC and LLVM LTO ABI-compatible?
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
   //   "%{fopenacc|fopenmp|%:"
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
   //                   "%{ftree-parallelize-loops=*:"  "%*   "}"
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
   //           " 1):   %:include(libgomp.spec)%(link_gomp)"
663
   //   "%{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):%:include(libgomp.spec)%(link_gomp)}    "
658
   //   "}    "
-
 
659
   /* FIXME: TODO */
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
         /* FIXME: TODO */
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
         /* FIXME: TODO */
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 we were invoked as g++ to link stuff it probably means we need a C++ library
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);