Rev 7 | Rev 10 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7 | Rev 8 | ||
---|---|---|---|
Line 53... | Line 53... | ||
53 | #else |
53 | #else |
54 | #error unsupported platform (not x86_64, not aarch64le). Please implement! |
54 | #error unsupported platform (not x86_64, not aarch64le). Please implement! |
55 | #endif |
55 | #endif |
56 | #define COMPILER "clang" |
56 | #define COMPILER "clang" |
57 | #define LINKER TARGET_TRIPLE "-ld" |
57 | #define LINKER TARGET_TRIPLE "-ld" |
- | 58 | //#define LINKER "ld.lld" |
|
58 | 59 | ||
59 | 60 | ||
60 | #define ARGMODE_SINGLE 0 |
61 | #define ARGMODE_SINGLE 0 |
61 | #define ARGMODE_HASVAL 1 |
62 | #define ARGMODE_HASVAL 1 |
62 | #define ARGMODE_EQUALVAL 2 |
63 | #define ARGMODE_EQUALVAL 2 |
Line 165... | Line 166... | ||
165 | || ARGV_CONTAINS_SINGLEARG ("-c") |
166 | || ARGV_CONTAINS_SINGLEARG ("-c") |
166 | || ARGV_CONTAINS_SINGLEARG ("-M") |
167 | || ARGV_CONTAINS_SINGLEARG ("-M") |
167 | || ARGV_CONTAINS_SINGLEARG ("-MM") |
168 | || ARGV_CONTAINS_SINGLEARG ("-MM") |
168 | || ARGV_CONTAINS_SINGLEARG ("-E") |
169 | || ARGV_CONTAINS_SINGLEARG ("-E") |
169 | || ARGV_CONTAINS_SINGLEARG ("-S")) |
170 | || ARGV_CONTAINS_SINGLEARG ("-S")) |
- | 171 | { |
|
- | 172 | if (ARGV_CONTAINS_SINGLEARG ("-c")) |
|
- | 173 | for (arg_index = 1; arg_index < argc; arg_index++) |
|
- | 174 | if (strcmp (argv[arg_index], "-shared") == 0) |
|
- | 175 | argv[arg_index] = ""; // HACK for GNU autotools: when compiling, wipe out the -shared flag to avoid a warning |
|
170 | execvpe (COMPILER, argv, envp); // by leaving argv[0] untouched, we will be invoking Clang as 'gcc', which will give it a supplemental hint about how to behave |
176 | execvpe (COMPILER, argv, envp); // by leaving argv[0] untouched, we will be invoking Clang as 'gcc', which will give it a supplemental hint about how to behave |
- | 177 | } |
|
171 | 178 | ||
172 | // collect source and object files in two separate lists |
179 | // collect source and object files in two separate lists |
173 | for (arg_index = 1; arg_index < argc; arg_index++) |
180 | for (arg_index = 1; arg_index < argc; arg_index++) |
174 | if ((strcmp (argv[arg_index - 1], "-o") != 0) // this arg is NOT preceded by "-o"... |
181 | if ((strcmp (argv[arg_index - 1], "-o") != 0) // this arg is NOT preceded by "-o"... |
175 | && (access (argv[arg_index], 0) == 0) // ... this arg is an existing file... |
182 | && (access (argv[arg_index], 0) == 0) // ... this arg is an existing file... |
Line 189... | Line 196... | ||
189 | ADD_O_ARG (argv[arg_index]); // this file is NOT one of the known file extensions: add to object files list |
196 | ADD_O_ARG (argv[arg_index]); // this file is NOT one of the known file extensions: add to object files list |
190 | } |
197 | } |
191 | 198 | ||
192 | // if we have zero .o file, OR if we have some source files, we have to compile first |
199 | // if we have zero .o file, OR if we have some source files, we have to compile first |
193 | if ((sarg_count > 0) || (oarg_count == 0)) |
200 | if ((sarg_count > 0) || (oarg_count == 0)) |
- | 201 | { |
|
- | 202 | if (ARGV_CONTAINS_SINGLEARG ("-c")) |
|
- | 203 | for (arg_index = 1; arg_index < argc; arg_index++) |
|
- | 204 | if (strcmp (argv[arg_index], "-shared") == 0) |
|
- | 205 | argv[arg_index] = ""; // HACK for GNU autotools: when compiling, wipe out the -shared flag to avoid a warning |
|
194 | execvpe (COMPILER, argv, envp); // by leaving argv[0] untouched, we will be invoking Clang as 'gcc', which will give it a supplemental hint about how to behave |
206 | execvpe (COMPILER, argv, envp); // by leaving argv[0] untouched, we will be invoking Clang as 'gcc', which will give it a supplemental hint about how to behave |
- | 207 | } |
|
195 | 208 | ||
196 | // collect -l flags |
209 | // collect -l flags |
197 | for (arg_index = 1; arg_index < argc; arg_index++) |
210 | for (arg_index = 1; arg_index < argc; arg_index++) |
198 | if ((strncmp (argv[arg_index], "-l", 2) == 0) && ((argv[arg_index])[2] != 0)) |
211 | if ((strncmp (argv[arg_index], "-l", 2) == 0) && ((argv[arg_index])[2] != 0)) |
199 | ADD_L_ARG (argv[arg_index]); |
212 | ADD_L_ARG (argv[arg_index]); |
Line 253... | Line 266... | ||
253 | // "%{h*} " |
266 | // "%{h*} " |
254 | for (arg_index = 1; arg_index < argc; arg_index++) |
267 | for (arg_index = 1; arg_index < argc; arg_index++) |
255 | if ((strcmp (argv[arg_index], "-h") == 0) && (arg_index + 1 < argc)) |
268 | if ((strcmp (argv[arg_index], "-h") == 0) && (arg_index + 1 < argc)) |
256 | { |
269 | { |
257 | ADD_LINKER_ARG ("-h"); |
270 | ADD_LINKER_ARG ("-h"); |
258 | ADD_LINKER_ARG (argv[++arg_index]); |
271 | ADD_LINKER_ARG (argv[++arg_index]); |
259 | } |
272 | } |
260 | else if ((strncmp (argv[arg_index], "-h", 2) == 0) && ((argv[arg_index])[2] != 0)) |
273 | else if ((strncmp (argv[arg_index], "-h", 2) == 0) && ((argv[arg_index])[2] != 0)) |
261 | ADD_LINKER_ARG (argv[arg_index]); |
274 | ADD_LINKER_ARG (argv[arg_index]); |
262 | 275 | ||
263 | // "%{v:" "-V" "} " |
276 | // "%{v:" "-V" "} " |
Line 282... | Line 295... | ||
282 | // "-zrelro " |
295 | // "-zrelro " |
283 | // "-znow " |
296 | // "-znow " |
284 | ADD_LINKER_ARG ("--warn-shared-textrel"); |
297 | ADD_LINKER_ARG ("--warn-shared-textrel"); |
285 | ADD_LINKER_ARG ("-zrelro"); |
298 | ADD_LINKER_ARG ("-zrelro"); |
286 | ADD_LINKER_ARG ("-znow"); |
299 | ADD_LINKER_ARG ("-znow"); |
287 | 300 | ||
- | 301 | // 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 |
|
- | 302 | // TODO: fix this in clang itself |
|
- | 303 | ADD_LINKER_ARG ("-znoexecstack"); |
|
- | 304 | ||
288 | #if IS_TARGET_INTEL |
305 | #if IS_TARGET_INTEL |
289 | // "%{shared:" "-G -dy -z text" "} " |
306 | // "%{shared:" "-G -dy -z text" "} " |
290 | if (ARGV_CONTAINS_SINGLEARG ("-shared")) |
307 | if (ARGV_CONTAINS_SINGLEARG ("-shared")) |
291 | { |
308 | { |
292 | ADD_LINKER_ARG ("-G"); |
309 | ADD_LINKER_ARG ("-G"); |
Line 742... | Line 759... | ||
742 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=thread")) |
759 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=thread")) |
743 | { |
760 | { |
744 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan")) ADD_LINKER_ARG ("-Bstatic"); |
761 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan")) ADD_LINKER_ARG ("-Bstatic"); |
745 | ADD_LINKER_ARG ("-ltsan"); |
762 | ADD_LINKER_ARG ("-ltsan"); |
746 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan")) ADD_LINKER_ARG ("-Bdynamic"); |
763 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan")) ADD_LINKER_ARG ("-Bdynamic"); |
747 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
764 | if (ARGV_CONTAINS_SINGLEARG ("-static-libtsan") || ARGV_CONTAINS_SINGLEARG ("-static")) |
748 | ADD_LINKER_ARG ("-lm"); // only known dependency to libtsan on QNX |
765 | ADD_LINKER_ARG ("-lm"); // only known dependency to libtsan on QNX |
749 | if (ARGV_CONTAINS_SINGLEARG ("-static")) |
766 | if (ARGV_CONTAINS_SINGLEARG ("-static")) |
750 | { |
767 | { |
751 | fprintf (stderr, "%s: error: cannot specify -static with -fsanitize=thread\n", argv[0]); |
768 | fprintf (stderr, "%s: error: cannot specify -static with -fsanitize=thread\n", argv[0]); |
752 | exit (1); |
769 | exit (1); |
753 | } |
770 | } |
754 | } |
771 | } |
755 | 772 | ||
756 | // "%{%:sanitize(undefined):" |
773 | // "%{%:sanitize(undefined):" |
757 | // "%{static-libubsan:" "-Bstatic" "} " |
774 | // "%{static-libubsan:" "-Bstatic" "} " |
758 | // "-lubsan " |
775 | // "-lubsan " |
759 | // "%{static-libubsan:" "-Bdynamic" "} " |
776 | // "%{static-libubsan:" "-Bdynamic" "} " |
760 | // "%{static-libubsan|static:" "%:include(libsanitizer.spec)%(link_libubsan)" "}" |
777 | // "%{static-libubsan|static:" "%:include(libsanitizer.spec)%(link_libubsan)" "}" |
761 | // "} " |
778 | // "} " |
762 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=undefined")) |
779 | if (ARGV_CONTAINS_SINGLEARG ("-fsanitize=undefined")) |
763 | { |
780 | { |
Line 986... | Line 1003... | ||
986 | } |
1003 | } |
987 | else |
1004 | else |
988 | { |
1005 | { |
989 | ADD_LINKER_ARG ("-lgcc_s"); |
1006 | ADD_LINKER_ARG ("-lgcc_s"); |
990 | if (!ARGV_CONTAINS_SINGLEARG ("-shared")) |
1007 | if (!ARGV_CONTAINS_SINGLEARG ("-shared")) |
991 | ADD_LINKER_ARG ("-lgcc"); |
1008 | ADD_LINKER_ARG ("-lgcc"); |
992 | } |
1009 | } |
993 | } |
1010 | } |
994 | 1011 | ||
995 | // "%{!nolibc:" |
1012 | // "%{!nolibc:" |
996 | // "%{!symbolic:" |
1013 | // "%{!symbolic:" |
997 | // " -lc" |
1014 | // " -lc" |
998 | // " %{shared:" "-lcS" "}" |
1015 | // " %{shared:" "-lcS" "}" |
999 | // " %{!no-pie:" "-lcS" "}" |
1016 | // " %{!no-pie:" "-lcS" "}" |
Line 1003... | Line 1020... | ||
1003 | if (!ARGV_CONTAINS_SINGLEARG ("-nolibc") && !ARGV_CONTAINS_SINGLEARG ("-symbolic")) |
1020 | if (!ARGV_CONTAINS_SINGLEARG ("-nolibc") && !ARGV_CONTAINS_SINGLEARG ("-symbolic")) |
1004 | { |
1021 | { |
1005 | ADD_LINKER_ARG ("-lc"); |
1022 | ADD_LINKER_ARG ("-lc"); |
1006 | if (ARGV_CONTAINS_SINGLEARG ("-shared") || !ARGV_CONTAINS_SINGLEARG ("-no-pie")) |
1023 | if (ARGV_CONTAINS_SINGLEARG ("-shared") || !ARGV_CONTAINS_SINGLEARG ("-no-pie")) |
1007 | ADD_LINKER_ARG ("-lcS"); |
1024 | ADD_LINKER_ARG ("-lcS"); |
1008 | } |
1025 | } |
1009 | 1026 | ||
1010 | // "%{static|static-pie:" "--end-group" "}" |
1027 | // "%{static|static-pie:" "--end-group" "}" |
1011 | if (ARGV_CONTAINS_SINGLEARG ("-static") || ARGV_CONTAINS_SINGLEARG ("-static-pie")) |
1028 | if (ARGV_CONTAINS_SINGLEARG ("-static") || ARGV_CONTAINS_SINGLEARG ("-static-pie")) |
1012 | ADD_LINKER_ARG ("--end-group"); |
1029 | ADD_LINKER_ARG ("--end-group"); |
1013 | // "%{!static:" |
1030 | // "%{!static:" |
1014 | // "%{!static-pie:" |
1031 | // "%{!static-pie:" |
Line 1092... | Line 1109... | ||
1092 | if (ARGV_CONTAINS_SINGLEARG ("-EB")) |
1109 | if (ARGV_CONTAINS_SINGLEARG ("-EB")) |
1093 | ADD_LINKER_ARG (resolve_envvars ("${QNX_TARGET}/aarch64be/lib/crtn.o")); |
1110 | ADD_LINKER_ARG (resolve_envvars ("${QNX_TARGET}/aarch64be/lib/crtn.o")); |
1094 | else |
1111 | else |
1095 | ADD_LINKER_ARG (resolve_envvars ("${QNX_TARGET}/aarch64le/lib/crtn.o")); |
1112 | ADD_LINKER_ARG (resolve_envvars ("${QNX_TARGET}/aarch64le/lib/crtn.o")); |
1096 | #endif // IS_TARGET_INTEL |
1113 | #endif // IS_TARGET_INTEL |
1097 | } |
1114 | } |
1098 | } |
1115 | } |
1099 | 1116 | ||
1100 | // "%{T*}" |
1117 | // "%{T*}" |
1101 | for (arg_index = 1; arg_index < argc; arg_index++) |
1118 | for (arg_index = 1; arg_index < argc; arg_index++) |
1102 | if ((strcmp (argv[arg_index], "-T") == 0) && (arg_index + 1 < argc)) |
1119 | if ((strcmp (argv[arg_index], "-T") == 0) && (arg_index + 1 < argc)) |
1103 | { |
1120 | { |
1104 | ADD_LINKER_ARG ("-T"); |
1121 | ADD_LINKER_ARG ("-T"); |
1105 | ADD_LINKER_ARG (argv[++arg_index]); |
1122 | ADD_LINKER_ARG (argv[++arg_index]); |
1106 | } |
1123 | } |
1107 | else if ((strncmp (argv[arg_index], "-T", 2) == 0) && ((argv[arg_index])[2] != 0)) |
1124 | else if ((strncmp (argv[arg_index], "-T", 2) == 0) && ((argv[arg_index])[2] != 0)) |
1108 | ADD_LINKER_ARG (argv[arg_index]); |
1125 | ADD_LINKER_ARG (argv[arg_index]); |
1109 | - | ||
1110 | // 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 |
- | |
1111 | // TODO: fix this in clang itself |
- | |
1112 | ADD_LINKER_ARG ("-z"); |
- | |
1113 | ADD_LINKER_ARG ("noexecstack"); |
- | |
1114 | 1126 | ||
1115 | if (ARGV_CONTAINS_SINGLEARG ("-v") || (getenv ("DEBUG_LINKER_DRIVER") != NULL)) |
1127 | if (ARGV_CONTAINS_SINGLEARG ("-v") || (getenv ("DEBUG_LINKER_DRIVER") != NULL)) |
1116 | { |
1128 | { |
1117 | fputs ("LINKER DRIVER: CONSTRUCTED COMMAND LINE BEGIN\n", stderr); |
1129 | fputs ("LINKER DRIVER: CONSTRUCTED COMMAND LINE BEGIN\n", stderr); |
1118 | for (arg_index = 0; arg_index < linker_argc; arg_index++) |
1130 | for (arg_index = 0; arg_index < linker_argc; arg_index++) |